early-access version 3390
This commit is contained in:
parent
24f51c15b0
commit
f570da2c88
5 changed files with 42 additions and 40 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 3386.
|
This is the source code for early-access 3390.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -289,11 +289,6 @@ public:
|
||||||
return cpu_addr;
|
return cpu_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the base CPU address of the buffer
|
|
||||||
void UpdateCpuAddr(VAddr cpu_addr_) noexcept {
|
|
||||||
cpu_addr = cpu_addr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the offset relative to the given CPU address
|
/// Returns the offset relative to the given CPU address
|
||||||
/// @pre IsInBounds returns true
|
/// @pre IsInBounds returns true
|
||||||
[[nodiscard]] u32 Offset(VAddr other_cpu_addr) const noexcept {
|
[[nodiscard]] u32 Offset(VAddr other_cpu_addr) const noexcept {
|
||||||
|
|
|
@ -205,9 +205,9 @@ public:
|
||||||
current_draw_indirect = current_draw_indirect_;
|
current_draw_indirect = current_draw_indirect_;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] typename BufferCache<P>::Buffer* GetDrawIndirectCount();
|
[[nodiscard]] std::pair<Buffer*, u32> GetDrawIndirectCount();
|
||||||
|
|
||||||
[[nodiscard]] typename BufferCache<P>::Buffer* GetDrawIndirectBuffer();
|
[[nodiscard]] std::pair<Buffer*, u32> GetDrawIndirectBuffer();
|
||||||
|
|
||||||
std::recursive_mutex mutex;
|
std::recursive_mutex mutex;
|
||||||
Runtime& runtime;
|
Runtime& runtime;
|
||||||
|
@ -385,9 +385,6 @@ private:
|
||||||
SlotVector<Buffer> slot_buffers;
|
SlotVector<Buffer> slot_buffers;
|
||||||
DelayedDestructionRing<Buffer, 8> delayed_destruction_ring;
|
DelayedDestructionRing<Buffer, 8> delayed_destruction_ring;
|
||||||
|
|
||||||
Buffer indirect_buffer;
|
|
||||||
Buffer indirect_count_buffer;
|
|
||||||
|
|
||||||
const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{};
|
const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{};
|
||||||
|
|
||||||
u32 last_index_count = 0;
|
u32 last_index_count = 0;
|
||||||
|
@ -461,9 +458,7 @@ private:
|
||||||
template <class P>
|
template <class P>
|
||||||
BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
|
BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
|
||||||
Core::Memory::Memory& cpu_memory_, Runtime& runtime_)
|
Core::Memory::Memory& cpu_memory_, Runtime& runtime_)
|
||||||
: runtime{runtime_}, rasterizer{rasterizer_}, cpu_memory{cpu_memory_},
|
: runtime{runtime_}, rasterizer{rasterizer_}, cpu_memory{cpu_memory_} {
|
||||||
indirect_buffer(runtime, rasterizer, 0, 0x1000),
|
|
||||||
indirect_count_buffer(runtime, rasterizer, 0, 0x1000) {
|
|
||||||
// Ensure the first slot is used for the null buffer
|
// Ensure the first slot is used for the null buffer
|
||||||
void(slot_buffers.insert(runtime, NullBufferParams{}));
|
void(slot_buffers.insert(runtime, NullBufferParams{}));
|
||||||
common_ranges.clear();
|
common_ranges.clear();
|
||||||
|
@ -1069,13 +1064,15 @@ void BufferCache<P>::BindHostVertexBuffers() {
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void BufferCache<P>::BindHostDrawIndirectBuffers() {
|
void BufferCache<P>::BindHostDrawIndirectBuffers() {
|
||||||
const auto bind_buffer = [this](const Binding& binding, Buffer& buffer) {
|
const auto bind_buffer = [this](const Binding& binding) {
|
||||||
|
Buffer& buffer = slot_buffers[binding.buffer_id];
|
||||||
|
TouchBuffer(buffer, binding.buffer_id);
|
||||||
SynchronizeBuffer(buffer, binding.cpu_addr, binding.size);
|
SynchronizeBuffer(buffer, binding.cpu_addr, binding.size);
|
||||||
};
|
};
|
||||||
if (current_draw_indirect->include_count) {
|
if (current_draw_indirect->include_count) {
|
||||||
bind_buffer(count_buffer_binding, indirect_count_buffer);
|
bind_buffer(count_buffer_binding);
|
||||||
}
|
}
|
||||||
bind_buffer(indirect_buffer_binding, indirect_buffer);
|
bind_buffer(indirect_buffer_binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
|
@ -1412,16 +1409,14 @@ void BufferCache<P>::UpdateDrawIndirect() {
|
||||||
binding = Binding{
|
binding = Binding{
|
||||||
.cpu_addr = *cpu_addr,
|
.cpu_addr = *cpu_addr,
|
||||||
.size = static_cast<u32>(size),
|
.size = static_cast<u32>(size),
|
||||||
.buffer_id = NULL_BUFFER_ID,
|
.buffer_id = FindBuffer(*cpu_addr, static_cast<u32>(size)),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (current_draw_indirect->include_count) {
|
if (current_draw_indirect->include_count) {
|
||||||
update(current_draw_indirect->count_start_address, sizeof(u32), count_buffer_binding);
|
update(current_draw_indirect->count_start_address, sizeof(u32), count_buffer_binding);
|
||||||
indirect_count_buffer.UpdateCpuAddr(count_buffer_binding.cpu_addr);
|
|
||||||
}
|
}
|
||||||
update(current_draw_indirect->indirect_start_address, current_draw_indirect->buffer_size,
|
update(current_draw_indirect->indirect_start_address, current_draw_indirect->buffer_size,
|
||||||
indirect_buffer_binding);
|
indirect_buffer_binding);
|
||||||
indirect_buffer.UpdateCpuAddr(indirect_buffer_binding.cpu_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
|
@ -2005,13 +2000,15 @@ bool BufferCache<P>::HasFastUniformBufferBound(size_t stage, u32 binding_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
typename BufferCache<P>::Buffer* BufferCache<P>::GetDrawIndirectCount() {
|
std::pair<typename BufferCache<P>::Buffer*, u32> BufferCache<P>::GetDrawIndirectCount() {
|
||||||
return &indirect_count_buffer;
|
auto& buffer = slot_buffers[count_buffer_binding.buffer_id];
|
||||||
|
return std::make_pair(&buffer, buffer.Offset(count_buffer_binding.cpu_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
typename BufferCache<P>::Buffer* BufferCache<P>::GetDrawIndirectBuffer() {
|
std::pair<typename BufferCache<P>::Buffer*, u32> BufferCache<P>::GetDrawIndirectBuffer() {
|
||||||
return &indirect_buffer;
|
auto& buffer = slot_buffers[indirect_buffer_binding.buffer_id];
|
||||||
|
return std::make_pair(&buffer, buffer.Offset(indirect_buffer_binding.cpu_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace VideoCommon
|
} // namespace VideoCommon
|
||||||
|
|
|
@ -285,19 +285,23 @@ void RasterizerOpenGL::DrawIndirect() {
|
||||||
const auto& params = maxwell3d->draw_manager->GetIndirectParams();
|
const auto& params = maxwell3d->draw_manager->GetIndirectParams();
|
||||||
buffer_cache.SetDrawIndirect(¶ms);
|
buffer_cache.SetDrawIndirect(¶ms);
|
||||||
PrepareDraw(params.is_indexed, [this, ¶ms](GLenum primitive_mode) {
|
PrepareDraw(params.is_indexed, [this, ¶ms](GLenum primitive_mode) {
|
||||||
const auto buffer = buffer_cache.GetDrawIndirectBuffer();
|
const auto [buffer, offset] = buffer_cache.GetDrawIndirectBuffer();
|
||||||
|
const GLvoid* const gl_offset =
|
||||||
|
reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(offset));
|
||||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->Handle());
|
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->Handle());
|
||||||
if (params.include_count) {
|
if (params.include_count) {
|
||||||
const auto draw_buffer = buffer_cache.GetDrawIndirectCount();
|
const auto [draw_buffer, offset_base] = buffer_cache.GetDrawIndirectCount();
|
||||||
glBindBuffer(GL_PARAMETER_BUFFER, draw_buffer->Handle());
|
glBindBuffer(GL_PARAMETER_BUFFER, draw_buffer->Handle());
|
||||||
|
|
||||||
if (params.is_indexed) {
|
if (params.is_indexed) {
|
||||||
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
|
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
|
||||||
glMultiDrawElementsIndirectCount(primitive_mode, format, nullptr, 0,
|
glMultiDrawElementsIndirectCount(primitive_mode, format, gl_offset,
|
||||||
|
static_cast<GLintptr>(offset_base),
|
||||||
static_cast<GLsizei>(params.max_draw_counts),
|
static_cast<GLsizei>(params.max_draw_counts),
|
||||||
static_cast<GLsizei>(params.stride));
|
static_cast<GLsizei>(params.stride));
|
||||||
} else {
|
} else {
|
||||||
glMultiDrawArraysIndirectCount(primitive_mode, nullptr, 0,
|
glMultiDrawArraysIndirectCount(primitive_mode, gl_offset,
|
||||||
|
static_cast<GLintptr>(offset_base),
|
||||||
static_cast<GLsizei>(params.max_draw_counts),
|
static_cast<GLsizei>(params.max_draw_counts),
|
||||||
static_cast<GLsizei>(params.stride));
|
static_cast<GLsizei>(params.stride));
|
||||||
}
|
}
|
||||||
|
@ -305,11 +309,11 @@ void RasterizerOpenGL::DrawIndirect() {
|
||||||
}
|
}
|
||||||
if (params.is_indexed) {
|
if (params.is_indexed) {
|
||||||
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
|
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
|
||||||
glMultiDrawElementsIndirect(primitive_mode, format, nullptr,
|
glMultiDrawElementsIndirect(primitive_mode, format, gl_offset,
|
||||||
static_cast<GLsizei>(params.max_draw_counts),
|
static_cast<GLsizei>(params.max_draw_counts),
|
||||||
static_cast<GLsizei>(params.stride));
|
static_cast<GLsizei>(params.stride));
|
||||||
} else {
|
} else {
|
||||||
glMultiDrawArraysIndirect(primitive_mode, nullptr,
|
glMultiDrawArraysIndirect(primitive_mode, gl_offset,
|
||||||
static_cast<GLsizei>(params.max_draw_counts),
|
static_cast<GLsizei>(params.max_draw_counts),
|
||||||
static_cast<GLsizei>(params.stride));
|
static_cast<GLsizei>(params.stride));
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,29 +230,35 @@ void RasterizerVulkan::DrawIndirect() {
|
||||||
const auto& params = maxwell3d->draw_manager->GetIndirectParams();
|
const auto& params = maxwell3d->draw_manager->GetIndirectParams();
|
||||||
buffer_cache.SetDrawIndirect(¶ms);
|
buffer_cache.SetDrawIndirect(¶ms);
|
||||||
PrepareDraw(params.is_indexed, [this, ¶ms] {
|
PrepareDraw(params.is_indexed, [this, ¶ms] {
|
||||||
const auto buffer = buffer_cache.GetDrawIndirectBuffer();
|
const auto indirect_buffer = buffer_cache.GetDrawIndirectBuffer();
|
||||||
|
const auto& buffer = indirect_buffer.first;
|
||||||
|
const auto& offset = indirect_buffer.second;
|
||||||
if (params.include_count) {
|
if (params.include_count) {
|
||||||
const auto draw_buffer = buffer_cache.GetDrawIndirectCount();
|
const auto count = buffer_cache.GetDrawIndirectCount();
|
||||||
|
const auto& draw_buffer = count.first;
|
||||||
|
const auto& offset_base = count.second;
|
||||||
scheduler.Record([draw_buffer_obj = draw_buffer->Handle(),
|
scheduler.Record([draw_buffer_obj = draw_buffer->Handle(),
|
||||||
buffer_obj = buffer->Handle(), params](vk::CommandBuffer cmdbuf) {
|
buffer_obj = buffer->Handle(), offset_base, offset,
|
||||||
|
params](vk::CommandBuffer cmdbuf) {
|
||||||
if (params.is_indexed) {
|
if (params.is_indexed) {
|
||||||
cmdbuf.DrawIndexedIndirectCount(buffer_obj, 0, draw_buffer_obj, 0,
|
cmdbuf.DrawIndexedIndirectCount(
|
||||||
static_cast<u32>(params.max_draw_counts),
|
buffer_obj, offset, draw_buffer_obj, offset_base,
|
||||||
static_cast<u32>(params.stride));
|
static_cast<u32>(params.max_draw_counts), static_cast<u32>(params.stride));
|
||||||
} else {
|
} else {
|
||||||
cmdbuf.DrawIndirectCount(buffer_obj, 0, draw_buffer_obj, 0,
|
cmdbuf.DrawIndirectCount(buffer_obj, offset, draw_buffer_obj, offset_base,
|
||||||
static_cast<u32>(params.max_draw_counts),
|
static_cast<u32>(params.max_draw_counts),
|
||||||
static_cast<u32>(params.stride));
|
static_cast<u32>(params.stride));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scheduler.Record([buffer_obj = buffer->Handle(), params](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([buffer_obj = buffer->Handle(), offset, params](vk::CommandBuffer cmdbuf) {
|
||||||
if (params.is_indexed) {
|
if (params.is_indexed) {
|
||||||
cmdbuf.DrawIndexedIndirect(buffer_obj, 0, static_cast<u32>(params.max_draw_counts),
|
cmdbuf.DrawIndexedIndirect(buffer_obj, offset,
|
||||||
|
static_cast<u32>(params.max_draw_counts),
|
||||||
static_cast<u32>(params.stride));
|
static_cast<u32>(params.stride));
|
||||||
} else {
|
} else {
|
||||||
cmdbuf.DrawIndirect(buffer_obj, 0, static_cast<u32>(params.max_draw_counts),
|
cmdbuf.DrawIndirect(buffer_obj, offset, static_cast<u32>(params.max_draw_counts),
|
||||||
static_cast<u32>(params.stride));
|
static_cast<u32>(params.stride));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue