[PATCH vkd3d 4/7] libs/vkd3d-shader: Implement swizzling for shader outputs.

Józef Kucia joseph.kucia at gmail.com
Thu May 24 06:08:35 CDT 2018


From: Józef Kucia <jkucia at codeweavers.com>

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 include/private/vkd3d_shader.h           | 23 ++++++++++++++++++++++-
 libs/vkd3d-shader/spirv.c                | 25 ++++++++++++++++++++++---
 libs/vkd3d-shader/vkd3d_shader_main.c    |  9 +++++----
 libs/vkd3d-shader/vkd3d_shader_private.h | 13 +------------
 libs/vkd3d/state.c                       |  2 +-
 programs/vkd3d-compiler/main.c           |  2 +-
 6 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/include/private/vkd3d_shader.h b/include/private/vkd3d_shader.h
index ed2fc8908263..1f8fa39765df 100644
--- a/include/private/vkd3d_shader.h
+++ b/include/private/vkd3d_shader.h
@@ -125,9 +125,16 @@ struct vkd3d_shader_interface
     unsigned int uav_counter_count;
 };
 
+struct vkd3d_shader_compile_arguments
+{
+    unsigned int *output_swizzles;
+    unsigned int output_swizzle_count;
+};
+
 int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_code *spirv, uint32_t compiler_options,
-        const struct vkd3d_shader_interface *shader_interface);
+        const struct vkd3d_shader_interface *shader_interface,
+        const struct vkd3d_shader_compile_arguments *compile_args);
 void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code);
 
 enum vkd3d_filter
@@ -390,6 +397,20 @@ struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element(
         unsigned int semantic_index, unsigned int stream_index);
 void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature);
 
+/* swizzle bits fields: wwzzyyxx */
+#define VKD3D_SWIZZLE_X (0u)
+#define VKD3D_SWIZZLE_Y (1u)
+#define VKD3D_SWIZZLE_Z (2u)
+#define VKD3D_SWIZZLE_W (3u)
+#define VKD3D_SWIZZLE_MASK (0x3u)
+#define VKD3D_SWIZZLE_SHIFT(idx) (2u * (idx))
+#define VKD3D_SWIZZLE(x, y, z, w) (((x & VKD3D_SWIZZLE_MASK) << VKD3D_SWIZZLE_SHIFT(0)) \
+        | ((y & VKD3D_SWIZZLE_MASK) << VKD3D_SWIZZLE_SHIFT(1)) \
+        | ((z & VKD3D_SWIZZLE_MASK) << VKD3D_SWIZZLE_SHIFT(2)) \
+        | ((w & VKD3D_SWIZZLE_MASK) << VKD3D_SWIZZLE_SHIFT(3)))
+#define VKD3D_NO_SWIZZLE \
+        VKD3D_SWIZZLE(VKD3D_SWIZZLE_X, VKD3D_SWIZZLE_Y, VKD3D_SWIZZLE_Z, VKD3D_SWIZZLE_W)
+
 #ifdef __cplusplus
 }
 #endif  /* __cplusplus */
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 53ddd44596cd..4b2b46c3b092 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1839,6 +1839,7 @@ struct vkd3d_dxbc_compiler
 
     struct vkd3d_shader_interface shader_interface;
     struct vkd3d_push_constant_buffer_binding *push_constants;
+    const struct vkd3d_shader_compile_arguments *compile_args;
 
     bool after_declarations_section;
     const struct vkd3d_shader_signature *input_signature;
@@ -1860,6 +1861,7 @@ struct vkd3d_dxbc_compiler
 struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version,
         const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options,
         const struct vkd3d_shader_interface *shader_interface,
+        const struct vkd3d_shader_compile_arguments *compile_args,
         const struct vkd3d_shader_scan_info *scan_info)
 {
     const struct vkd3d_shader_signature *output_signature = &shader_desc->output_signature;
@@ -1926,6 +1928,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
                 compiler->push_constants[i].pc = shader_interface->push_constant_buffers[i];
         }
     }
+    compiler->compile_args = compile_args;
 
     compiler->scan_info = scan_info;
 
@@ -3013,6 +3016,18 @@ static unsigned int vkd3d_dxbc_compiler_get_output_variable_index(
     return register_idx;
 }
 
+static unsigned int get_shader_output_swizzle(struct vkd3d_dxbc_compiler *compiler,
+        unsigned int register_idx)
+{
+    const struct vkd3d_shader_compile_arguments *compile_args;
+
+    if (!(compile_args = compiler->compile_args))
+        return VKD3D_NO_SWIZZLE;
+    if (register_idx >= compile_args->output_swizzle_count)
+        return VKD3D_NO_SWIZZLE;
+    return compile_args->output_swizzles[register_idx];
+}
+
 static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_input_sysval_semantic sysval)
 {
@@ -3069,7 +3084,10 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp
         compiler->output_info[signature_idx].component_type = component_type;
     }
 
-    if ((use_private_variable = component_type != VKD3D_TYPE_FLOAT || component_count != VKD3D_VEC4_SIZE))
+    use_private_variable = component_type != VKD3D_TYPE_FLOAT || component_count != VKD3D_VEC4_SIZE
+            || (signature_element
+            && get_shader_output_swizzle(compiler, signature_element->register_index) != VKD3D_NO_SWIZZLE);
+    if (use_private_variable)
         storage_class = SpvStorageClassPrivate;
 
     vkd3d_symbol_make_register(&reg_symbol, reg);
