Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- configure.ac | 1 + include/private/vkd3d_common.h | 11 +++++++++++ libs/vkd3d/command.c | 4 ++-- libs/vkd3d/device.c | 3 +-- 4 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac index 275bca26..88d58e40 100644 --- a/configure.ac +++ b/configure.ac @@ -127,6 +127,7 @@ AS_IF([test "x$with_xcb" != "xno"], dnl Check for functions VKD3D_CHECK_FUNC([HAVE_BUILTIN_CLZ], [__builtin_clz], [__builtin_clz(0)]) VKD3D_CHECK_FUNC([HAVE_BUILTIN_POPCOUNT], [__builtin_popcount], [__builtin_popcount(0)]) +VKD3D_CHECK_FUNC([HAVE_BUILTIN_ADD_OVERFLOW], [__builtin_add_overflow], [__builtin_add_overflow(0, 0, (int *)0)]) VKD3D_CHECK_FUNC([HAVE_SYNC_ADD_AND_FETCH], [__sync_add_and_fetch], [__sync_add_and_fetch((int *)0, 0)]) VKD3D_CHECK_FUNC([HAVE_SYNC_SUB_AND_FETCH], [__sync_sub_and_fetch], [__sync_sub_and_fetch((int *)0, 0)])
diff --git a/include/private/vkd3d_common.h b/include/private/vkd3d_common.h index 4ce2a2e3..369226f8 100644 --- a/include/private/vkd3d_common.h +++ b/include/private/vkd3d_common.h @@ -138,6 +138,17 @@ static inline void *vkd3d_memmem( const void *haystack, size_t haystack_len, con return NULL; }
+static inline bool vkd3d_bound_range(size_t start, size_t count, size_t limit) +{ +#ifdef HAVE_BUILTIN_ADD_OVERFLOW + size_t sum; + + return !__builtin_add_overflow(start, count, &sum) && sum <= limit; +#else + return start <= limit && count <= limit - start; +#endif +} + static inline int ascii_isupper(int c) { return 'A' <= c && c <= 'Z'; diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 614d19e7..93c519af 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -4422,7 +4422,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi null_resources = &list->device->null_resources; gpu_va_allocator = &list->device->gpu_va_allocator;
- if (start_slot >= ARRAY_SIZE(list->strides) || view_count > ARRAY_SIZE(list->strides) - start_slot) + if (!vkd3d_bound_range(start_slot, view_count, ARRAY_SIZE(list->strides))) { WARN("Invalid start slot %u / view count %u.\n", start_slot, view_count); return; @@ -4477,7 +4477,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm return; }
- if (start_slot >= ARRAY_SIZE(buffers) || view_count > ARRAY_SIZE(buffers) - start_slot) + if (!vkd3d_bound_range(start_slot, view_count, ARRAY_SIZE(buffers))) { WARN("Invalid start slot %u / view count %u.\n", start_slot, view_count); return; diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 159bc470..be0bf2fb 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -3515,8 +3515,7 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device *i
array_size = d3d12_resource_desc_get_layer_count(desc);
- if (first_sub_resource >= desc->MipLevels * array_size - || sub_resource_count > desc->MipLevels * array_size - first_sub_resource) + if (!vkd3d_bound_range(first_sub_resource, sub_resource_count, desc->MipLevels * array_size)) { WARN("Invalid sub-resource range %u-%u for resource.\n", first_sub_resource, sub_resource_count); return;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 165 ++++++++--------------- libs/vkd3d-shader/vkd3d_shader_main.c | 28 ++++ libs/vkd3d-shader/vkd3d_shader_private.h | 30 +++++ 3 files changed, 114 insertions(+), 109 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 51cb789f..7e3e4d77 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1321,62 +1321,6 @@ static struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const return ret; }
-struct bytecode_buffer -{ - struct hlsl_ctx *ctx; - uint8_t *data; - size_t size, capacity; - int status; -}; - -static size_t put_bytes(struct bytecode_buffer *buffer, const void *bytes, size_t size) -{ - size_t aligned_size = align(size, 4); - size_t offset = buffer->size; - - if (buffer->status) - return offset; - - if (!hlsl_array_reserve(buffer->ctx, (void **)&buffer->data, &buffer->capacity, offset + aligned_size, 1)) - { - buffer->status = VKD3D_ERROR_OUT_OF_MEMORY; - return offset; - } - memcpy(buffer->data + offset, bytes, size); - memset(buffer->data + offset + size, 0xab, aligned_size - size); - buffer->size = offset + aligned_size; - return offset; -} - -static size_t put_dword(struct bytecode_buffer *buffer, uint32_t value) -{ - return put_bytes(buffer, &value, sizeof(value)); -} - -static size_t put_float(struct bytecode_buffer *buffer, float value) -{ - return put_bytes(buffer, &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); -} - -static size_t get_buffer_size(struct bytecode_buffer *buffer) -{ - return buffer->size; -} - static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, unsigned int minor) { if (type == VKD3D_SHADER_TYPE_VERTEX) @@ -1487,7 +1431,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); @@ -1506,20 +1450,20 @@ static void write_sm1_type(struct bytecode_buffer *buffer, struct hlsl_type *typ write_sm1_type(buffer, field->type, ctab_start); }
- fields_offset = get_buffer_size(buffer) - ctab_start; + fields_offset = bytecode_get_size(buffer) - ctab_start;
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); + put_u32(buffer, field->name_bytecode_offset - ctab_start); + 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 = put_u32(buffer, sm1_class(type) | (sm1_base_type(type) << 16)); + put_u32(buffer, type->dimy | (type->dimx << 16)); + put_u32(buffer, array_size | (field_count << 16)); + put_u32(buffer, fields_offset); }
static void sm1_sort_extern(struct list *sorted, struct hlsl_ir_var *to_sort) @@ -1550,7 +1494,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_offset, ctab_start, ctab_end, vars_start, size_offset, creator_offset, offset; @@ -1582,28 +1526,28 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
sm1_sort_externs(ctx);
- size_offset = put_dword(buffer, 0); - ctab_offset = put_dword(buffer, MAKEFOURCC('C','T','A','B')); + size_offset = put_u32(buffer, 0); + ctab_offset = 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 = put_u32(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); + creator_offset = put_u32(buffer, 0); + put_u32(buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version)); + put_u32(buffer, uniform_count); + put_u32(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* offset of constants */ + put_u32(buffer, 0); /* FIXME: flags */ + put_u32(buffer, 0); /* FIXME: target string */
- vars_start = get_buffer_size(buffer); + vars_start = bytecode_get_size(buffer);
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { 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 */ + put_u32(buffer, 0); /* name */ + put_u32(buffer, D3DXRS_FLOAT4 | (var->reg.id << 16)); + put_u32(buffer, var->data_type->reg_size / 4); + put_u32(buffer, 0); /* type */ + put_u32(buffer, 0); /* FIXME: default value */ } }
@@ -1617,19 +1561,19 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf size_t name_offset;
name_offset = put_string(buffer, var->name); - set_dword(buffer, var_offset, name_offset - ctab_start); + set_u32(buffer, var_offset, name_offset - ctab_start);
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); + 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); + set_u32(buffer, creator_offset, offset - ctab_start);
- ctab_end = get_buffer_size(buffer); - set_dword(buffer, size_offset, D3DSIO_COMMENT | (((ctab_end - ctab_offset) / sizeof(uint32_t)) << 16)); + ctab_end = bytecode_get_size(buffer); + set_u32(buffer, size_offset, D3DSIO_COMMENT | (((ctab_end - ctab_offset) / sizeof(uint32_t)) << 16)); }
static uint32_t sm1_encode_register_type(D3DSHADER_PARAM_REGISTER_TYPE type) @@ -1662,21 +1606,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); + 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); + 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; @@ -1684,7 +1628,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); + put_u32(buffer, token);
if (instr->has_dst) write_sm1_dst_register(buffer, &instr->dst); @@ -1693,7 +1637,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) { @@ -1717,7 +1661,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) { @@ -1739,7 +1683,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;
@@ -1755,15 +1699,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); + 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]); + put_f32(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}; @@ -1787,18 +1731,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); + put_u32(buffer, token);
token = (1u << 31); token |= usage << D3DSP_DCL_USAGE_SHIFT; token |= usage_idx << D3DSP_DCL_USAGEINDEX_SHIFT; - put_dword(buffer, token); + 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; @@ -1819,7 +1763,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 = @@ -1842,7 +1787,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; @@ -1892,7 +1837,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); @@ -1934,7 +1879,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; @@ -1977,7 +1923,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; @@ -2002,7 +1949,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; @@ -2051,10 +1998,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)); + put_u32(&buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
write_sm1_uniforms(ctx, &buffer, entry_func);
@@ -2062,7 +2009,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); + 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 1a566a7b..78312a14 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -282,6 +282,34 @@ void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const stru va_end(args); }
+size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size) +{ + size_t aligned_size = align(size, 4); + size_t offset = buffer->size; + + if (buffer->status) + return offset; + + if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->capacity, offset + aligned_size, 1)) + { + buffer->status = VKD3D_ERROR_OUT_OF_MEMORY; + return offset; + } + memcpy(buffer->data + offset, bytes, size); + memset(buffer->data + offset + size, 0xab, aligned_size - size); + buffer->size = offset + aligned_size; + return offset; +} + +void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value) +{ + if (buffer->status) + return; + + assert(vkd3d_bound_range(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 b247acc0..3603d983 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -906,6 +906,36 @@ 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 +{ + uint8_t *data; + size_t size, capacity; + int status; +}; + +size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size) DECLSPEC_HIDDEN; +void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value) DECLSPEC_HIDDEN; + +static inline size_t put_u32(struct vkd3d_bytecode_buffer *buffer, uint32_t value) +{ + return bytecode_put_bytes(buffer, &value, sizeof(value)); +} + +static inline size_t put_f32(struct vkd3d_bytecode_buffer *buffer, float value) +{ + return bytecode_put_bytes(buffer, &value, sizeof(value)); +} + +static inline size_t put_string(struct vkd3d_bytecode_buffer *buffer, const char *string) +{ + return bytecode_put_bytes(buffer, string, strlen(string) + 1); +} + +static inline size_t bytecode_get_size(struct vkd3d_bytecode_buffer *buffer) +{ + return buffer->size; +} + struct vkd3d_shader_location { const char *source_name;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 65 +++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 30 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index e57cc413..5bd91d68 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -2930,9 +2930,7 @@ struct root_signature_writer_context { struct vkd3d_shader_message_context message_context;
- DWORD *data; - size_t position; - size_t capacity; + struct vkd3d_bytecode_buffer buffer;
size_t total_size_position; size_t chunk_position; @@ -2943,12 +2941,10 @@ static bool write_dwords(struct root_signature_writer_context *context, { unsigned int i;
- if (!vkd3d_array_reserve((void **)&context->data, &context->capacity, - context->position + count, sizeof(*context->data))) - return false; for (i = 0; i < count; ++i) - context->data[context->position++] = d; - return true; + put_u32(&context->buffer, d); + + return !context->buffer.status; }
static bool write_dword(struct root_signature_writer_context *context, DWORD d) @@ -2958,22 +2954,19 @@ static bool write_dword(struct root_signature_writer_context *context, DWORD d)
static bool write_float(struct root_signature_writer_context *context, float f) { - union - { - float f; - DWORD d; - } u; - u.f = f; - return write_dword(context, u.d); + put_f32(&context->buffer, f); + return !context->buffer.status; }
static size_t get_chunk_offset(struct root_signature_writer_context *context) { - return (context->position - context->chunk_position) * sizeof(DWORD); + return bytecode_get_size(&context->buffer) - context->chunk_position; }
static int shader_write_root_signature_header(struct root_signature_writer_context *context) { + struct vkd3d_bytecode_buffer *buffer = &context->buffer; + if (!write_dword(context, TAG_DXBC)) goto fail;
@@ -2984,7 +2977,7 @@ static int shader_write_root_signature_header(struct root_signature_writer_conte if (!write_dword(context, 0x00000001)) goto fail;
- context->total_size_position = context->position; + context->total_size_position = bytecode_get_size(buffer); if (!write_dword(context, 0xffffffff)) /* total size */ goto fail;
@@ -2992,14 +2985,14 @@ static int shader_write_root_signature_header(struct root_signature_writer_conte goto fail;
/* chunk offset */ - if (!write_dword(context, (context->position + 1) * sizeof(DWORD))) + if (!write_dword(context, bytecode_get_size(buffer) + sizeof(uint32_t))) goto fail;
if (!write_dword(context, TAG_RTS0)) goto fail; if (!write_dword(context, 0xffffffff)) /* chunk size */ goto fail; - context->chunk_position = context->position; + context->chunk_position = bytecode_get_size(buffer);
return VKD3D_OK;
@@ -3155,11 +3148,12 @@ static int shader_write_root_parameters(struct root_signature_writer_context *co const struct vkd3d_shader_versioned_root_signature_desc *desc) { unsigned int parameter_count = versioned_root_signature_get_parameter_count(desc); + struct vkd3d_bytecode_buffer *buffer = &context->buffer; size_t parameters_position; unsigned int i; int ret;
- parameters_position = context->position; + parameters_position = bytecode_get_size(buffer); for (i = 0; i < parameter_count; ++i) { if (!write_dword(context, versioned_root_signature_get_parameter_type(desc, i))) @@ -3172,7 +3166,7 @@ static int shader_write_root_parameters(struct root_signature_writer_context *co
for (i = 0; i < parameter_count; ++i) { - context->data[parameters_position + 3 * i + 2] = get_chunk_offset(context); /* offset */ + set_u32(buffer, parameters_position + ((3 * i + 2) * sizeof(uint32_t)), get_chunk_offset(context));
switch (versioned_root_signature_get_parameter_type(desc, i)) { @@ -3260,6 +3254,7 @@ fail: static int shader_write_root_signature(struct root_signature_writer_context *context, const struct vkd3d_shader_versioned_root_signature_desc *desc) { + struct vkd3d_bytecode_buffer *buffer = &context->buffer; size_t samplers_offset_position; int ret;
@@ -3273,7 +3268,7 @@ static int shader_write_root_signature(struct root_signature_writer_context *con
if (!write_dword(context, versioned_root_signature_get_static_sampler_count(desc))) goto fail; - samplers_offset_position = context->position; + samplers_offset_position = bytecode_get_size(buffer); if (!write_dword(context, 0xffffffff)) /* offset */ goto fail;
@@ -3283,7 +3278,7 @@ static int shader_write_root_signature(struct root_signature_writer_context *con if ((ret = shader_write_root_parameters(context, desc)) < 0) return ret;
- context->data[samplers_offset_position] = get_chunk_offset(context); + set_u32(buffer, samplers_offset_position, get_chunk_offset(context)); return shader_write_static_samplers(context, desc);
fail: @@ -3406,6 +3401,7 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro struct root_signature_writer_context context; size_t total_size, chunk_size; uint32_t checksum[4]; + unsigned int i; int ret;
TRACE("root_signature %p, dxbc %p, messages %p.\n", root_signature, dxbc, messages); @@ -3432,26 +3428,35 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro memset(dxbc, 0, sizeof(*dxbc)); if ((ret = shader_write_root_signature_header(&context)) < 0) { - vkd3d_free(context.data); + vkd3d_free(context.buffer.data); goto done; }
if ((ret = shader_write_root_signature(&context, root_signature)) < 0) { - vkd3d_free(context.data); + vkd3d_free(context.buffer.data); + goto done; + } + + if (context.buffer.status) + { + vkd3d_shader_error(&context.message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, + "Out of memory while writing root signature."); + vkd3d_free(context.buffer.data); goto done; }
- total_size = context.position * sizeof(DWORD); + total_size = bytecode_get_size(&context.buffer); chunk_size = get_chunk_offset(&context); - context.data[context.total_size_position] = total_size; - context.data[context.chunk_position - 1] = chunk_size; + set_u32(&context.buffer, context.total_size_position, total_size); + set_u32(&context.buffer, context.chunk_position - sizeof(uint32_t), chunk_size);
- dxbc->code = context.data; + dxbc->code = context.buffer.data; dxbc->size = total_size;
vkd3d_compute_dxbc_checksum(dxbc->code, dxbc->size, checksum); - memcpy((uint32_t *)dxbc->code + 1, checksum, sizeof(checksum)); + for (i = 0; i < 4; ++i) + set_u32(&context.buffer, (i + 1) * sizeof(uint32_t), checksum[i]);
ret = VKD3D_OK;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=94546
Your paranoid android.
=== debiant2 (build log) ===
error: patch failed: configure.ac:127 Task: Patch failed to apply
=== debiant2 (build log) ===
error: patch failed: configure.ac:127 Task: Patch failed to apply