[PATCH] wind3d: Acknowledge additional instruction modifiers

Tobias Klausmann tobias.johannes.klausmann at mni.thm.de
Sat Sep 8 16:36:58 CDT 2018


Extended opcodes (modifiers) are primarily used for sign-extension, yet
there are some additional modifiers we can parse at least.

Information taken from dxvk implementation!

There should be no functional change beyond the FIXME -> TRACE change for the
newly acknowledge modifiers.

Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de>
---
 dlls/wined3d/shader_sm4.c | 98 +++++++++++++++++++++++++++------------
 1 file changed, 69 insertions(+), 29 deletions(-)

diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index b119e8feaa..ad0ac9e80a 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -25,14 +25,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode);
 
 #define WINED3D_SM4_INSTRUCTION_MODIFIER        (0x1u << 31)
+#define WINED3D_SM4_INSTRUCTION_MODIFIER_BIT 31
 
-#define WINED3D_SM4_MODIFIER_AOFFIMMI           0x1
-#define WINED3D_SM4_AOFFIMMI_U_SHIFT            9
-#define WINED3D_SM4_AOFFIMMI_U_MASK             (0xfu << WINED3D_SM4_AOFFIMMI_U_SHIFT)
-#define WINED3D_SM4_AOFFIMMI_V_SHIFT            13
-#define WINED3D_SM4_AOFFIMMI_V_MASK             (0xfu << WINED3D_SM4_AOFFIMMI_V_SHIFT)
-#define WINED3D_SM4_AOFFIMMI_W_SHIFT            17
-#define WINED3D_SM4_AOFFIMMI_W_MASK             (0xfu << WINED3D_SM4_AOFFIMMI_W_SHIFT)
+#define WINED3D_SM4_MODIFIER_FIELD_BIT_LOW      0
+#define WINED3D_SM4_MODIFIER_FIELD_BIT_HIGH     5
+
+#define WINED3D_SM4_AOFFIMMI_U_BIT_LOW          9
+#define WINED3D_SM4_AOFFIMMI_U_BIT_HIGH         12
+
+#define WINED3D_SM4_AOFFIMMI_V_BIT_LOW          13
+#define WINED3D_SM4_AOFFIMMI_V_BIT_HIGH         16
+
+#define WINED3D_SM4_AOFFIMMI_W_BIT_LOW          17
+#define WINED3D_SM4_AOFFIMMI_W_BIT_HIGH         20
 
 #define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT    24
 #define WINED3D_SM4_INSTRUCTION_LENGTH_MASK     (0x1fu << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT)
@@ -304,6 +309,13 @@ enum wined3d_sm4_opcode
     WINED3D_SM5_OP_DCL_GS_INSTANCES                 = 0xce,
 };
 
+enum wined3d_sm4_ext_opcode {
+    WINED3D_SM4_EXT_OP_EMPTY = 0,
+    WINED3D_SM4_EXT_OP_SAMPLE_CONTROLS,
+    WINED3D_SM4_EXT_OP_RESOURCE_DIM,
+    WINED3D_SM4_EXT_OP_RESOURCE_RETURN_TYPE,
+};
+
 enum wined3d_sm4_register_type
 {
     WINED3D_SM4_RT_TEMP                    = 0x00,
@@ -1222,6 +1234,10 @@ static enum wined3d_data_type map_data_type(char t)
     }
 }
 
+inline DWORD bit_extract32(DWORD value, DWORD fst, DWORD lst) {
+  return (value >> fst) & ~(~0 << (lst - fst + 1));
+}
+
 enum wined3d_shader_type wined3d_get_sm4_shader_type(const DWORD *byte_code, size_t byte_code_size)
 {
     DWORD shader_type;
@@ -1610,32 +1626,56 @@ static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD
 
 static void shader_sm4_read_instruction_modifier(DWORD modifier, struct wined3d_shader_instruction *ins)
 {
-    static const DWORD recognized_bits = WINED3D_SM4_INSTRUCTION_MODIFIER
-            | WINED3D_SM4_MODIFIER_AOFFIMMI
-            | WINED3D_SM4_AOFFIMMI_U_MASK
-            | WINED3D_SM4_AOFFIMMI_V_MASK
-            | WINED3D_SM4_AOFFIMMI_W_MASK;
-
-    if (modifier & ~recognized_bits)
+    if (bit_extract32(modifier,
+            WINED3D_SM4_INSTRUCTION_MODIFIER_BIT,
+            WINED3D_SM4_INSTRUCTION_MODIFIER_BIT))
     {
-        FIXME("Unhandled modifier 0x%08x.\n", modifier);
+        const DWORD extOpcode = bit_extract32(modifier,
+                WINED3D_SM4_MODIFIER_FIELD_BIT_LOW,
+                WINED3D_SM4_MODIFIER_FIELD_BIT_HIGH);
+
+        switch (extOpcode)
+        {
+        case WINED3D_SM4_EXT_OP_SAMPLE_CONTROLS: {
+            /* Bit fields are used for sign extension */
+            struct
+            {
+                int u : 4;
+                int v : 4;
+                int w : 4;
+            }
+            aoffimmi;
+
+            aoffimmi.u = bit_extract32(modifier,
+                    WINED3D_SM4_AOFFIMMI_U_BIT_LOW,
+                    WINED3D_SM4_AOFFIMMI_U_BIT_HIGH);
+            aoffimmi.v = bit_extract32(modifier,
+                    WINED3D_SM4_AOFFIMMI_V_BIT_LOW,
+                    WINED3D_SM4_AOFFIMMI_V_BIT_HIGH);
+            aoffimmi.w = bit_extract32(modifier,
+                    WINED3D_SM4_AOFFIMMI_W_BIT_LOW,
+                    WINED3D_SM4_AOFFIMMI_W_BIT_HIGH);
+
+            ins->texel_offset.u = aoffimmi.u;
+            ins->texel_offset.v = aoffimmi.v;
+            ins->texel_offset.w = aoffimmi.w;
+        }
+            break;
+
+        case WINED3D_SM4_EXT_OP_RESOURCE_DIM:
+        case WINED3D_SM4_EXT_OP_RESOURCE_RETURN_TYPE:
+            TRACE("Unhandled opcode extension 0x%08x -> %d\n", modifier,
+                    extOpcode);
+            break;  // part of resource description
+
+        default:
+            FIXME("Unhandled opcode extension 0x%08x\n", modifier);
+            break;
+        }
     }
     else
     {
-        /* Bit fields are used for sign extension */
-        struct
-        {
-            int u : 4;
-            int v : 4;
-            int w : 4;
-        }
-        aoffimmi;
-        aoffimmi.u = (modifier & WINED3D_SM4_AOFFIMMI_U_MASK) >> WINED3D_SM4_AOFFIMMI_U_SHIFT;
-        aoffimmi.v = (modifier & WINED3D_SM4_AOFFIMMI_V_MASK) >> WINED3D_SM4_AOFFIMMI_V_SHIFT;
-        aoffimmi.w = (modifier & WINED3D_SM4_AOFFIMMI_W_MASK) >> WINED3D_SM4_AOFFIMMI_W_SHIFT;
-        ins->texel_offset.u = aoffimmi.u;
-        ins->texel_offset.v = aoffimmi.v;
-        ins->texel_offset.w = aoffimmi.w;
+        FIXME("Unhandled modifier 0x%08x\n", modifier);
     }
 }
 
-- 
2.18.0




More information about the wine-devel mailing list