Henri Verbeet : vkd3d-shader/hlsl: Respect the requested target type.

Alexandre Julliard julliard at winehq.org
Mon Feb 28 15:48:37 CST 2022


Module: vkd3d
Branch: master
Commit: f5c4c06090d45598b99caf40ebf02e2afa8d580f
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=f5c4c06090d45598b99caf40ebf02e2afa8d580f

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Mon Feb 28 12:23:43 2022 +0100

vkd3d-shader/hlsl: Respect the requested target type.

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 include/vkd3d_shader.h                   |  5 +++++
 libs/vkd3d-shader/hlsl.c                 | 17 +++++++++++++--
 libs/vkd3d-shader/hlsl.h                 |  3 ++-
 libs/vkd3d-shader/hlsl_codegen.c         | 19 ++++++++++++-----
 libs/vkd3d-shader/vkd3d_shader_main.c    |  1 +
 libs/vkd3d-shader/vkd3d_shader_private.h |  3 ++-
 libs/vkd3d-utils/vkd3d_utils_main.c      | 36 ++++++++++++++++++++++++++++++++
 programs/vkd3d-compiler/main.c           |  4 ++++
 8 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 6ce9819..be2be3c 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -581,6 +581,11 @@ enum vkd3d_shader_target_type
     VKD3D_SHADER_TARGET_SPIRV_BINARY,
     VKD3D_SHADER_TARGET_SPIRV_TEXT,
     VKD3D_SHADER_TARGET_D3D_ASM,