@@ -5900,7 +5918,7 @@ static void vkd3d_dxbc_compiler_emit_output_setup_function(struct vkd3d_dxbc_com
     uint32_t param_type_id[MAX_REG_OUTPUT + 1], param_id[MAX_REG_OUTPUT + 1] = {};
     const struct vkd3d_shader_signature *signature = compiler->output_signature;
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
-    DWORD write_mask, variable_idx;
+    DWORD write_mask, swizzle, variable_idx;
     unsigned int i, count;
 
     function_id = compiler->output_setup_function_id;
@@ -5945,8 +5963,9 @@ static void vkd3d_dxbc_compiler_emit_output_setup_function(struct vkd3d_dxbc_com
             continue;
 
         write_mask = signature->elements[i].mask & 0xff;
+        swizzle = get_shader_output_swizzle(compiler, signature->elements[i].register_index);
         val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
-                param_id[variable_idx], VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, write_mask);
+                param_id[variable_idx], VKD3D_TYPE_FLOAT, swizzle, write_mask);
 
         if (compiler->output_info[i].component_type != VKD3D_TYPE_FLOAT)
         {
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 9db8b56946f2..1de56ac935a2 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -58,7 +58,8 @@ static void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
 
 int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_code *spirv, uint32_t compiler_options,
-        const struct vkd3d_shader_interface *shader_interface)
+        const struct vkd3d_shader_interface *shader_interface,
+        const struct vkd3d_shader_compile_arguments *compile_args)
 {
     struct vkd3d_shader_instruction instruction;
     struct vkd3d_dxbc_compiler *spirv_compiler;
@@ -66,8 +67,8 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
     struct vkd3d_shader_parser parser;
     int ret;
 
-    TRACE("dxbc {%p, %zu}, spirv %p, compiler_options %#x, shader_interface %p.\n",
-            dxbc->code, dxbc->size, spirv, compiler_options, shader_interface);
+    TRACE("dxbc {%p, %zu}, spirv %p, compiler_options %#x, shader_interface %p, compile_args %p.\n",
+            dxbc->code, dxbc->size, spirv, compiler_options, shader_interface, compile_args);
 
     if ((ret = vkd3d_shader_scan_dxbc(dxbc, &scan_info)) < 0)
         return ret;
@@ -76,7 +77,7 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
         return ret;
 
     if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version,
-            &parser.shader_desc, compiler_options, shader_interface, &scan_info)))
+            &parser.shader_desc, compiler_options, shader_interface, compile_args, &scan_info)))
     {
         ERR("Failed to create DXBC compiler.\n");
         vkd3d_shader_parser_destroy(&parser);
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 45af2db438c3..4aeeb50e8817 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -780,6 +780,7 @@ struct vkd3d_dxbc_compiler;
 struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version,
         const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options,
         const struct vkd3d_shader_interface *shader_interface,
+        const struct vkd3d_shader_compile_arguments *compile_args,
         const struct vkd3d_shader_scan_info *scan_info) DECLSPEC_HIDDEN;
 void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction) DECLSPEC_HIDDEN;
@@ -850,18 +851,6 @@ static inline unsigned int vkd3d_write_mask_component_count(DWORD write_mask)
     return count;
 }
 
-/* swizzle bits fields: wwzzyyxx */
-#define VKD3D_SWIZZLE_X (0u)
-#define VKD3D_SWIZZLE_Y (1u)
-#define VKD3D_SWIZZLE_Z (2u)
-#define VKD3D_SWIZZLE_W (3u)
-#define VKD3D_SWIZZLE_MASK (0x3u)
-#define VKD3D_SWIZZLE_SHIFT(idx) (2u * (idx))
-#define VKD3D_NO_SWIZZLE ((VKD3D_SWIZZLE_X << VKD3D_SWIZZLE_SHIFT(0)) \
-        | (VKD3D_SWIZZLE_Y << VKD3D_SWIZZLE_SHIFT(1)) \
-        | (VKD3D_SWIZZLE_Z << VKD3D_SWIZZLE_SHIFT(2)) \
-        | (VKD3D_SWIZZLE_W << VKD3D_SWIZZLE_SHIFT(3)))
-
 static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle,
         unsigned int idx)
 {
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 4841b0de92b8..826d68f6f63c 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -1284,7 +1284,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
     shader_desc.flags = 0;
 
     dump_shader_stage(stage, code->pShaderBytecode, code->BytecodeLength);
-    if ((ret = vkd3d_shader_compile_dxbc(&dxbc, &spirv, 0, shader_interface)) < 0)
+    if ((ret = vkd3d_shader_compile_dxbc(&dxbc, &spirv, 0, shader_interface, NULL)) < 0)
     {
         WARN("Failed to compile shader, vkd3d result %d.\n", ret);
         return hresult_from_vkd3d_result(ret);
diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c
index 2e6566882a66..83ccd3d65a4a 100644
--- a/programs/vkd3d-compiler/main.c
+++ b/programs/vkd3d-compiler/main.c
@@ -163,7 +163,7 @@ int main(int argc, char **argv)
         return 1;
     }
 
-    hr = vkd3d_shader_compile_dxbc(&dxbc, &spirv, options.compiler_options, NULL);
+    hr = vkd3d_shader_compile_dxbc(&dxbc, &spirv, options.compiler_options, NULL, NULL);
     vkd3d_shader_free_shader_code(&dxbc);
     if (FAILED(hr))
     {
-- 
2.16.1




More information about the wine-devel mailing list