[PATCH vkd3d 2/2] vkd3d-shader: Compute XfbOffset per buffer.

Conor McCarthy cmccarthy at codeweavers.com
Tue Jul 20 09:24:29 CDT 2021


Fixes NVIDIA HairWorks GPU crash on Metro Exodus.

From: Hans-Kristian Arntzen <post at arntzen-software.no>
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d-shader/spirv.c | 11 +++++++----
 tests/d3d12.c             |  2 --
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 65834696..445ca668 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -17,6 +17,7 @@
  */
 
 #include "vkd3d_shader_private.h"
+#include "vkd3d_d3d12.h"
 #include "rbtree.h"
 
 #include <stdarg.h>
@@ -4066,13 +4067,15 @@ static void vkd3d_dxbc_compiler_decorate_xfb_output(struct vkd3d_dxbc_compiler *
     const struct vkd3d_shader_transform_feedback_info *xfb_info = compiler->xfb_info;
     const struct vkd3d_shader_transform_feedback_element *xfb_element;
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
-    unsigned int offset, stride, i;
+    unsigned int buffer_offsets[D3D12_SO_BUFFER_SLOT_COUNT];
+    unsigned int stride, i;
 
     if (!xfb_info)
         return;
 
-    offset = 0;
+    memset(buffer_offsets, 0, sizeof(buffer_offsets));
     xfb_element = NULL;
+
     for (i = 0; i < xfb_info->element_count; ++i)
     {
         const struct vkd3d_shader_transform_feedback_element *e = &xfb_info->elements[i];
@@ -4085,7 +4088,7 @@ static void vkd3d_dxbc_compiler_decorate_xfb_output(struct vkd3d_dxbc_compiler *
             break;
         }
 
-        offset += 4 * e->component_count;
+        buffer_offsets[e->output_slot] += 4 * e->component_count;
     }
 
     if (!xfb_element)
@@ -4115,7 +4118,7 @@ static void vkd3d_dxbc_compiler_decorate_xfb_output(struct vkd3d_dxbc_compiler *
 
     vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationXfbBuffer, xfb_element->output_slot);
     vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationXfbStride, stride);
-    vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationOffset, offset);
+    vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationOffset, buffer_offsets[xfb_element->output_slot]);
 }
 
 static uint32_t vkd3d_dxbc_compiler_emit_builtin_variable(struct vkd3d_dxbc_compiler *compiler,
diff --git a/tests/d3d12.c b/tests/d3d12.c
index ee9b55fe..940736bb 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -28505,13 +28505,11 @@ static void test_line_tessellation(void)
         data = get_readback_data(&rb, i + 2048 / (2 * sizeof(*data)), 0, 0, 2 * sizeof(*data));
         expected = &expected_data[3 * i + 1];
         bug_if(is_nvidia_device(context.device))
-        todo_if(i != 6)
         ok(compare_vec4(data, expected, 1),
                 "Got color {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e} at %u.\n",
                 data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w, i);
         ++data;
         expected = &expected_data[3 * i + 2];
-        todo
         ok(compare_vec4(data, expected, 1),
                 "Got primitive ID {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e} at %u.\n",
                 data->x, data->y, data->z, data->w, expected->x, expected->y, expected->z, expected->w, i);
-- 
2.32.0




More information about the wine-devel mailing list