+    /**
+     * Legacy Direct3D byte-code. This is the format used for Direct3D shader
+     * model 1, 2, and 3 shaders.
+     */
+    VKD3D_SHADER_TARGET_D3D_BYTECODE,
     /**
      * A 'Tokenized Program Format' shader embedded in a DXBC container. This is
      * the format used for Direct3D shader model 4 and 5 shaders.
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index a9a4277..8197fa9 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -1952,7 +1952,7 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx)
 }
 
 int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info,
-        struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context)
+        struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
 {
     const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
     struct hlsl_ir_function_decl *entry_func;
@@ -1976,6 +1976,19 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
 
     vkd3d_shader_dump_shader(compile_info->source_type, profile->type, &compile_info->source);
 
+    if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE && profile->major_version > 3)
+    {
+        vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
+                "The '%s' target profile is incompatible with the 'd3dbc' target type.", profile->name);
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+    else if (compile_info->target_type == VKD3D_SHADER_TARGET_DXBC_TPF && profile->major_version < 4)
+    {
+        vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
+                "The '%s' target profile is incompatible with the 'dxbc-tpf' target type.", profile->name);
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+
     if (!hlsl_ctx_init(&ctx, compile_info->source_name, profile, message_context))
         return VKD3D_ERROR_OUT_OF_MEMORY;
 
@@ -2009,7 +2022,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
         return VKD3D_ERROR_INVALID_SHADER;
     }
 
-    ret = hlsl_emit_dxbc(&ctx, entry_func, dxbc);
+    ret = hlsl_emit_bytecode(&ctx, entry_func, compile_info->target_type, out);
 
     hlsl_ctx_cleanup(&ctx);
     return ret;
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index 043d7fb..243ed72 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -711,7 +711,8 @@ bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var
 
 void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func);
 
-int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out);
+int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
+        enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);
 
 void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new);
 
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index e416647..837d39e 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -1611,7 +1611,8 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere
     return ret;
 }
 
-int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out)
+int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
+        enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out)
 {
     struct hlsl_block *const body = &entry_func->body;
     struct hlsl_ir_var *var;
@@ -1697,8 +1698,16 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
     if (ctx->result)
         return ctx->result;
 
-    if (ctx->profile->major_version < 4)
-        return hlsl_sm1_write(ctx, entry_func, out);
-    else
-        return hlsl_sm4_write(ctx, entry_func, out);
+    switch (target_type)
+    {
+        case VKD3D_SHADER_TARGET_D3D_BYTECODE:
+            return hlsl_sm1_write(ctx, entry_func, out);
+
+        case VKD3D_SHADER_TARGET_DXBC_TPF:
+            return hlsl_sm4_write(ctx, entry_func, out);
+
+        default:
+            ERR("Unsupported shader target type %#x.\n", target_type);
+            return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
 }
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index ae0662b..a25e28a 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -1399,6 +1399,7 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
 
     static const enum vkd3d_shader_target_type hlsl_types[] =
     {
+        VKD3D_SHADER_TARGET_D3D_BYTECODE,
         VKD3D_SHADER_TARGET_DXBC_TPF,
     };
 
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 5ab8494..50c1e9d 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -116,6 +116,7 @@ enum vkd3d_shader_error
     VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED             = 5017,
     VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET        = 5018,
     VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS        = 5019,
+    VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE        = 5020,
 
     VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION       = 5300,
 
@@ -1094,7 +1095,7 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
         struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
 
 int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info,
-        struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context);
+        struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
 
 static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type(
         enum vkd3d_data_type data_type)
diff --git a/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d-utils/vkd3d_utils_main.c
index ee3bfb4..006e5e2 100644
--- a/libs/vkd3d-utils/vkd3d_utils_main.c
+++ b/libs/vkd3d-utils/vkd3d_utils_main.c
@@ -163,10 +163,34 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
     struct vkd3d_shader_compile_option *option;
     struct vkd3d_shader_code byte_code;
     const D3D_SHADER_MACRO *macro;
+    size_t profile_len, i;
     char *messages;
     HRESULT hr;
     int ret;
 
+    static const char * const d3dbc_profiles[] =
+    {
+        "fx_2_",
+
+        "ps.1.",
+        "ps.2.",
+        "ps.3.",
+
+        "ps_1_",
+        "ps_2_",
+        "ps_3_",
+
+        "vs.1.",
+        "vs.2.",
+        "vs.3.",
+
+        "vs_1_",
+        "vs_2_",
+        "vs_3_",
+
+        "tx_1_",
+    };
+
     TRACE("data %p, data_size %lu, filename %s, macros %p, include %p, entry_point %s, "
             "profile %s, flags %#x, effect_flags %#x, secondary_flags %#x, secondary_data %p, "
             "secondary_data_size %lu, shader_blob %p, messages_blob %p.\n",
@@ -195,6 +219,18 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
     compile_info.log_level = VKD3D_SHADER_LOG_INFO;
     compile_info.source_name = filename;
 
+    profile_len = strlen(profile);
+    for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i)
+    {
+        size_t len = strlen(d3dbc_profiles[i]);
+
+        if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len))
+        {
+            compile_info.target_type = VKD3D_SHADER_TARGET_D3D_BYTECODE;
+            break;
+        }
+    }
+
     preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO;
     preprocess_info.next = &hlsl_info;
     preprocess_info.macros = (const struct vkd3d_shader_macro *)macros;
diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c
index c974c9a..f1a6b47 100644
--- a/programs/vkd3d-compiler/main.c
+++ b/programs/vkd3d-compiler/main.c
@@ -97,6 +97,10 @@ target_type_info[] =
     {VKD3D_SHADER_TARGET_D3D_ASM,
         "d3d-asm", "A shader in Direct3D assembly form.\n",
         false},
+    {VKD3D_SHADER_TARGET_D3D_BYTECODE,
+        "d3dbc",        "Legacy Direct3D byte-code.\n"
+        "                This is the format used for Direct3D shader model 1, 2, and 3 shaders.\n",
+        true},
     {VKD3D_SHADER_TARGET_DXBC_TPF,
         "dxbc-tpf",     "A 'Tokenized Program Format' shader embedded in a DXBC container.\n"
         "                This is the format used for Direct3D shader model 4 and 5 shaders.\n",




More information about the wine-cvs mailing list