Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 160 ++++++++--------------- libs/vkd3d-shader/vkd3d_shader_main.c | 43 ++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 12 ++ 3 files changed, 111 insertions(+), 104 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 27bbd9b6..c9ada5bc 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1325,57 +1325,6 @@ static struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const return ret; }
-struct bytecode_buffer -{ - struct hlsl_ctx *ctx; - char *data; - size_t size, capacity; - int status; -}; - -static size_t put_bytes(struct bytecode_buffer *buffer, const void *bytes, size_t size, size_t alignment) -{ - size_t prev_size = buffer->size; - size_t offset = align(prev_size, alignment); - - if (buffer->status) - return offset; - - if (!hlsl_array_reserve(buffer->ctx, (void **)&buffer->data, &buffer->capacity, offset + size, 1)) - { - buffer->status = VKD3D_ERROR_OUT_OF_MEMORY; - return offset; - } - memset(buffer->data + prev_size, 0xab, offset - prev_size); - memcpy(buffer->data + offset, bytes, size); - buffer->size = offset + size; - return offset; -} - -static size_t put_dword(struct bytecode_buffer *buffer, uint32_t value) -{ - return put_bytes(buffer, &value, sizeof(value), sizeof(value)); -} - -static size_t put_float(struct bytecode_buffer *buffer, float value) -{ - return put_bytes(buffer, &value, sizeof(value), sizeof(value)); -} - -static void set_dword(struct bytecode_buffer *buffer, size_t offset, uint32_t value) -{ - if (buffer->status) - return; - - assert(offset + sizeof(value) <= buffer->size); - memcpy(buffer->data + offset, &value, sizeof(value)); -} - -static size_t put_string(struct bytecode_buffer *buffer, const char *string) -{ - return put_bytes(buffer, string, strlen(string) + 1, 1); -} - static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, unsigned int minor) { if (type == VKD3D_SHADER_TYPE_VERTEX) @@ -1486,7 +1435,7 @@ static unsigned int get_array_size(const struct hlsl_type *type) return 1; }
-static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *type, unsigned int ctab_start) +static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type, unsigned int ctab_start) { const struct hlsl_type *array_type = get_array_type(type); unsigned int array_size = get_array_size(type); @@ -1501,7 +1450,7 @@ static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *typ { LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) { - field->name_bytecode_offset = put_string(buffer, field->name); + field->name_bytecode_offset = vkd3d_put_string(buffer, field->name); write_sm1_type(buffer, field->type, ctab_start); }
@@ -1509,16 +1458,16 @@ static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *typ
LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) { - put_dword(buffer, field->name_bytecode_offset - ctab_start); - put_dword(buffer, field->type->bytecode_offset - ctab_start); + vkd3d_put_u32(buffer, field->name_bytecode_offset - ctab_start); + vkd3d_put_u32(buffer, field->type->bytecode_offset - ctab_start); ++field_count; } }
- type->bytecode_offset = put_dword(buffer, sm1_class(type) | (sm1_base_type(type) << 16)); - put_dword(buffer, type->dimy | (type->dimx << 16)); - put_dword(buffer, array_size | (field_count << 16)); - put_dword(buffer, fields_offset); + type->bytecode_offset = vkd3d_put_u32(buffer, sm1_class(type) | (sm1_base_type(type) << 16)); + vkd3d_put_u32(buffer, type->dimy | (type->dimx << 16)); + vkd3d_put_u32(buffer, array_size | (field_count << 16)); + vkd3d_put_u32(buffer, fields_offset); }
static void sm1_sort_extern(struct list *sorted, struct hlsl_ir_var *to_sort) @@ -1549,7 +1498,7 @@ static void sm1_sort_externs(struct hlsl_ctx *ctx) list_move_tail(&ctx->extern_vars, &sorted); }
-static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, +static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_ir_function_decl *entry_func) { size_t ctab_start, vars_start, size_offset, creator_offset, offset; @@ -1581,16 +1530,16 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
sm1_sort_externs(ctx);
- size_offset = put_dword(buffer, 0); - put_dword(buffer, MAKEFOURCC('C','T','A','B')); + size_offset = vkd3d_put_u32(buffer, 0); + vkd3d_put_u32(buffer, MAKEFOURCC('C','T','A','B'));
- ctab_start = put_dword(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); - creator_offset = put_dword(buffer, 0); - put_dword(buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version)); - put_dword(buffer, uniform_count); - put_dword(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* offset of constants */ - put_dword(buffer, 0); /* FIXME: flags */ - put_dword(buffer, 0); /* FIXME: target string */ + ctab_start = vkd3d_put_u32(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); + creator_offset = vkd3d_put_u32(buffer, 0); + vkd3d_put_u32(buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version)); + vkd3d_put_u32(buffer, uniform_count); + vkd3d_put_u32(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* offset of constants */ + vkd3d_put_u32(buffer, 0); /* FIXME: flags */ + vkd3d_put_u32(buffer, 0); /* FIXME: target string */
vars_start = buffer->size;
@@ -1598,11 +1547,11 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf { if (!var->semantic.name && var->reg.allocated) { - put_dword(buffer, 0); /* name */ - put_dword(buffer, D3DXRS_FLOAT4 | (var->reg.id << 16)); - put_dword(buffer, var->data_type->reg_size / 4); - put_dword(buffer, 0); /* type */ - put_dword(buffer, 0); /* FIXME: default value */ + vkd3d_put_u32(buffer, 0); /* name */ + vkd3d_put_u32(buffer, D3DXRS_FLOAT4 | (var->reg.id << 16)); + vkd3d_put_u32(buffer, var->data_type->reg_size / 4); + vkd3d_put_u32(buffer, 0); /* type */ + vkd3d_put_u32(buffer, 0); /* FIXME: default value */ } }
@@ -1614,19 +1563,19 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf { size_t var_offset = vars_start + (uniform_count * 5 * sizeof(uint32_t));
- set_dword(buffer, var_offset, buffer->size - ctab_start); - put_string(buffer, var->name); + vkd3d_set_u32(buffer, var_offset, buffer->size - ctab_start); + vkd3d_put_string(buffer, var->name);
write_sm1_type(buffer, var->data_type, ctab_start); - set_dword(buffer, var_offset + 3 * sizeof(uint32_t), var->data_type->bytecode_offset - ctab_start); + vkd3d_set_u32(buffer, var_offset + 3 * sizeof(uint32_t), var->data_type->bytecode_offset - ctab_start); ++uniform_count; } }
- offset = put_string(buffer, vkd3d_shader_get_version(NULL, NULL)); - set_dword(buffer, creator_offset, offset - ctab_start); + offset = vkd3d_put_string(buffer, vkd3d_shader_get_version(NULL, NULL)); + vkd3d_set_u32(buffer, creator_offset, offset - ctab_start);
- set_dword(buffer, size_offset, D3DSIO_COMMENT | (((buffer->size - (ctab_start - 1)) / sizeof(uint32_t)) << 16)); + vkd3d_set_u32(buffer, size_offset, D3DSIO_COMMENT | (((buffer->size - (ctab_start - 1)) / sizeof(uint32_t)) << 16)); }
static uint32_t sm1_encode_register_type(D3DSHADER_PARAM_REGISTER_TYPE type) @@ -1659,21 +1608,21 @@ struct sm1_instruction unsigned int has_dst; };
-static void write_sm1_dst_register(struct bytecode_buffer *buffer, const struct sm1_dst_register *reg) +static void write_sm1_dst_register(struct vkd3d_bytecode_buffer *buffer, const struct sm1_dst_register *reg) { assert(reg->writemask); - put_dword(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (reg->writemask << 16) | reg->reg); + vkd3d_put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (reg->writemask << 16) | reg->reg); }
-static void write_sm1_src_register(struct bytecode_buffer *buffer, +static void write_sm1_src_register(struct vkd3d_bytecode_buffer *buffer, const struct sm1_src_register *reg, unsigned int dst_writemask) { unsigned int swizzle = map_swizzle(reg->swizzle, dst_writemask);
- put_dword(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (swizzle << 16) | reg->reg); + vkd3d_put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (swizzle << 16) | reg->reg); }
-static void write_sm1_instruction(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, +static void write_sm1_instruction(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct sm1_instruction *instr) { uint32_t token = instr->opcode; @@ -1681,7 +1630,7 @@ static void write_sm1_instruction(struct hlsl_ctx *ctx, struct bytecode_buffer *
if (ctx->profile->major_version > 1) token |= (instr->has_dst + instr->src_count) << D3DSI_INSTLENGTH_SHIFT; - put_dword(buffer, token); + vkd3d_put_u32(buffer, token);
if (instr->has_dst) write_sm1_dst_register(buffer, &instr->dst); @@ -1690,7 +1639,7 @@ static void write_sm1_instruction(struct hlsl_ctx *ctx, struct bytecode_buffer * write_sm1_src_register(buffer, &instr->srcs[i], instr->dst.writemask); };
-static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, +static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst, const struct hlsl_reg *src1, const struct hlsl_reg *src2) { @@ -1714,7 +1663,7 @@ static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct bytecode_buffer *bu write_sm1_instruction(ctx, buffer, &instr); }
-static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, +static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst, const struct hlsl_reg *src, D3DSHADER_PARAM_SRCMOD_TYPE src_mod) { @@ -1736,7 +1685,7 @@ static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct bytecode_buffer *buf write_sm1_instruction(ctx, buffer, &instr); }
-static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer) +static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer) { unsigned int i, x;
@@ -1752,15 +1701,15 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct bytecode_buffer
if (ctx->profile->major_version > 1) token |= 5 << D3DSI_INSTLENGTH_SHIFT; - put_dword(buffer, token); + vkd3d_put_u32(buffer, token);
write_sm1_dst_register(buffer, ®); for (x = 0; x < 4; ++x) - put_float(buffer, ctx->constant_defs.values[i].f[x]); + vkd3d_put_float(buffer, ctx->constant_defs.values[i].f[x]); } }
-static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, +static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var, bool output) { struct sm1_dst_register reg = {0}; @@ -1784,18 +1733,18 @@ static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct bytecode_buffer token = D3DSIO_DCL; if (ctx->profile->major_version > 1) token |= 2 << D3DSI_INSTLENGTH_SHIFT; - put_dword(buffer, token); + vkd3d_put_u32(buffer, token);
token = (1u << 31); token |= usage << D3DSP_DCL_USAGE_SHIFT; token |= usage_idx << D3DSP_DCL_USAGEINDEX_SHIFT; - put_dword(buffer, token); + vkd3d_put_u32(buffer, token);
reg.writemask = (1 << var->data_type->dimx) - 1; write_sm1_dst_register(buffer, ®); }
-static void write_sm1_semantic_dcls(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer) +static void write_sm1_semantic_dcls(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer) { bool write_in = false, write_out = false; struct hlsl_ir_var *var; @@ -1816,7 +1765,8 @@ static void write_sm1_semantic_dcls(struct hlsl_ctx *ctx, struct bytecode_buffer } }
-static void write_sm1_constant(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr) +static void write_sm1_constant(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_ir_node *instr) { const struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); struct sm1_instruction sm1_instr = @@ -1839,7 +1789,7 @@ static void write_sm1_constant(struct hlsl_ctx *ctx, struct bytecode_buffer *buf write_sm1_instruction(ctx, buffer, &sm1_instr); }
-static void write_sm1_expr(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr) +static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr) { struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); struct hlsl_ir_node *arg1 = expr->operands[0].node; @@ -1889,7 +1839,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, } }
-static void write_sm1_load(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr) +static void write_sm1_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr) { const struct hlsl_ir_load *load = hlsl_ir_load(instr); const struct hlsl_reg reg = hlsl_reg_from_deref(&load->src, instr->data_type); @@ -1931,7 +1881,8 @@ static void write_sm1_load(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, write_sm1_instruction(ctx, buffer, &sm1_instr); }
-static void write_sm1_store(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr) +static void write_sm1_store(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_ir_node *instr) { const struct hlsl_ir_store *store = hlsl_ir_store(instr); const struct hlsl_ir_node *rhs = store->rhs.node; @@ -1974,7 +1925,8 @@ static void write_sm1_store(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer write_sm1_instruction(ctx, buffer, &sm1_instr); }
-static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, const struct hlsl_ir_node *instr) +static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_ir_node *instr) { const struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(instr); const struct hlsl_ir_node *val = swizzle->val.node; @@ -1999,7 +1951,7 @@ static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct bytecode_buffer *buff write_sm1_instruction(ctx, buffer, &sm1_instr); }
-static void write_sm1_instructions(struct hlsl_ctx *ctx, struct bytecode_buffer *buffer, +static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_function_decl *entry_func) { const struct hlsl_ir_node *instr; @@ -2048,10 +2000,10 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct bytecode_buffer static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) { - struct bytecode_buffer buffer = {.ctx = ctx}; + struct vkd3d_bytecode_buffer buffer = {0}; int ret;
- put_dword(&buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version)); + vkd3d_put_u32(&buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
write_sm1_uniforms(ctx, &buffer, entry_func);
@@ -2059,7 +2011,7 @@ static int write_sm1_shader(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl * write_sm1_semantic_dcls(ctx, &buffer); write_sm1_instructions(ctx, &buffer, entry_func);
- put_dword(&buffer, D3DSIO_END); + vkd3d_put_u32(&buffer, D3DSIO_END);
if (!(ret = buffer.status)) { diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 40d55b70..9f366a43 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -282,6 +282,49 @@ void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const stru va_end(args); }
+static size_t vkd3d_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size, size_t alignment) +{ + size_t prev_size = buffer->size; + size_t offset = align(prev_size, alignment); + + if (buffer->status) + return offset; + + if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->capacity, offset + size, 1)) + { + buffer->status = VKD3D_ERROR_OUT_OF_MEMORY; + return offset; + } + memset(buffer->data + prev_size, 0xab, offset - prev_size); + memcpy(buffer->data + offset, bytes, size); + buffer->size = offset + size; + return offset; +} + +size_t vkd3d_put_u32(struct vkd3d_bytecode_buffer *buffer, uint32_t value) +{ + return vkd3d_put_bytes(buffer, &value, sizeof(value), sizeof(value)); +} + +size_t vkd3d_put_float(struct vkd3d_bytecode_buffer *buffer, float value) +{ + return vkd3d_put_bytes(buffer, &value, sizeof(value), sizeof(value)); +} + +size_t vkd3d_put_string(struct vkd3d_bytecode_buffer *buffer, const char *string) +{ + return vkd3d_put_bytes(buffer, string, strlen(string) + 1, 1); +} + +void vkd3d_set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value) +{ + if (buffer->status) + return; + + assert(offset + sizeof(value) <= buffer->size); + memcpy(buffer->data + offset, &value, sizeof(value)); +} + static void vkd3d_shader_dump_blob(const char *path, const char *prefix, const void *data, size_t size) { static int shader_id = 0; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index c61b3773..d736e411 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -899,6 +899,18 @@ void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *list, void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function) DECLSPEC_HIDDEN; int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args) DECLSPEC_HIDDEN;
+struct vkd3d_bytecode_buffer +{ + char *data; + size_t size, capacity; + int status; +}; + +size_t vkd3d_put_float(struct vkd3d_bytecode_buffer *buffer, float value) DECLSPEC_HIDDEN; +size_t vkd3d_put_u32(struct vkd3d_bytecode_buffer *buffer, uint32_t value) DECLSPEC_HIDDEN; +size_t vkd3d_put_string(struct vkd3d_bytecode_buffer *buffer, const char *string) DECLSPEC_HIDDEN; +void vkd3d_set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value) DECLSPEC_HIDDEN; + struct vkd3d_shader_location { const char *source_name;