=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Introduce helper function to get shader type from byte code.

Alexandre Julliard julliard at winehq.org
Mon Apr 23 17:58:36 CDT 2018


Module: wine
Branch: master
Commit: 319abecc41d36e9c4d31ec9bf463b1d7ac4aa51e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=319abecc41d36e9c4d31ec9bf463b1d7ac4aa51e

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Mon Apr 23 16:20:14 2018 +0200

wined3d: Introduce helper function to get shader type from byte code.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/shader.c          | 24 +++++++++++++++
 dlls/wined3d/shader_sm4.c      | 69 +++++++++++++++++++++++++-----------------
 dlls/wined3d/wined3d_private.h |  4 +++
 3 files changed, 70 insertions(+), 27 deletions(-)

diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index c20c1da..8934c4f 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -419,6 +419,15 @@ static const struct wined3d_shader_frontend *shader_select_frontend(enum wined3d
     }
 }
 
+static enum wined3d_shader_type shader_get_shader_type(const struct wined3d_shader_desc *desc)
+{
+    if (desc->format == WINED3D_SHADER_BYTE_CODE_FORMAT_SM4)
+        return wined3d_get_sm4_shader_type(desc->byte_code, desc->byte_code_size);
+
+    FIXME("Could not get shader type for byte code format %#x.\n", desc->format);
+    return WINED3D_SHADER_TYPE_INVALID;
+}
+
 void string_buffer_clear(struct wined3d_string_buffer *buffer)
 {
     buffer->buffer[0] = '\0';
@@ -3722,8 +3731,23 @@ static HRESULT geometry_shader_init(struct wined3d_shader *shader, struct wined3
         void *parent, const struct wined3d_parent_ops *parent_ops)
 {
     struct wined3d_stream_output_element *elements = NULL;
+    enum wined3d_shader_type shader_type;
     HRESULT hr;
 
+    if (so_desc)
+    {
+        shader_type = shader_get_shader_type(desc);
+        switch (shader_type)
+        {
+            case WINED3D_SHADER_TYPE_VERTEX:
+            case WINED3D_SHADER_TYPE_DOMAIN:
+                FIXME("Stream output not supported for %s.\n", debug_shader_type(shader_type));
+                return E_NOTIMPL;
+            default:
+                break;
+        }
+    }
+
     if (so_desc && !(elements = heap_calloc(so_desc->element_count, sizeof(*elements))))
         return E_OUTOFMEMORY;
 
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index 8eac746..f11af76 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -1218,6 +1218,43 @@ static enum wined3d_data_type map_data_type(char t)
     }
 }
 
+enum wined3d_shader_type wined3d_get_sm4_shader_type(const DWORD *byte_code, size_t byte_code_size)
+{
+    DWORD shader_type;
+
+    if (byte_code_size / sizeof(*byte_code) < 1)
+    {
+        WARN("Invalid byte code size %lu.\n", (long)byte_code_size);
+        return WINED3D_SHADER_TYPE_INVALID;
+    }
+
+    shader_type = byte_code[0] >> 16;
+    switch (shader_type)
+    {
+        case WINED3D_SM4_PS:
+            return WINED3D_SHADER_TYPE_PIXEL;
+            break;
+        case WINED3D_SM4_VS:
+            return WINED3D_SHADER_TYPE_VERTEX;
+            break;
+        case WINED3D_SM4_GS:
+            return WINED3D_SHADER_TYPE_GEOMETRY;
+            break;
+        case WINED3D_SM5_HS:
+            return WINED3D_SHADER_TYPE_HULL;
+            break;
+        case WINED3D_SM5_DS:
+            return WINED3D_SHADER_TYPE_DOMAIN;
+            break;
+        case WINED3D_SM5_CS:
+            return WINED3D_SHADER_TYPE_COMPUTE;
+            break;
+        default:
+            FIXME("Unrecognised shader type %#x.\n", shader_type);
+            return WINED3D_SHADER_TYPE_INVALID;
+    }
+}
+
 static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
         const struct wined3d_shader_signature *output_signature)
 {
@@ -1251,35 +1288,13 @@ static void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
     priv->start = &byte_code[2];
     priv->end = &byte_code[token_count];
 
-    switch (version_token >> 16)
+    priv->shader_version.type = wined3d_get_sm4_shader_type(byte_code, byte_code_size);
+    if (priv->shader_version.type == WINED3D_SHADER_TYPE_INVALID)
     {
-        case WINED3D_SM4_PS:
-            priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL;
-            break;
-
-        case WINED3D_SM4_VS:
-            priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX;
-            break;
-
-        case WINED3D_SM4_GS:
-            priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY;
-            break;
-
-        case WINED3D_SM5_HS:
-            priv->shader_version.type = WINED3D_SHADER_TYPE_HULL;
-            break;
-
-        case WINED3D_SM5_DS:
-            priv->shader_version.type = WINED3D_SHADER_TYPE_DOMAIN;
-            break;
-
-        case WINED3D_SM5_CS:
-            priv->shader_version.type = WINED3D_SHADER_TYPE_COMPUTE;
-            break;
-
-        default:
-            FIXME("Unrecognised shader type %#x.\n", version_token >> 16);
+        heap_free(priv);
+        return NULL;
     }
+
     priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token);
     priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token);
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e9e3f86..9ab1843 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -929,6 +929,7 @@ enum wined3d_shader_type
 
     WINED3D_SHADER_TYPE_COMPUTE = WINED3D_SHADER_TYPE_GRAPHICS_COUNT,
     WINED3D_SHADER_TYPE_COUNT,
+    WINED3D_SHADER_TYPE_INVALID = WINED3D_SHADER_TYPE_COUNT,
 };
 
 struct wined3d_shader_version
@@ -1265,6 +1266,9 @@ struct wined3d_shader_frontend
 extern const struct wined3d_shader_frontend sm1_shader_frontend DECLSPEC_HIDDEN;
 extern const struct wined3d_shader_frontend sm4_shader_frontend DECLSPEC_HIDDEN;
 
+enum wined3d_shader_type wined3d_get_sm4_shader_type(const DWORD *byte_code,
+        size_t byte_code_size) DECLSPEC_HIDDEN;
+
 typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
 
 #define WINED3D_SHADER_CAP_VS_CLIPPING      0x00000001




More information about the wine-cvs mailing list