Просмотр исходного кода

video_core: Reimplement inline index buffer binding

Feng Chen 3 лет назад
Родитель
Сommit
cb971ad654

+ 31 - 2
src/video_core/buffer_cache/buffer_cache.h

@@ -992,7 +992,20 @@ void BufferCache<P>::BindHostIndexBuffer() {
     TouchBuffer(buffer, index_buffer.buffer_id);
     const u32 offset = buffer.Offset(index_buffer.cpu_addr);
     const u32 size = index_buffer.size;
-    SynchronizeBuffer(buffer, index_buffer.cpu_addr, size);
+    if (maxwell3d->inline_index_draw_indexes.size()) {
+        if constexpr (USE_MEMORY_MAPS) {
+            auto upload_staging = runtime.UploadStagingBuffer(size);
+            std::array<BufferCopy, 1> copies{
+                {BufferCopy{.src_offset = upload_staging.offset, .dst_offset = 0, .size = size}}};
+            std::memcpy(upload_staging.mapped_span.data(),
+                        maxwell3d->inline_index_draw_indexes.data(), size);
+            runtime.CopyBuffer(buffer, upload_staging.buffer, copies);
+        } else {
+            buffer.ImmediateUpload(0, maxwell3d->inline_index_draw_indexes);
+        }
+    } else {
+        SynchronizeBuffer(buffer, index_buffer.cpu_addr, size);
+    }
     if constexpr (HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) {
         const u32 new_offset = offset + maxwell3d->regs.index_buffer.first *
                                             maxwell3d->regs.index_buffer.FormatSizeInBytes();
@@ -1275,7 +1288,15 @@ void BufferCache<P>::UpdateIndexBuffer() {
     }
     flags[Dirty::IndexBuffer] = false;
     last_index_count = index_array.count;
-
+    if (maxwell3d->inline_index_draw_indexes.size()) {
+        auto inline_index_size = static_cast<u32>(maxwell3d->inline_index_draw_indexes.size());
+        index_buffer = Binding{
+            .cpu_addr = 0,
+            .size = inline_index_size,
+            .buffer_id = CreateBuffer(0, inline_index_size),
+        };
+        return;
+    }
     const GPUVAddr gpu_addr_begin = index_array.StartAddress();
     const GPUVAddr gpu_addr_end = index_array.EndAddress();
     const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr_begin);
@@ -1491,6 +1512,14 @@ typename BufferCache<P>::OverlapResult BufferCache<P>::ResolveOverlaps(VAddr cpu
     VAddr end = cpu_addr + wanted_size;
     int stream_score = 0;
     bool has_stream_leap = false;
+    if (begin == 0) {
+        return OverlapResult{
+            .ids = std::move(overlap_ids),
+            .begin = begin,
+            .end = end,
+            .has_stream_leap = has_stream_leap,
+        };
+    }
     for (; cpu_addr >> YUZU_PAGEBITS < Common::DivCeil(end, YUZU_PAGESIZE);
          cpu_addr += YUZU_PAGESIZE) {
         const BufferId overlap_id = page_table[cpu_addr >> YUZU_PAGEBITS];

+ 0 - 12
src/video_core/renderer_opengl/gl_rasterizer.cpp

@@ -222,8 +222,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) {
     pipeline->SetEngine(maxwell3d, gpu_memory);
     pipeline->Configure(is_indexed);
 
-    BindInlineIndexBuffer();
-
     SyncState();
 
     const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology);
@@ -1140,16 +1138,6 @@ void RasterizerOpenGL::ReleaseChannel(s32 channel_id) {
     query_cache.EraseChannel(channel_id);
 }
 
-void RasterizerOpenGL::BindInlineIndexBuffer() {
-    if (maxwell3d->inline_index_draw_indexes.empty()) {
-        return;
-    }
-    const auto data_count = static_cast<u32>(maxwell3d->inline_index_draw_indexes.size());
-    auto buffer = Buffer(buffer_cache_runtime, *this, 0, data_count);
-    buffer.ImmediateUpload(0, maxwell3d->inline_index_draw_indexes);
-    buffer_cache_runtime.BindIndexBuffer(buffer, 0, data_count);
-}
-
 AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {}
 
 bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) {

+ 0 - 2
src/video_core/renderer_opengl/gl_rasterizer.h

@@ -199,8 +199,6 @@ private:
     /// End a transform feedback
     void EndTransformFeedback();
 
-    void BindInlineIndexBuffer();
-
     Tegra::GPU& gpu;
 
     const Device& device;

+ 0 - 15
src/video_core/renderer_vulkan/vk_rasterizer.cpp

@@ -191,8 +191,6 @@ void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) {
     pipeline->SetEngine(maxwell3d, gpu_memory);
     pipeline->Configure(is_indexed);
 
-    BindInlineIndexBuffer();
-
     BeginTransformFeedback();
 
     UpdateDynamicStates();
@@ -1029,17 +1027,4 @@ void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
     query_cache.EraseChannel(channel_id);
 }
 
-void RasterizerVulkan::BindInlineIndexBuffer() {
-    if (maxwell3d->inline_index_draw_indexes.empty()) {
-        return;
-    }
-    const auto data_count = static_cast<u32>(maxwell3d->inline_index_draw_indexes.size());
-    auto buffer = buffer_cache_runtime.UploadStagingBuffer(data_count);
-    std::memcpy(buffer.mapped_span.data(), maxwell3d->inline_index_draw_indexes.data(), data_count);
-    buffer_cache_runtime.BindIndexBuffer(
-        maxwell3d->regs.draw.topology, maxwell3d->regs.index_buffer.format,
-        maxwell3d->regs.index_buffer.first, maxwell3d->regs.index_buffer.count, buffer.buffer,
-        static_cast<u32>(buffer.offset), data_count);
-}
-
 } // namespace Vulkan

+ 0 - 2
src/video_core/renderer_vulkan/vk_rasterizer.h

@@ -141,8 +141,6 @@ private:
 
     void UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs);
 
-    void BindInlineIndexBuffer();
-
     Tegra::GPU& gpu;
 
     ScreenInfo& screen_info;