[PATCH vkd3d 6/6] vkd3d-shader: Allocate varying registers.

Matteo Bruni matteo.mystral at gmail.com
Mon Apr 26 07:50:31 CDT 2021


On Wed, Apr 21, 2021 at 6:30 AM Zebediah Figura <zfigura at codeweavers.com> wrote:
>
> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
> ---
>  include/vkd3d_d3d9types.h        | 15 +++++
>  libs/vkd3d-shader/hlsl_codegen.c | 99 ++++++++++++++++++++++++++++++++
>  2 files changed, 114 insertions(+)
>
> diff --git a/include/vkd3d_d3d9types.h b/include/vkd3d_d3d9types.h
> index ba7dcbfb..1f886443 100644
> --- a/include/vkd3d_d3d9types.h
> +++ b/include/vkd3d_d3d9types.h
> @@ -164,5 +164,20 @@ typedef enum _D3DSHADER_PARAM_REGISTER_TYPE
>      D3DSPR_FORCE_DWORD  = 0x7fffffff,
>  } D3DSHADER_PARAM_REGISTER_TYPE;
>
> +typedef enum _D3DSHADER_MISCTYPE_OFFSETS
> +{
> +    D3DSMO_POSITION  = 0x0,
> +    D3DSMO_FACE      = 0x1,
> +} D3DSHADER_MISCTYPE_OFFSETS;
> +
> +typedef enum _D3DVS_RASTOUT_OFFSETS
> +{
> +    D3DSRO_POSITION     = 0x0,
> +    D3DSRO_FOG          = 0x1,
> +    D3DSRO_POINT_SIZE   = 0x2,
> +
> +    D3DSRO_FORCE_DWORD  = 0x7fffffff,
> +} D3DVS_RASTOUT_OFFSETS;
> +
>  #endif  /* _d3d9TYPES_H_ */
>  #endif  /* __VKD3D_D3D9TYPES_H */
> diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
> index b1faa8a0..ab291545 100644
> --- a/libs/vkd3d-shader/hlsl_codegen.c
> +++ b/libs/vkd3d-shader/hlsl_codegen.c
> @@ -967,6 +967,104 @@ static void allocate_temp_registers(struct hlsl_ir_function_decl *entry_func)
>      allocate_temp_registers_recurse(entry_func->body, &liveness);
>  }
>
> +static bool sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output,
> +        D3DSHADER_PARAM_REGISTER_TYPE *type, unsigned int *reg)
> +{
> +    unsigned int i;
> +
> +    static const struct
> +    {
> +        const char *semantic;
> +        bool output;
> +        enum vkd3d_shader_type shader_type;
> +        unsigned int major_version;
> +        D3DSHADER_PARAM_REGISTER_TYPE type;
> +        DWORD offset;
> +    }
> +    register_table[] =
> +    {
> +        {"color",       true,  VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_COLOROUT},
> +        {"depth",       true,  VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_DEPTHOUT},
> +        {"sv_depth",    true,  VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_DEPTHOUT},
> +        {"sv_target",   true,  VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_COLOROUT},
> +        {"color",       false, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_INPUT},
> +        {"texcoord",    false, VKD3D_SHADER_TYPE_PIXEL, 2, D3DSPR_TEXTURE},
> +
> +        {"color",       true,  VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_COLOROUT},
> +        {"depth",       true,  VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_DEPTHOUT},
> +        {"sv_depth",    true,  VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_DEPTHOUT},
> +        {"sv_target",   true,  VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_COLOROUT},
> +        {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_MISCTYPE,    D3DSMO_POSITION},
> +        {"vface",       false, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_MISCTYPE,    D3DSMO_FACE},
> +        {"vpos",        false, VKD3D_SHADER_TYPE_PIXEL, 3, D3DSPR_MISCTYPE,    D3DSMO_POSITION},
> +
> +        {"color",       true,  VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_ATTROUT},
> +        {"fog",         true,  VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT,     D3DSRO_FOG},
> +        {"position",    true,  VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT,     D3DSRO_POSITION},
> +        {"psize",       true,  VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT,     D3DSRO_POINT_SIZE},
> +        {"sv_position", true,  VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_RASTOUT,     D3DSRO_POSITION},
> +        {"texcoord",    true,  VKD3D_SHADER_TYPE_VERTEX, 1, D3DSPR_TEXCRDOUT},
> +
> +        {"color",       true,  VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_ATTROUT},
> +        {"fog",         true,  VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT,     D3DSRO_FOG},
> +        {"position",    true,  VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT,     D3DSRO_POSITION},
> +        {"psize",       true,  VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT,     D3DSRO_POINT_SIZE},
> +        {"sv_position", true,  VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_RASTOUT,     D3DSRO_POSITION},
> +        {"texcoord",    true,  VKD3D_SHADER_TYPE_VERTEX, 2, D3DSPR_TEXCRDOUT},
> +    };
> +
> +    for (i = 0; i < ARRAY_SIZE(register_table); ++i)
> +    {
> +        if (!ascii_strcasecmp(semantic->name, register_table[i].semantic)
> +                && output == register_table[i].output
> +                && ctx->profile->type == register_table[i].shader_type
> +                && ctx->profile->major_version == register_table[i].major_version)
> +        {
> +            *type = register_table[i].type;
> +            if (register_table[i].type == D3DSPR_MISCTYPE || register_table[i].type == D3DSPR_RASTOUT)
> +                *reg = register_table[i].offset;
> +            else
> +                *reg = semantic->index;
> +            return true;
> +        }
> +    }
> +
> +    return false;
> +}
> +
> +static void allocate_varying_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, unsigned int *counter, bool output)
> +{
> +    assert(var->semantic.name);
> +
> +    if (ctx->profile->major_version < 4)
> +    {
> +        D3DSHADER_PARAM_REGISTER_TYPE type;
> +        unsigned int reg;
> +
> +        if (!sm1_register_from_semantic(ctx, &var->semantic, output, &type, &reg))
> +        {
> +            var->reg.allocated = true;
> +            var->reg.id = (*counter)++;
> +            var->reg.writemask = (1 << var->data_type->dimx) - 1;
> +            TRACE("Allocated %s to %s.\n", var->name, debug_register(output ? 'o' : 'v', var->reg, var->data_type));
> +        }
> +    }
> +}
> +
> +static void allocate_varying_registers(struct hlsl_ctx *ctx)
> +{
> +    unsigned int input_counter = 0, output_counter = 0;
> +    struct hlsl_ir_var *var;
> +
> +    LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
> +    {
> +        if (var->is_input_varying && var->last_read)
> +            allocate_varying_register(ctx, var, &input_counter, false);
> +        if (var->is_output_varying && var->first_write)
> +            allocate_varying_register(ctx, var, &output_counter, true);
> +    }
> +}
> +
>  struct bytecode_buffer
>  {
>      uint32_t *data;
> @@ -1377,6 +1475,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
>      allocate_temp_registers(entry_func);
>      if (ctx->profile->major_version < 4)
>          constant_defs = allocate_const_registers(ctx, entry_func);
> +    allocate_varying_registers(ctx);
>
>      if (ctx->failed)
>          return VKD3D_ERROR_INVALID_SHADER;

Nothing new as of this patch but I just realized it now: the naming
here isn't entirely correct. AFAIK varying is an old name that was
used for the variables that are traditionally output by the vertex
shader and end into the fixed function rasterizer, and the
interpolated variables that constitute the output of the rasterizer
and the input of the pixel shader. So a couple points:
- calling "varying" a VS input or a PS output isn't entirely proper
- things become even more muddied with the additional geometry shader
stages in SM4+; technically only the final geometry stage would
produce a varying
So calling all of the shader inputs and outputs "varyings" is maybe
not ideal. Not that I necessarily have a great replacement. I guess
some of the usual modern terms for this would be input / output,
interface.



More information about the wine-devel mailing list