[PATCH 1/2] wined3d: Implement SM5 bfi opcode in glsl.
Józef Kucia
joseph.kucia at gmail.com
Mon Jul 18 07:17:37 CDT 2016
On Fri, Jul 15, 2016 at 1:53 PM, Guillaume Charifi
<guillaume.charifi at sfr.fr> wrote:
> Signed-off-by: Guillaume Charifi <guillaume.charifi at sfr.fr>
> ---
> dlls/wined3d/glsl_shader.c | 72 +++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 71 insertions(+), 1 deletion(-)
>
> diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
> index d8edfdc..b0d3a91 100644
> --- a/dlls/wined3d/glsl_shader.c
> +++ b/dlls/wined3d/glsl_shader.c
> @@ -4380,6 +4380,76 @@ static void shader_glsl_f32tof16(const struct wined3d_shader_instruction *ins)
> #undef NB_COMPS
> }
This patch requires 124405 so it should be in the same series.
>
> +
> +static void shader_glsl_bitfield_op(const struct wined3d_shader_instruction *ins)
> +{
> +#define NB_COMPS 4
> + const DWORD write_masks[NB_COMPS] = {
> + WINED3DSP_WRITEMASK_0,
> + WINED3DSP_WRITEMASK_1,
> + WINED3DSP_WRITEMASK_2,
> + WINED3DSP_WRITEMASK_3,
> + };
You shouldn't need this array. You can assume that
WINED3DSP_WRITE_MASK_i = WINED3DSP_WRITE_MASK_0 << i.
> + const char dst_masks[NB_COMPS] = { 'x', 'y', 'z', 'w' };
> + const char *prefix;
> + const char *suffix;
> + int nb_params;
For consistency, this should be named "param_count" and should be unsigned int.
> + struct glsl_src_param src_param;
> + DWORD write_mask;
> + char dst_mask[6];
> + char *dst_mask_ptr = dst_mask;
> +
> + switch(ins->handler_idx)
> + {
> + case WINED3DSIH_BFI:
> + prefix = "bitfieldInsert(";
> + suffix = ")";
> + nb_params = 4;
> + break;
> +
> + default:
> + prefix = "<unhandled opcode>";
> + suffix = "";
> + nb_params = 0;
> + FIXME("Can't handle opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
> + }
> +
> + write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
> +
> + *dst_mask_ptr++ = '.';
> + shader_addline(ins->ctx->buffer, "uvec4(\n");
> +
> + for (int i = 0; i < NB_COMPS; i++)
This requires C99.
> + {
> + if (write_mask & write_masks[i])
> + {
> + shader_addline(ins->ctx->buffer, "%s", prefix);
> + for(int j = nb_params - 1; j >= 0; j--)
> + {
> + shader_glsl_add_src_param(ins, &ins->src[j], write_masks[i], &src_param);
> + if(j <= 1)
> + shader_addline(ins->ctx->buffer, "int(%s)", src_param.param_str);
You shouldn't need this cast. It's better to adjust the parameter
types and let shader_glsl_add_src_param() handle this.
> + else
> + shader_addline(ins->ctx->buffer, "%s", src_param.param_str);
> +
> + if(j)
> + shader_addline(ins->ctx->buffer, ", ");
> + }
> + shader_addline(ins->ctx->buffer, "%s", suffix);
> + *dst_mask_ptr++ = dst_masks[i];
> + } else
> + shader_addline(ins->ctx->buffer, "0");
> +
> + if(i != NB_COMPS - 1)
> + shader_addline(ins->ctx->buffer, ",");
> + shader_addline(ins->ctx->buffer, "\n");
> + }
> +
> + *dst_mask_ptr++ = '\0';
You shouldn't need to build dst_mask manually.
> + shader_addline(ins->ctx->buffer, ")%s);\n", dst_mask);
> +#undef NB_COMPS
I don't like this duplicated enums.
Generally, this implementation seems overly complicated. You should be
able to do something similar to:
for (i = 0; i < 4; ++i)
{
write_mask = WINED3DSP_WRITEMASK_0 << i;
dst.write_mask = ins->dst[0].write_mask & write_mask;
if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins,
&dst, dst.reg.data_type)))
continue;
shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &bits);
shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &offset);
shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &insert);
shader_glsl_add_src_param(ins, &ins->src[3], write_mask, &base);
shader_addline(ins->ctx->buffer, "bitfieldInsert(%s, %s, %s, %s));\n",
base.param_str, insert.param_str, offset.param_str, bits.param_str);
}
More information about the wine-devel
mailing list