=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Pack interpolation modes.

Alexandre Julliard julliard at winehq.org
Wed Oct 18 15:16:28 CDT 2017


Module: wine
Branch: master
Commit: 9cb69d91b2132876bdd3941384408bce91cf884b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9cb69d91b2132876bdd3941384408bce91cf884b

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Wed Oct 18 00:25:09 2017 +0200

wined3d: Pack interpolation modes.

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/glsl_shader.c     | 25 +++++++++++++++------
 dlls/wined3d/shader.c          | 18 ++++++++++++----
 dlls/wined3d/wined3d_private.h | 49 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 77 insertions(+), 15 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index e4aa6c5..a03f179 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2141,10 +2141,18 @@ static const char *shader_glsl_interpolation_qualifiers(enum wined3d_shader_inte
     }
 }
 
+static enum wined3d_shader_interpolation_mode wined3d_extract_interpolation_mode(
+        const DWORD *packed_interpolation_mode, unsigned int register_idx)
+{
+    return wined3d_extract_bits(packed_interpolation_mode,
+            register_idx * WINED3D_PACKED_INTERPOLATION_BIT_COUNT, WINED3D_PACKED_INTERPOLATION_BIT_COUNT);
+}
+
 static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_info,
         struct wined3d_string_buffer *buffer, unsigned int element_count,
-        const enum wined3d_shader_interpolation_mode *interpolation_mode, BOOL unroll)
+        const DWORD *interpolation_mode, BOOL unroll)
 {
+    enum wined3d_shader_interpolation_mode mode;
     unsigned int i;
 
     if (shader_glsl_use_interface_blocks(gl_info))
@@ -2154,8 +2162,8 @@ static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_i
             shader_addline(buffer, "in shader_in_out {\n");
             for (i = 0; i < element_count; ++i)
             {
-                shader_addline(buffer, "%s vec4 reg%u;\n",
-                        shader_glsl_interpolation_qualifiers(interpolation_mode[i]), i);
+                mode = wined3d_extract_interpolation_mode(interpolation_mode, i);
+                shader_addline(buffer, "%s vec4 reg%u;\n", shader_glsl_interpolation_qualifiers(mode), i);
             }
             shader_addline(buffer, "} shader_in;\n");
         }
