[PATCH vkd3d 2/3] vkd3d-shader: Implement support for stencil export.

Conor McCarthy cmccarthy at codeweavers.com
Wed Oct 6 00:03:33 CDT 2021


Based on a vkd3d-proton patch by Philip Rebohle.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 include/vkd3d_shader.h                   |  1 +
 libs/vkd3d-shader/dxbc.c                 |  3 +++
 libs/vkd3d-shader/sm4.h                  |  1 +
 libs/vkd3d-shader/spirv.c                | 20 ++++++++++++++++++++
 libs/vkd3d-shader/trace.c                |  4 ++++
 libs/vkd3d-shader/vkd3d_shader_private.h |  2 ++
 6 files changed, 31 insertions(+)

diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 58e507b7..e8f329f3 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -578,6 +578,7 @@ enum vkd3d_shader_spirv_extension
     VKD3D_SHADER_SPIRV_EXTENSION_NONE,
     VKD3D_SHADER_SPIRV_EXTENSION_EXT_DEMOTE_TO_HELPER_INVOCATION,
     VKD3D_SHADER_SPIRV_EXTENSION_EXT_DESCRIPTOR_INDEXING,
+    VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT,
 
     VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SPIRV_EXTENSION),
 };
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 23814a35..3e4dfc6d 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -923,6 +923,8 @@ static const enum vkd3d_shader_register_type register_type_table[] =
     /* VKD3D_SM5_RT_GS_INSTANCE_ID */          VKD3DSPR_GSINSTID,
     /* VKD3D_SM5_RT_DEPTHOUT_GREATER_EQUAL */  VKD3DSPR_DEPTHOUTGE,
     /* VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL */     VKD3DSPR_DEPTHOUTLE,
+    /* VKD3D_SM5_RT_CYCLE_COUNTER */           ~0u,
+    /* VKD3D_SM5_RT_OUTPUT_STENCIL_REF */      VKD3DSPR_OUTSTENCILREF,
 };
 
 static const enum vkd3d_shader_register_precision register_precision_table[] =
@@ -1385,6 +1387,7 @@ static bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *re
         case VKD3DSPR_OUTPOINTID:
         case VKD3DSPR_PRIMID:
         case VKD3DSPR_SAMPLEMASK:
+        case VKD3DSPR_OUTSTENCILREF:
             return true;
         default:
             return false;
diff --git a/libs/vkd3d-shader/sm4.h b/libs/vkd3d-shader/sm4.h
index 3ac41cb0..ddcb9a86 100644
--- a/libs/vkd3d-shader/sm4.h
+++ b/libs/vkd3d-shader/sm4.h
@@ -397,6 +397,7 @@ enum vkd3d_sm4_register_type
     VKD3D_SM5_RT_GS_INSTANCE_ID          = 0x25,
     VKD3D_SM5_RT_DEPTHOUT_GREATER_EQUAL  = 0x26,
     VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL     = 0x27,
+    VKD3D_SM5_RT_OUTPUT_STENCIL_REF      = 0x29,
 };
 
 enum vkd3d_sm4_extended_operand_type
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index f604b8ef..b03558e4 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1840,6 +1840,8 @@ static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder,
             || vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT)
             || vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStorageImageArrayDynamicIndexing))
         vkd3d_spirv_build_op_extension(&stream, "SPV_EXT_descriptor_indexing");
+    if (vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStencilExportEXT))
+        vkd3d_spirv_build_op_extension(&stream, "SPV_EXT_shader_stencil_export");
 
     if (builder->ext_instr_set_glsl_450)
         vkd3d_spirv_build_op_ext_inst_import(&stream, builder->ext_instr_set_glsl_450, "GLSL.std.450");
@@ -2884,6 +2886,9 @@ static bool vkd3d_dxbc_compiler_get_register_name(char *buffer, unsigned int buf
         case VKD3DSPR_PRIMID:
             /* SPIRV-Tools disassembler generates names for SPIR-V built-ins. */
             return false;
+        case VKD3DSPR_OUTSTENCILREF:
+            snprintf(buffer, buffer_size, "oStencilRef");
+            break;
         default:
             FIXME("Unhandled register %#x.\n", reg->type);
             snprintf(buffer, buffer_size, "unrecognized_%#x", reg->type);
@@ -4090,6 +4095,8 @@ vkd3d_register_builtins[] =
     {VKD3DSPR_DEPTHOUT,         {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInFragDepth}},
     {VKD3DSPR_DEPTHOUTGE,       {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInFragDepth}},
     {VKD3DSPR_DEPTHOUTLE,       {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInFragDepth}},
+
+    {VKD3DSPR_OUTSTENCILREF,    {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInFragStencilRefEXT}},
 };
 
 static void vkd3d_dxbc_compiler_emit_register_execution_mode(struct vkd3d_dxbc_compiler *compiler,
@@ -4103,6 +4110,18 @@ static void vkd3d_dxbc_compiler_emit_register_execution_mode(struct vkd3d_dxbc_c
         case VKD3DSPR_DEPTHOUTLE:
             vkd3d_dxbc_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthLess, NULL, 0);
             break;
+        case VKD3DSPR_OUTSTENCILREF:
+            if (!vkd3d_dxbc_compiler_is_target_extension_supported(compiler,
+                    VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT))
+            {
+                FIXME("The target environment does not support stencil export.\n");
+                vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED,
+                        "Cannot export stencil reference value for register id %u. "
+                        "The target environment does not support stencil export.", reg->idx[0].offset);
+            }
+            vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityStencilExportEXT);
+            vkd3d_dxbc_compiler_emit_execution_mode(compiler, SpvExecutionModeStencilRefReplacingEXT, NULL, 0);
+            break;
         default:
             return;
     }
@@ -4864,6 +4883,7 @@ static void vkd3d_dxbc_compiler_emit_output_register(struct vkd3d_dxbc_compiler
     reg_symbol.info.reg.dcl_mask = write_mask;
     reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size;
     vkd3d_dxbc_compiler_put_symbol(compiler, &reg_symbol);
+    vkd3d_dxbc_compiler_emit_register_execution_mode(compiler, reg);
     vkd3d_dxbc_compiler_emit_register_debug_name(builder, output_id, reg);
 }
 
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c
index 45f38d13..d4dbf059 100644
--- a/libs/vkd3d-shader/trace.c
+++ b/libs/vkd3d-shader/trace.c
@@ -1027,6 +1027,10 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
             shader_addline(buffer, "vGSInstanceID");
             break;
 
+        case VKD3DSPR_OUTSTENCILREF:
+            shader_addline(buffer, "oStencilRef");
+            break;
+
         default:
             shader_addline(buffer, "<unhandled_rtype(%#x)>", reg->type);
             break;
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 8b3e7624..a06755d2 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -76,6 +76,7 @@ enum vkd3d_shader_error
     VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE        = 2001,
     VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING   = 2002,
     VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED   = 2003,
+    VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED   = 2004,
 
     VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY                 = 3000,
     VKD3D_SHADER_ERROR_RS_INVALID_VERSION               = 3001,
@@ -437,6 +438,7 @@ enum vkd3d_shader_register_type
     VKD3DSPR_DEPTHOUTGE,
     VKD3DSPR_DEPTHOUTLE,
     VKD3DSPR_RASTERIZER,
+    VKD3DSPR_OUTSTENCILREF,
 
     VKD3DSPR_INVALID = ~0u,
 };
-- 
2.32.0




More information about the wine-devel mailing list