[PATCH vkd3d 7/8] vkd3d-shader/glsl: Implement glsl_src_param_init_ext().

Atharva Nimbalkar atharvakn at gmail.com
Tue Aug 17 23:19:20 CDT 2021


Signed-off-by: Atharva Nimbalkar <atharvakn at gmail.com>
---
 libs/vkd3d-shader/glsl.c | 186 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 180 insertions(+), 6 deletions(-)

diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c
index 75b7bbc..32458f0 100644
--- a/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d-shader/glsl.c
@@ -161,6 +161,30 @@ static bool shader_is_scalar(const struct vkd3d_shader_register *reg)
     }
 }
 
+static void shader_glsl_print_swizzle(uint32_t swizzle, bool fixup, uint32_t mask,
+        struct vkd3d_string_buffer *str)
+{
+    /* For registers of type VKD3DDECLTYPE_D3DCOLOR, data is stored as "bgra",
+     * but addressed as "rgba". To fix this we need to swap the register's x
+     * and z components. */
+    const char *swizzle_chars = fixup ? "zyxw" : "xyzw";
+    unsigned int i;
+
+    vkd3d_string_buffer_printf(str, ".");
+    for (i = 0; i < 4; ++i)
+    {
+        if (mask & (VKD3DSP_WRITEMASK_0 << i))
+            vkd3d_string_buffer_printf(str, "%c", swizzle_chars[vkd3d_swizzle_get_component(swizzle, i)]);
+    }
+}
+
+static void shader_glsl_get_swizzle(const struct vkd3d_shader_src_param *param,
+        bool fixup, uint32_t mask, struct vkd3d_string_buffer *swizzle_str)
+{
+    if (!shader_is_scalar(&param->reg))
+        shader_glsl_print_swizzle(param->swizzle, fixup, mask, swizzle_str);
+}
+
 static void shader_glsl_print_write_mask(uint32_t write_mask, struct vkd3d_string_buffer *str)
 {
     vkd3d_string_buffer_printf(str, ".");
@@ -204,6 +228,120 @@ static void shader_glsl_get_register_name(struct vkd3d_glsl_generator *gen,
             "Internal compiler error: Unhandled register type %#x.", reg->type);
 }
 