@@ -2172,8 +2180,9 @@ static void shader_glsl_declare_shader_inputs(const struct wined3d_gl_info *gl_i
 
 static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_info,
         struct wined3d_string_buffer *buffer, unsigned int element_count, BOOL rasterizer_setup,
-        const enum wined3d_shader_interpolation_mode *interpolation_mode)
+        const DWORD *interpolation_mode)
 {
+    enum wined3d_shader_interpolation_mode mode;
     unsigned int i;
 
     if (shader_glsl_use_interface_blocks(gl_info))
@@ -2185,7 +2194,10 @@ static void shader_glsl_declare_shader_outputs(const struct wined3d_gl_info *gl_
             {
                 const char *interpolation_qualifiers = "";
                 if (needs_interpolation_qualifiers_for_shader_outputs(gl_info))
-                    interpolation_qualifiers = shader_glsl_interpolation_qualifiers(interpolation_mode[i]);
+                {
+                    mode = wined3d_extract_interpolation_mode(interpolation_mode, i);
+                    interpolation_qualifiers = shader_glsl_interpolation_qualifiers(mode);
+                }
                 shader_addline(buffer, "%s vec4 reg%u;\n", interpolation_qualifiers, i);
             }
             shader_addline(buffer, "} shader_out;\n");
@@ -7063,8 +7075,7 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
 
 static void shader_glsl_generate_sm4_output_setup(struct shader_glsl_priv *priv,
         const struct wined3d_shader *shader, unsigned int input_count,
-        const struct wined3d_gl_info *gl_info, BOOL rasterizer_setup,
-        const enum wined3d_shader_interpolation_mode *interpolation_mode)
+        const struct wined3d_gl_info *gl_info, BOOL rasterizer_setup, const DWORD *interpolation_mode)
 {
     const char *prefix = shader_glsl_get_prefix(shader->reg_maps.shader_version.type);
     struct wined3d_string_buffer *buffer = &priv->shader_buffer;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 2c741c8..f80467b 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -961,6 +961,16 @@ static HRESULT shader_record_shader_phase(struct wined3d_shader *shader,
     return WINED3D_OK;
 }
 
+static void wined3d_insert_interpolation_mode(DWORD *packed_interpolation_mode,
+        unsigned int register_idx, enum wined3d_shader_interpolation_mode mode)
+{
+    if (mode > WINED3DSIM_LINEAR_NOPERSPECTIVE_SAMPLE)
+        FIXME("Unexpected interpolation mode %#x.\n", mode);
+
+    wined3d_insert_bits(packed_interpolation_mode,
+            register_idx * WINED3D_PACKED_INTERPOLATION_BIT_COUNT, WINED3D_PACKED_INTERPOLATION_BIT_COUNT, mode);
+}
+
 /* Note that this does not count the loop register as an address register. */
 static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const struct wined3d_shader_frontend *fe,
         struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature *input_signature,
@@ -1151,13 +1161,13 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
         else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PS)
         {
             unsigned int reg_idx = ins.declaration.dst.reg.idx[0].offset;
-            if (reg_idx >= ARRAY_SIZE(shader->u.ps.interpolation_mode))
+            if (reg_idx >= MAX_REG_INPUT)
             {
                 ERR("Invalid register index %u.\n", reg_idx);
                 break;
             }
             if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
-                shader->u.ps.interpolation_mode[reg_idx] = ins.flags;
+                wined3d_insert_interpolation_mode(shader->u.ps.interpolation_mode, reg_idx, ins.flags);
             else
                 FIXME("Invalid instruction %#x for shader type %#x.\n",
                         ins.handler_idx, shader_version.type);
@@ -3400,13 +3410,13 @@ HRESULT CDECL wined3d_shader_set_local_constants_float(struct wined3d_shader *sh
     return WINED3D_OK;
 }
 
-static void init_interpolation_compile_args(enum wined3d_shader_interpolation_mode *interpolation_args,
+static void init_interpolation_compile_args(DWORD *interpolation_args,
         const struct wined3d_shader *pixel_shader, const struct wined3d_gl_info *gl_info)
 {
     if (!needs_interpolation_qualifiers_for_shader_outputs(gl_info)
             || !pixel_shader || pixel_shader->reg_maps.shader_version.major < 4)
     {
-        memset(interpolation_args, 0, MAX_REG_INPUT * sizeof(*interpolation_args));
+        memset(interpolation_args, 0, sizeof(pixel_shader->u.ps.interpolation_mode));
         return;
     }
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 26bda61..fad3fad 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -561,6 +561,9 @@ enum wined3d_shader_interpolation_mode
     WINED3DSIM_LINEAR_NOPERSPECTIVE_SAMPLE = 7,
 };
 
+#define WINED3D_PACKED_INTERPOLATION_SIZE 3
+#define WINED3D_PACKED_INTERPOLATION_BIT_COUNT 3
+
 enum wined3d_shader_global_flags
 {
     WINED3DSGF_REFACTORING_ALLOWED               = 0x1,
@@ -1363,7 +1366,7 @@ struct vs_compile_args
     BYTE padding : 1;
     WORD swizzle_map;   /* MAX_ATTRIBS, 16 */
     unsigned int next_shader_input_count;
-    enum wined3d_shader_interpolation_mode interpolation_mode[MAX_REG_INPUT];
+    DWORD interpolation_mode[WINED3D_PACKED_INTERPOLATION_SIZE];
 };
 
 struct ds_compile_args
@@ -1374,13 +1377,13 @@ struct ds_compile_args
     unsigned int next_shader_type : 3;
     unsigned int render_offscreen : 1;
     unsigned int padding : 12;
-    enum wined3d_shader_interpolation_mode interpolation_mode[MAX_REG_INPUT];
+    DWORD interpolation_mode[WINED3D_PACKED_INTERPOLATION_SIZE];
 };
 
 struct gs_compile_args
 {
     unsigned int output_count;
-    enum wined3d_shader_interpolation_mode interpolation_mode[MAX_REG_INPUT];
+    DWORD interpolation_mode[WINED3D_PACKED_INTERPOLATION_SIZE];
 };
 
 struct wined3d_context;
@@ -3916,7 +3919,7 @@ struct wined3d_pixel_shader
 
     BOOL force_early_depth_stencil;
     enum wined3d_shader_register_type depth_output;
-    enum wined3d_shader_interpolation_mode interpolation_mode[MAX_REG_INPUT];
+    DWORD interpolation_mode[WINED3D_PACKED_INTERPOLATION_SIZE];
 };
 
 struct wined3d_compute_shader
@@ -4293,6 +4296,44 @@ static inline BOOL needs_interpolation_qualifiers_for_shader_outputs(const struc
     return gl_info->glsl_version < MAKEDWORD_VERSION(4, 40);
 }
 
+static inline DWORD wined3d_extract_bits(const DWORD *bitstream,
+        unsigned int offset, unsigned int count)
+{
+    const unsigned int word_bit_count = sizeof(*bitstream) * CHAR_BIT;
+    const unsigned int idx = offset / word_bit_count;
+    const unsigned int shift = offset % word_bit_count;
+    DWORD mask = (1u << count) - 1;
+    DWORD ret;
+
+    ret = (bitstream[idx] >> shift) & mask;
+    if (shift + count > word_bit_count)
+    {
+        const unsigned int extracted_bit_count = word_bit_count - shift;
+        const unsigned int remaining_bit_count = count - extracted_bit_count;
+        mask = (1u << remaining_bit_count) - 1;
+        ret |= (bitstream[idx + 1] & mask) << extracted_bit_count;
+    }
+    return ret;
+}
+
+static inline void wined3d_insert_bits(DWORD *bitstream,
+        unsigned int offset, unsigned int count, DWORD bits)
+{
+    const unsigned int word_bit_count = sizeof(*bitstream) * CHAR_BIT;
+    const unsigned int idx = offset / word_bit_count;
+    const unsigned int shift = offset % word_bit_count;
+    DWORD mask = (1u << count) - 1;
+
+    bitstream[idx] |= (bits & mask) << shift;
+    if (shift + count > word_bit_count)
+    {
+        const unsigned int inserted_bit_count = word_bit_count - shift;
+        const unsigned int remaining_bit_count = count - inserted_bit_count;
+        mask = (1u << remaining_bit_count) - 1;
+        bitstream[idx + 1] |= (bits >> inserted_bit_count) & mask;
+    }
+}
+
 static inline struct wined3d_surface *context_get_rt_surface(const struct wined3d_context *context)
 {
     struct wined3d_texture *texture = context->current_rt.texture;




More information about the wine-cvs mailing list