Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- include/vkd3d_d3d9types.h | 32 +++++++++ libs/vkd3d-shader/hlsl_codegen.c | 114 ++++++++++++++++++++++++++++++- 2 files changed, 145 insertions(+), 1 deletion(-)
diff --git a/include/vkd3d_d3d9types.h b/include/vkd3d_d3d9types.h index 1f886443..c204202e 100644 --- a/include/vkd3d_d3d9types.h +++ b/include/vkd3d_d3d9types.h @@ -29,6 +29,10 @@
#define D3DSI_INSTLENGTH_SHIFT 24
+#define D3DSP_DCL_USAGE_SHIFT 0 +#define D3DSP_DCL_USAGEINDEX_SHIFT 16 +#define D3DSP_DSTMOD_SHIFT 20 + #define D3DSP_REGTYPE_SHIFT 28 #define D3DSP_REGTYPE_SHIFT2 8 #define D3DSP_REGTYPE_MASK (0x7 << D3DSP_REGTYPE_SHIFT) @@ -43,6 +47,24 @@ #define D3DPS_VERSION(major, minor) (0xffff0000 | ((major) << 8) | (minor)) #define D3DVS_VERSION(major, minor) (0xfffe0000 | ((major) << 8) | (minor))
+typedef enum _D3DDECLUSAGE +{ + D3DDECLUSAGE_POSITION = 0x0, + D3DDECLUSAGE_BLENDWEIGHT = 0x1, + D3DDECLUSAGE_BLENDINDICES = 0x2, + D3DDECLUSAGE_NORMAL = 0x3, + D3DDECLUSAGE_PSIZE = 0x4, + D3DDECLUSAGE_TEXCOORD = 0x5, + D3DDECLUSAGE_TANGENT = 0x6, + D3DDECLUSAGE_BINORMAL = 0x7, + D3DDECLUSAGE_TESSFACTOR = 0x8, + D3DDECLUSAGE_POSITIONT = 0x9, + D3DDECLUSAGE_COLOR = 0xa, + D3DDECLUSAGE_FOG = 0xb, + D3DDECLUSAGE_DEPTH = 0xc, + D3DDECLUSAGE_SAMPLE = 0xd, +} D3DDECLUSAGE; + typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE { D3DSIO_NOP = 0x00, @@ -136,6 +158,16 @@ typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE D3DSIO_FORCE_DWORD = 0x7fffffff, } D3DSHADER_INSTRUCTION_OPCODE_TYPE;
+typedef enum _D3DSHADER_PARAM_DSTMOD_TYPE +{ + D3DSPDM_NONE = 0 << D3DSP_DSTMOD_SHIFT, + D3DSPDM_SATURATE = 1 << D3DSP_DSTMOD_SHIFT, + D3DSPDM_PARTIALPRECISION = 2 << D3DSP_DSTMOD_SHIFT, + D3DSPDM_MSAMPCENTROID = 4 << D3DSP_DSTMOD_SHIFT, + + D3DSPDM_FORCE_DWORD = 0x7fffffff, +} D3DSHADER_PARAM_DSTMOD_TYPE; + typedef enum _D3DSHADER_PARAM_REGISTER_TYPE { D3DSPR_TEMP = 0x00, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 9f2c278c..d4995110 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1013,6 +1013,49 @@ static bool sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_s return false; }
+static bool sm1_usage_from_semantic(const struct hlsl_semantic *semantic, D3DDECLUSAGE *usage, uint32_t *usage_idx) +{ + static const struct + { + const char *name; + D3DDECLUSAGE usage; + } + semantics[] = + { + {"binormal", D3DDECLUSAGE_BINORMAL}, + {"blendindices", D3DDECLUSAGE_BLENDINDICES}, + {"blendweight", D3DDECLUSAGE_BLENDWEIGHT}, + {"color", D3DDECLUSAGE_COLOR}, + {"depth", D3DDECLUSAGE_DEPTH}, + {"fog", D3DDECLUSAGE_FOG}, + {"normal", D3DDECLUSAGE_NORMAL}, + {"position", D3DDECLUSAGE_POSITION}, + {"positiont", D3DDECLUSAGE_POSITIONT}, + {"psize", D3DDECLUSAGE_PSIZE}, + {"sample", D3DDECLUSAGE_SAMPLE}, + {"sv_depth", D3DDECLUSAGE_DEPTH}, + {"sv_position", D3DDECLUSAGE_POSITION}, + {"sv_target", D3DDECLUSAGE_COLOR}, + {"tangent", D3DDECLUSAGE_TANGENT}, + {"tessfactor", D3DDECLUSAGE_TESSFACTOR}, + {"texcoord", D3DDECLUSAGE_TEXCOORD}, + }; + + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(semantics); ++i) + { + if (!ascii_strcasecmp(semantic->name, semantics[i].name)) + { + *usage = semantics[i].usage; + *usage_idx = semantic->index; + return true; + } + } + + return false; +} + static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, unsigned int *counter, bool output) { assert(var->semantic.name); @@ -1020,7 +1063,15 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var if (ctx->profile->major_version < 4) { D3DSHADER_PARAM_REGISTER_TYPE type; - unsigned int reg; + uint32_t reg, usage_idx; + D3DDECLUSAGE usage; + + if (!sm1_usage_from_semantic(&var->semantic, &usage, &usage_idx)) + { + hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + "Invalid semantic '%s'.", var->semantic.name); + return; + }
if (!sm1_register_from_semantic(ctx, &var->semantic, output, &type, ®)) { @@ -1371,6 +1422,12 @@ static uint32_t sm1_encode_register_type(D3DSHADER_PARAM_REGISTER_TYPE type) | ((type << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2); }
+static uint32_t sm1_encode_dst(D3DSHADER_PARAM_REGISTER_TYPE type, + D3DSHADER_PARAM_DSTMOD_TYPE modifier, unsigned int writemask, unsigned int reg) +{ + return (1u << 31) | sm1_encode_register_type(type) | modifier | (writemask << 16) | reg; +} + static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer) { unsigned int i, x; @@ -1393,6 +1450,60 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct bytecode_buffer } }
+static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, + const struct hlsl_ir_var *var, bool output) +{ + D3DSHADER_PARAM_REGISTER_TYPE type; + uint32_t token, usage_idx, reg_idx; + D3DDECLUSAGE usage; + bool ret; + + if (sm1_register_from_semantic(ctx, &var->semantic, output, &type, ®_idx)) + { + usage = 0; + usage_idx = 0; + } + else + { + ret = sm1_usage_from_semantic(&var->semantic, &usage, &usage_idx); + assert(ret); + type = output ? D3DSPR_OUTPUT : D3DSPR_INPUT; + reg_idx = var->reg.id; + } + + token = D3DSIO_DCL; + if (ctx->profile->major_version > 1) + token |= 2 << D3DSI_INSTLENGTH_SHIFT; + put_dword(buffer, token); + + token = (1u << 31); + token |= usage << D3DSP_DCL_USAGE_SHIFT; + token |= usage_idx << D3DSP_DCL_USAGEINDEX_SHIFT; + put_dword(buffer, token); + put_dword(buffer, sm1_encode_dst(type, D3DSPDM_NONE, (1 << var->data_type->dimx) - 1, reg_idx)); +} + +static void write_sm1_semantic_dcls(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer) +{ + bool write_in = false, write_out = false; + struct hlsl_ir_var *var; + + if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) + write_in = true; + else if (ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX && ctx->profile->major_version == 3) + write_in = write_out = true; + else if (ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX && ctx->profile->major_version < 3) + write_in = true; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (write_in && var->is_input_semantic) + write_sm1_semantic_dcl(ctx, buffer, var, false); + if (write_out && var->is_output_semantic) + write_sm1_semantic_dcl(ctx, buffer, var, true); + } +} + static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) { @@ -1404,6 +1515,7 @@ static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl * write_sm1_uniforms(ctx, &buffer, entry_func);
write_sm1_constant_defs(ctx, &buffer); + write_sm1_semantic_dcls(ctx, &buffer);
put_dword(&buffer, D3DSIO_END);