diff --git a/README.md b/README.md
index 8a3453b1e..fa9ded158 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
yuzu emulator early access
=============
-This is the source code for early-access 3386.
+This is the source code for early-access 3390.
## Legal Notice
diff --git a/src/video_core/buffer_cache/buffer_base.h b/src/video_core/buffer_cache/buffer_base.h
index 172e849b6..0a44caa66 100755
--- a/src/video_core/buffer_cache/buffer_base.h
+++ b/src/video_core/buffer_cache/buffer_base.h
@@ -289,11 +289,6 @@ public:
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
/// @pre IsInBounds returns true
[[nodiscard]] u32 Offset(VAddr other_cpu_addr) const noexcept {
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index e46e0f518..b2b0c8ae6 100755
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -205,9 +205,9 @@ public:
current_draw_indirect = current_draw_indirect_;
}
- [[nodiscard]] typename BufferCache
::Buffer* GetDrawIndirectCount();
+ [[nodiscard]] std::pair GetDrawIndirectCount();
- [[nodiscard]] typename BufferCache::Buffer* GetDrawIndirectBuffer();
+ [[nodiscard]] std::pair GetDrawIndirectBuffer();
std::recursive_mutex mutex;
Runtime& runtime;
@@ -385,9 +385,6 @@ private:
SlotVector slot_buffers;
DelayedDestructionRing delayed_destruction_ring;
- Buffer indirect_buffer;
- Buffer indirect_count_buffer;
-
const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{};
u32 last_index_count = 0;
@@ -461,9 +458,7 @@ private:
template
BufferCache::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
Core::Memory::Memory& cpu_memory_, Runtime& runtime_)
- : runtime{runtime_}, rasterizer{rasterizer_}, cpu_memory{cpu_memory_},
- indirect_buffer(runtime, rasterizer, 0, 0x1000),
- indirect_count_buffer(runtime, rasterizer, 0, 0x1000) {
+ : runtime{runtime_}, rasterizer{rasterizer_}, cpu_memory{cpu_memory_} {
// Ensure the first slot is used for the null buffer
void(slot_buffers.insert(runtime, NullBufferParams{}));
common_ranges.clear();
@@ -1069,13 +1064,15 @@ void BufferCache
::BindHostVertexBuffers() {
template
void BufferCache::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);
};
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
@@ -1412,16 +1409,14 @@ void BufferCache::UpdateDrawIndirect() {
binding = Binding{
.cpu_addr = *cpu_addr,
.size = static_cast(size),
- .buffer_id = NULL_BUFFER_ID,
+ .buffer_id = FindBuffer(*cpu_addr, static_cast(size)),
};
};
if (current_draw_indirect->include_count) {
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,
indirect_buffer_binding);
- indirect_buffer.UpdateCpuAddr(indirect_buffer_binding.cpu_addr);
}
template
@@ -2005,13 +2000,15 @@ bool BufferCache::HasFastUniformBufferBound(size_t stage, u32 binding_index)
}
template
-typename BufferCache::Buffer* BufferCache
::GetDrawIndirectCount() {
- return &indirect_count_buffer;
+std::pair::Buffer*, u32> BufferCache::GetDrawIndirectCount() {
+ auto& buffer = slot_buffers[count_buffer_binding.buffer_id];
+ return std::make_pair(&buffer, buffer.Offset(count_buffer_binding.cpu_addr));
}
template
-typename BufferCache::Buffer* BufferCache
::GetDrawIndirectBuffer() {
- return &indirect_buffer;
+std::pair::Buffer*, u32> BufferCache::GetDrawIndirectBuffer() {
+ auto& buffer = slot_buffers[indirect_buffer_binding.buffer_id];
+ return std::make_pair(&buffer, buffer.Offset(indirect_buffer_binding.cpu_addr));
}
} // namespace VideoCommon
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 3461b3bae..5bea7e66c 100755
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -285,19 +285,23 @@ void RasterizerOpenGL::DrawIndirect() {
const auto& params = maxwell3d->draw_manager->GetIndirectParams();
buffer_cache.SetDrawIndirect(¶ms);
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(static_cast(offset));
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer->Handle());
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());
if (params.is_indexed) {
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
- glMultiDrawElementsIndirectCount(primitive_mode, format, nullptr, 0,
+ glMultiDrawElementsIndirectCount(primitive_mode, format, gl_offset,
+ static_cast(offset_base),
static_cast(params.max_draw_counts),
static_cast(params.stride));
} else {
- glMultiDrawArraysIndirectCount(primitive_mode, nullptr, 0,
+ glMultiDrawArraysIndirectCount(primitive_mode, gl_offset,
+ static_cast(offset_base),
static_cast(params.max_draw_counts),
static_cast(params.stride));
}
@@ -305,11 +309,11 @@ void RasterizerOpenGL::DrawIndirect() {
}
if (params.is_indexed) {
const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
- glMultiDrawElementsIndirect(primitive_mode, format, nullptr,
+ glMultiDrawElementsIndirect(primitive_mode, format, gl_offset,
static_cast(params.max_draw_counts),
static_cast(params.stride));
} else {
- glMultiDrawArraysIndirect(primitive_mode, nullptr,
+ glMultiDrawArraysIndirect(primitive_mode, gl_offset,
static_cast(params.max_draw_counts),
static_cast(params.stride));
}
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index e1dccfadd..4d64a62f8 100755
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -230,29 +230,35 @@ void RasterizerVulkan::DrawIndirect() {
const auto& params = maxwell3d->draw_manager->GetIndirectParams();
buffer_cache.SetDrawIndirect(¶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) {
- 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(),
- buffer_obj = buffer->Handle(), params](vk::CommandBuffer cmdbuf) {
+ buffer_obj = buffer->Handle(), offset_base, offset,
+ params](vk::CommandBuffer cmdbuf) {
if (params.is_indexed) {
- cmdbuf.DrawIndexedIndirectCount(buffer_obj, 0, draw_buffer_obj, 0,
- static_cast(params.max_draw_counts),
- static_cast(params.stride));
+ cmdbuf.DrawIndexedIndirectCount(
+ buffer_obj, offset, draw_buffer_obj, offset_base,
+ static_cast(params.max_draw_counts), static_cast(params.stride));
} else {
- cmdbuf.DrawIndirectCount(buffer_obj, 0, draw_buffer_obj, 0,
+ cmdbuf.DrawIndirectCount(buffer_obj, offset, draw_buffer_obj, offset_base,
static_cast(params.max_draw_counts),
static_cast(params.stride));
}
});
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) {
- cmdbuf.DrawIndexedIndirect(buffer_obj, 0, static_cast(params.max_draw_counts),
+ cmdbuf.DrawIndexedIndirect(buffer_obj, offset,
+ static_cast(params.max_draw_counts),
static_cast(params.stride));
} else {
- cmdbuf.DrawIndirect(buffer_obj, 0, static_cast(params.max_draw_counts),
+ cmdbuf.DrawIndirect(buffer_obj, offset, static_cast(params.max_draw_counts),
static_cast(params.stride));
}
});