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

Zebediah Figura (she/her) zfigura at codeweavers.com
Mon Apr 26 11:08:46 CDT 2021


On 4/26/21 7:50 AM, Matteo Bruni wrote:
> 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.
> 

Doesn't "interface" also encompass uniforms?

"semantic" is another potential option...



More information about the wine-devel mailing list