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

Macro HLE: Add DrawIndirectByteCount

Fernando Sahmkow 3 лет назад
Родитель
Сommit
57401589c2

+ 1 - 0
src/video_core/engines/draw_manager.h

@@ -46,6 +46,7 @@ public:
     };
 
     struct IndirectParams {
+        bool is_byte_count;
         bool is_indexed;
         bool include_count;
         GPUVAddr count_start_address;

+ 30 - 5
src/video_core/macro/macro_hle.cpp

@@ -67,6 +67,7 @@ public:
         }
 
         auto& params = maxwell3d.draw_manager->GetIndirectParams();
+        params.is_byte_count = false;
         params.is_indexed = false;
         params.include_count = false;
         params.count_start_address = 0;
@@ -161,6 +162,7 @@ public:
                 0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
         }
         auto& params = maxwell3d.draw_manager->GetIndirectParams();
+        params.is_byte_count = false;
         params.is_indexed = true;
         params.include_count = false;
         params.count_start_address = 0;
@@ -256,6 +258,7 @@ public:
         const u32 estimate = static_cast<u32>(maxwell3d.EstimateIndexBufferSize());
         maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
         auto& params = maxwell3d.draw_manager->GetIndirectParams();
+        params.is_byte_count = false;
         params.is_indexed = true;
         params.include_count = true;
         params.count_start_address = maxwell3d.GetMacroAddress(4);
@@ -324,17 +327,39 @@ public:
     explicit HLE_DrawIndirectByteCount(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
 
     void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
+        auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0xFFFFU);
+        if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) {
+            Fallback(parameters);
+            return;
+        }
+
+        auto& params = maxwell3d.draw_manager->GetIndirectParams();
+        params.is_byte_count = true;
+        params.is_indexed = false;
+        params.include_count = false;
+        params.count_start_address = 0;
+        params.indirect_start_address = maxwell3d.GetMacroAddress(2);
+        params.buffer_size = 4;
+        params.max_draw_counts = 1;
+        params.stride = parameters[1];
+        maxwell3d.regs.draw.begin = parameters[0];
+        maxwell3d.regs.draw_auto_stride = parameters[1];
+        maxwell3d.regs.draw_auto_byte_count = parameters[2];
+
+        maxwell3d.draw_manager->DrawArrayIndirect(topology);
+    }
+
+private:
+    void Fallback(const std::vector<u32>& parameters) {
         maxwell3d.RefreshParameters();
 
         maxwell3d.regs.draw.begin = parameters[0];
         maxwell3d.regs.draw_auto_stride = parameters[1];
         maxwell3d.regs.draw_auto_byte_count = parameters[2];
 
-        if (maxwell3d.ShouldExecute()) {
-            maxwell3d.draw_manager->DrawArray(
-                maxwell3d.regs.draw.topology, 0,
-                maxwell3d.regs.draw_auto_byte_count / maxwell3d.regs.draw_auto_stride, 0, 1);
-        }
+        maxwell3d.draw_manager->DrawArray(
+            maxwell3d.regs.draw.topology, 0,
+            maxwell3d.regs.draw_auto_byte_count / maxwell3d.regs.draw_auto_stride, 0, 1);
     }
 };
 

+ 1 - 0
src/video_core/vulkan_common/vulkan_wrapper.cpp

@@ -101,6 +101,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
     X(vkCmdDrawIndexedIndirect);
     X(vkCmdDrawIndirectCount);
     X(vkCmdDrawIndexedIndirectCount);
+    X(vkCmdDrawIndirectByteCountEXT);
     X(vkCmdEndConditionalRenderingEXT);
     X(vkCmdEndQuery);
     X(vkCmdEndRenderPass);

+ 8 - 0
src/video_core/vulkan_common/vulkan_wrapper.h

@@ -212,6 +212,7 @@ struct DeviceDispatch : InstanceDispatch {
     PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect{};
     PFN_vkCmdDrawIndirectCount vkCmdDrawIndirectCount{};
     PFN_vkCmdDrawIndexedIndirectCount vkCmdDrawIndexedIndirectCount{};
+    PFN_vkCmdDrawIndirectByteCountEXT vkCmdDrawIndirectByteCountEXT{};
     PFN_vkCmdEndConditionalRenderingEXT vkCmdEndConditionalRenderingEXT{};
     PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT{};
     PFN_vkCmdEndQuery vkCmdEndQuery{};
@@ -1185,6 +1186,13 @@ public:
                                            count_offset, draw_count, stride);
     }
 
+    void DrawIndirectByteCountEXT(u32 instance_count, u32 first_instance, VkBuffer counter_buffer,
+                                  VkDeviceSize counter_buffer_offset, u32 counter_offset,
+                                  u32 stride) {
+        dld->vkCmdDrawIndirectByteCountEXT(handle, instance_count, first_instance, counter_buffer,
+                                           counter_buffer_offset, counter_offset, stride);
+    }
+
     void ClearAttachments(Span<VkClearAttachment> attachments,
                           Span<VkClearRect> rects) const noexcept {
         dld->vkCmdClearAttachments(handle, attachments.size(), attachments.data(), rects.size(),