+static void shader_glsl_sprintf_cast(struct vkd3d_glsl_generator *gen,
+        struct vkd3d_string_buffer *dst_param, const char *src_param,
+        enum vkd3d_data_type dst_data_type, enum vkd3d_data_type src_data_type, unsigned int size)
+{
+    if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM)
+        dst_data_type = VKD3D_DATA_FLOAT;
+    if (src_data_type == VKD3D_DATA_UNORM || src_data_type == VKD3D_DATA_SNORM)
+        src_data_type = VKD3D_DATA_FLOAT;
+
+    if (dst_data_type == src_data_type)
+    {
+        vkd3d_string_buffer_printf(dst_param, "%s", src_param);
+        return;
+    }
+
+    if (src_data_type == VKD3D_DATA_FLOAT)
+    {
+        switch (dst_data_type)
+        {
+            case VKD3D_DATA_INT:
+                vkd3d_string_buffer_printf(dst_param, "floatBitsToInt(%s)", src_param);
+                return;
+            case VKD3D_DATA_RESOURCE:
+            case VKD3D_DATA_SAMPLER:
+            case VKD3D_DATA_UINT:
+                vkd3d_string_buffer_printf(dst_param, "floatBitsToUint(%s)", src_param);
+                return;
+            default:
+                break;
+        }
+    }
+
+    if (src_data_type == VKD3D_DATA_UINT && dst_data_type == VKD3D_DATA_FLOAT)
+    {
+        vkd3d_string_buffer_printf(dst_param, "uintBitsToFloat(%s)", src_param);
+        return;
+    }
+
+    if (src_data_type == VKD3D_DATA_INT)
+    {
+        switch (dst_data_type)
+        {
+            case VKD3D_DATA_FLOAT:
+                vkd3d_string_buffer_printf(dst_param, "intBitsToFloat(%s)", src_param);
+                return;
+            case VKD3D_DATA_UINT:
+                if (size == 1)
+                    vkd3d_string_buffer_printf(dst_param, "uint(%s)", src_param);
+                else
+                    vkd3d_string_buffer_printf(dst_param, "uvec%u(%s)", size, src_param);
+                return;
+            default:
+                break;
+        }
+    }
+
+    vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+        "Unhandled cast from %#x to %#x.\n", src_data_type, dst_data_type);
+    vkd3d_string_buffer_printf(dst_param, "%s", src_param);
+}
+
+/* Generate a GLSL parameter that does the input modifier computation and return the input register/mask to use */
+static void shader_glsl_gen_modifier(struct vkd3d_glsl_generator *gen,
+        enum vkd3d_shader_src_modifier src_modifier,
+        const char *in_reg, const struct vkd3d_string_buffer *in_regswizzle,
+        struct vkd3d_string_buffer *out_str)
+{
+    switch (src_modifier)
+    {
+        case VKD3DSPSM_DZ: /* Need to handle this in the instructions itself (texld & texcrd). */
+        case VKD3DSPSM_DW:
+        case VKD3DSPSM_NONE:
+            vkd3d_string_buffer_printf(out_str, "%s%s", in_reg, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_NEG:
+            vkd3d_string_buffer_printf(out_str, "-%s%s", in_reg, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_NOT:
+            vkd3d_string_buffer_printf(out_str, "!%s%s", in_reg, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_BIAS:
+            vkd3d_string_buffer_printf(out_str, "(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle->buffer, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_BIASNEG:
+            vkd3d_string_buffer_printf(out_str, "-(%s%s - vec4(0.5)%s)", in_reg, in_regswizzle->buffer, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_SIGN:
+            vkd3d_string_buffer_printf(out_str, "(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_SIGNNEG:
+            vkd3d_string_buffer_printf(out_str, "-(2.0 * (%s%s - 0.5))", in_reg, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_COMP:
+            vkd3d_string_buffer_printf(out_str, "(1.0 - %s%s)", in_reg, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_X2:
+            vkd3d_string_buffer_printf(out_str, "(2.0 * %s%s)", in_reg, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_X2NEG:
+            vkd3d_string_buffer_printf(out_str, "-(2.0 * %s%s)", in_reg, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_ABS:
+            vkd3d_string_buffer_printf(out_str, "abs(%s%s)", in_reg, in_regswizzle->buffer);
+            break;
+        case VKD3DSPSM_ABSNEG:
+            vkd3d_string_buffer_printf(out_str, "-abs(%s%s)", in_reg, in_regswizzle->buffer);
+            break;
+        default:
+            vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+                "Unhandled modifier %#x\n", src_modifier);
+            vkd3d_string_buffer_printf(out_str, "%s%s", in_reg, in_regswizzle->buffer);
+    }
+}
+
 /* From a given parameter token, generate the corresponding GLSL string.
  * Also, return the actual register name and swizzle in case the
  * caller needs this information as well. */
@@ -211,14 +349,50 @@ static void glsl_src_param_init_ext(struct vkd3d_glsl_generator *gen,
         const struct vkd3d_shader_src_param *vkd3d_src, uint32_t mask, struct glsl_src_param *glsl_src,
         enum vkd3d_data_type data_type)
 {
-    /*
-     * TODO: Add implementation
-     * Sets an error state as of now.
-     */
+    struct vkd3d_string_buffer *param_str = vkd3d_string_buffer_get(&gen->string_buffers);
+    struct vkd3d_string_buffer *reg_name = vkd3d_string_buffer_get(&gen->string_buffers);
+    struct vkd3d_string_buffer *swizzle_str = vkd3d_string_buffer_get(&gen->string_buffers);
+    enum vkd3d_data_type param_data_type;
+    bool is_color = false;
+    unsigned int size;
 
     glsl_src->param_str = vkd3d_string_buffer_get(&gen->string_buffers);
-    vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
-            "Internal compiler error: Unhandled parameter token.");
+    shader_glsl_get_register_name(gen, &vkd3d_src->reg, data_type, reg_name, &is_color);
+    shader_glsl_get_swizzle(vkd3d_src, false, mask, swizzle_str);
+
+    switch (vkd3d_src->reg.type)
+    {
+        case VKD3DSPR_IMMCONST:
+            param_data_type = data_type;
+            size = vkd3d_src->reg.immconst_type == VKD3D_IMMCONST_SCALAR ? 1 : 4;
+            break;
+        case VKD3DSPR_FORKINSTID:
+        case VKD3DSPR_GSINSTID:
+        case VKD3DSPR_JOININSTID:
+        case VKD3DSPR_LOCALTHREADINDEX:
+        case VKD3DSPR_OUTPOINTID:
+        case VKD3DSPR_PRIMID:
+            param_data_type = VKD3D_DATA_INT;
+            size = 1;
+            break;
+        case VKD3DSPR_LOCALTHREADID:
+        case VKD3DSPR_THREADGROUPID:
+        case VKD3DSPR_THREADID:
+            param_data_type = VKD3D_DATA_INT;
+            size = 3;
+            break;
+        default:
+            param_data_type = VKD3D_DATA_FLOAT;
+            size = 4;
+            break;
+    }
+
+    shader_glsl_sprintf_cast(gen, param_str, reg_name->buffer, data_type, param_data_type, size);
+    shader_glsl_gen_modifier(gen, vkd3d_src->modifiers, param_str->buffer, swizzle_str, glsl_src->param_str);
+
+    vkd3d_string_buffer_release(&gen->string_buffers, swizzle_str);
+    vkd3d_string_buffer_release(&gen->string_buffers, reg_name);
+    vkd3d_string_buffer_release(&gen->string_buffers, param_str);
 }
 
 static void glsl_src_param_init(struct vkd3d_glsl_generator *gen,
-- 
2.32.0




More information about the wine-devel mailing list