Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v4: Split up the patch, and preserve an out-of-memory error message.
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 4bc62014..a0c083f1 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -2911,9 +2911,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; @@ -2924,12 +2922,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) @@ -2939,22 +2935,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;
@@ -2965,7 +2958,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;
@@ -2973,14 +2966,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;
@@ -3136,11 +3129,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))) @@ -3153,7 +3147,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)) { @@ -3241,6 +3235,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;
@@ -3254,7 +3249,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;
@@ -3264,7 +3259,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: @@ -3387,6 +3382,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); @@ -3413,26 +3409,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;