Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 374 +++++++++++---------------------------- 1 file changed, 105 insertions(+), 269 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 70ab70aa..21cf1a20 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -2897,86 +2897,38 @@ 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; -}; - -static bool write_dwords(struct root_signature_writer_context *context, - unsigned int count, DWORD d) -{ - 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; -}
-static bool write_dword(struct root_signature_writer_context *context, DWORD d) -{ - return write_dwords(context, 1, 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); -} + int status; +};
static size_t get_chunk_offset(struct root_signature_writer_context *context) { - return (context->position - context->chunk_position) * sizeof(DWORD); + return context->buffer.size - context->chunk_position; }
-static int shader_write_root_signature_header(struct root_signature_writer_context *context) +static void shader_write_root_signature_header(struct root_signature_writer_context *context) { - if (!write_dword(context, TAG_DXBC)) - goto fail; + struct vkd3d_bytecode_buffer *buffer = &context->buffer; + unsigned int i;
+ vkd3d_put_u32(buffer, TAG_DXBC); /* The checksum is computed when all data is generated. */ - if (!write_dwords(context, 4, 0x00000000)) - goto fail; - - if (!write_dword(context, 0x00000001)) - goto fail; - - context->total_size_position = context->position; - if (!write_dword(context, 0xffffffff)) /* total size */ - goto fail; - - if (!write_dword(context, 1)) /* chunk count */ - goto fail; - - /* chunk offset */ - if (!write_dword(context, (context->position + 1) * sizeof(DWORD))) - goto fail; - - if (!write_dword(context, TAG_RTS0)) - goto fail; - if (!write_dword(context, 0xffffffff)) /* chunk size */ - goto fail; - context->chunk_position = context->position; - - return VKD3D_OK; - -fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature header."); - return VKD3D_ERROR_OUT_OF_MEMORY; -} - -static int shader_write_descriptor_ranges(struct root_signature_writer_context *context, + for (i = 0; i < 4; ++i) + vkd3d_put_u32(buffer, 0); + vkd3d_put_u32(buffer, 1); + context->total_size_position = vkd3d_put_u32(buffer, 0xffffffff); + vkd3d_put_u32(buffer, 1); /* chunk count */ + vkd3d_put_u32(buffer, buffer->size + sizeof(uint32_t)); /* chunk offset */ + vkd3d_put_u32(buffer, TAG_RTS0); + vkd3d_put_u32(buffer, 0xffffffff); + context->chunk_position = buffer->size; +} + +static void shader_write_descriptor_ranges(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_root_descriptor_table *table) { const struct vkd3d_shader_descriptor_range *ranges = table->descriptor_ranges; @@ -2984,27 +2936,15 @@ static int shader_write_descriptor_ranges(struct root_signature_writer_context *
for (i = 0; i < table->descriptor_range_count; ++i) { - if (!write_dword(context, ranges[i].range_type)) - goto fail; - if (!write_dword(context, ranges[i].descriptor_count)) - goto fail; - if (!write_dword(context, ranges[i].base_shader_register)) - goto fail; - if (!write_dword(context, ranges[i].register_space)) - goto fail; - if (!write_dword(context, ranges[i].descriptor_table_offset)) - goto fail; + vkd3d_put_u32(buffer, ranges[i].range_type); + vkd3d_put_u32(buffer, ranges[i].descriptor_count); + vkd3d_put_u32(buffer, ranges[i].base_shader_register); + vkd3d_put_u32(buffer, ranges[i].register_space); + vkd3d_put_u32(buffer, ranges[i].descriptor_table_offset); } - - return VKD3D_OK; - -fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature descriptor ranges."); - return VKD3D_ERROR_OUT_OF_MEMORY; }
-static int shader_write_descriptor_ranges1(struct root_signature_writer_context *context, +static void shader_write_descriptor_ranges1(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_root_descriptor_table1 *table) { const struct vkd3d_shader_descriptor_range1 *ranges = table->descriptor_ranges; @@ -3012,175 +2952,113 @@ static int shader_write_descriptor_ranges1(struct root_signature_writer_context
for (i = 0; i < table->descriptor_range_count; ++i) { - if (!write_dword(context, ranges[i].range_type)) - goto fail; - if (!write_dword(context, ranges[i].descriptor_count)) - goto fail; - if (!write_dword(context, ranges[i].base_shader_register)) - goto fail; - if (!write_dword(context, ranges[i].register_space)) - goto fail; - if (!write_dword(context, ranges[i].flags)) - goto fail; - if (!write_dword(context, ranges[i].descriptor_table_offset)) - goto fail; + vkd3d_put_u32(buffer, ranges[i].range_type); + vkd3d_put_u32(buffer, ranges[i].descriptor_count); + vkd3d_put_u32(buffer, ranges[i].base_shader_register); + vkd3d_put_u32(buffer, ranges[i].register_space); + vkd3d_put_u32(buffer, ranges[i].flags); + vkd3d_put_u32(buffer, ranges[i].descriptor_table_offset); } - - return VKD3D_OK; - -fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature descriptor ranges."); - return VKD3D_ERROR_OUT_OF_MEMORY; }
-static int shader_write_descriptor_table(struct root_signature_writer_context *context, +static void shader_write_descriptor_table(struct root_signature_writer_context *context, const struct vkd3d_shader_root_descriptor_table *table) { - if (!write_dword(context, table->descriptor_range_count)) - goto fail; - if (!write_dword(context, get_chunk_offset(context) + sizeof(DWORD))) /* offset */ - goto fail; + struct vkd3d_bytecode_buffer *buffer = &context->buffer;
- return shader_write_descriptor_ranges(context, table); + vkd3d_put_u32(buffer, table->descriptor_range_count); + vkd3d_put_u32(buffer, get_chunk_offset(context) + sizeof(uint32_t)); /* offset */
-fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature root descriptor table."); - return VKD3D_ERROR_OUT_OF_MEMORY; + shader_write_descriptor_ranges(buffer, table); }
-static int shader_write_descriptor_table1(struct root_signature_writer_context *context, +static void shader_write_descriptor_table1(struct root_signature_writer_context *context, const struct vkd3d_shader_root_descriptor_table1 *table) { - if (!write_dword(context, table->descriptor_range_count)) - goto fail; - if (!write_dword(context, get_chunk_offset(context) + sizeof(DWORD))) /* offset */ - goto fail; + struct vkd3d_bytecode_buffer *buffer = &context->buffer;
- return shader_write_descriptor_ranges1(context, table); + vkd3d_put_u32(buffer, table->descriptor_range_count); + vkd3d_put_u32(buffer, get_chunk_offset(context) + sizeof(uint32_t)); /* offset */
-fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature root descriptor table."); - return VKD3D_ERROR_OUT_OF_MEMORY; + shader_write_descriptor_ranges1(buffer, table); }
-static int shader_write_root_constants(struct root_signature_writer_context *context, +static void shader_write_root_constants(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_root_constants *constants) { - if (!write_dword(context, constants->shader_register)) - goto fail; - if (!write_dword(context, constants->register_space)) - goto fail; - if (!write_dword(context, constants->value_count)) - goto fail; - - return VKD3D_OK; - -fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature root constants."); - return VKD3D_ERROR_OUT_OF_MEMORY; + vkd3d_put_u32(buffer, constants->shader_register); + vkd3d_put_u32(buffer, constants->register_space); + vkd3d_put_u32(buffer, constants->value_count); }
-static int shader_write_root_descriptor(struct root_signature_writer_context *context, +static void shader_write_root_descriptor(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_root_descriptor *descriptor) { - if (!write_dword(context, descriptor->shader_register)) - goto fail; - if (!write_dword(context, descriptor->register_space)) - goto fail; - - return VKD3D_OK; - -fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature root descriptor."); - return VKD3D_ERROR_OUT_OF_MEMORY; + vkd3d_put_u32(buffer, descriptor->shader_register); + vkd3d_put_u32(buffer, descriptor->register_space); }
-static int shader_write_root_descriptor1(struct root_signature_writer_context *context, +static void shader_write_root_descriptor1(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_root_descriptor1 *descriptor) { - if (!write_dword(context, descriptor->shader_register)) - goto fail; - if (!write_dword(context, descriptor->register_space)) - goto fail; - if (!write_dword(context, descriptor->flags)) - goto fail; - - return VKD3D_OK; - -fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature root descriptor."); - return VKD3D_ERROR_OUT_OF_MEMORY; + vkd3d_put_u32(buffer, descriptor->shader_register); + vkd3d_put_u32(buffer, descriptor->register_space); + vkd3d_put_u32(buffer, descriptor->flags); }
-static int shader_write_root_parameters(struct root_signature_writer_context *context, +static void shader_write_root_parameters(struct root_signature_writer_context *context, 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 = buffer->size; for (i = 0; i < parameter_count; ++i) { - if (!write_dword(context, versioned_root_signature_get_parameter_type(desc, i))) - goto fail; - if (!write_dword(context, versioned_root_signature_get_parameter_shader_visibility(desc, i))) - goto fail; - if (!write_dword(context, 0xffffffff)) /* offset */ - goto fail; + vkd3d_put_u32(buffer, versioned_root_signature_get_parameter_type(desc, i)); + vkd3d_put_u32(buffer, versioned_root_signature_get_parameter_shader_visibility(desc, i)); + vkd3d_put_u32(buffer, 0xffffffff); /* offset */ }
for (i = 0; i < parameter_count; ++i) { - context->data[parameters_position + 3 * i + 2] = get_chunk_offset(context); /* offset */ + vkd3d_set_u32(buffer, parameters_position + ((3 * i + 2) * sizeof(uint32_t)), get_chunk_offset(context));
switch (versioned_root_signature_get_parameter_type(desc, i)) { case VKD3D_SHADER_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: if (desc->version == VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_0) - ret = shader_write_descriptor_table(context, &desc->u.v_1_0.parameters[i].u.descriptor_table); + shader_write_descriptor_table(context, &desc->u.v_1_0.parameters[i].u.descriptor_table); else - ret = shader_write_descriptor_table1(context, &desc->u.v_1_1.parameters[i].u.descriptor_table); + shader_write_descriptor_table1(context, &desc->u.v_1_1.parameters[i].u.descriptor_table); break; + case VKD3D_SHADER_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: - ret = shader_write_root_constants(context, versioned_root_signature_get_root_constants(desc, i)); + shader_write_root_constants(buffer, versioned_root_signature_get_root_constants(desc, i)); break; + case VKD3D_SHADER_ROOT_PARAMETER_TYPE_CBV: case VKD3D_SHADER_ROOT_PARAMETER_TYPE_SRV: case VKD3D_SHADER_ROOT_PARAMETER_TYPE_UAV: if (desc->version == VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_0) - ret = shader_write_root_descriptor(context, &desc->u.v_1_0.parameters[i].u.descriptor); + shader_write_root_descriptor(buffer, &desc->u.v_1_0.parameters[i].u.descriptor); else - ret = shader_write_root_descriptor1(context, &desc->u.v_1_1.parameters[i].u.descriptor); + shader_write_root_descriptor1(buffer, &desc->u.v_1_1.parameters[i].u.descriptor); break; + default: FIXME("Unrecognized type %#x.\n", versioned_root_signature_get_parameter_type(desc, i)); vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_INVALID_ROOT_PARAMETER_TYPE, "Invalid/unrecognised root signature root parameter type %#x.", versioned_root_signature_get_parameter_type(desc, i)); - return VKD3D_ERROR_INVALID_ARGUMENT; + context->status = VKD3D_ERROR_INVALID_ARGUMENT; } - - if (ret < 0) - return ret; } - - return VKD3D_OK; - -fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature root parameters."); - return VKD3D_ERROR_OUT_OF_MEMORY; }
-static int shader_write_static_samplers(struct root_signature_writer_context *context, +static void shader_write_static_samplers(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_versioned_root_signature_desc *desc) { const struct vkd3d_shader_static_sampler_desc *samplers = versioned_root_signature_get_static_samplers(desc); @@ -3188,75 +3066,39 @@ static int shader_write_static_samplers(struct root_signature_writer_context *co
for (i = 0; i < versioned_root_signature_get_static_sampler_count(desc); ++i) { - if (!write_dword(context, samplers[i].filter)) - goto fail; - if (!write_dword(context, samplers[i].address_u)) - goto fail; - if (!write_dword(context, samplers[i].address_v)) - goto fail; - if (!write_dword(context, samplers[i].address_w)) - goto fail; - if (!write_float(context, samplers[i].mip_lod_bias)) - goto fail; - if (!write_dword(context, samplers[i].max_anisotropy)) - goto fail; - if (!write_dword(context, samplers[i].comparison_func)) - goto fail; - if (!write_dword(context, samplers[i].border_colour)) - goto fail; - if (!write_float(context, samplers[i].min_lod)) - goto fail; - if (!write_float(context, samplers[i].max_lod)) - goto fail; - if (!write_dword(context, samplers[i].shader_register)) - goto fail; - if (!write_dword(context, samplers[i].register_space)) - goto fail; - if (!write_dword(context, samplers[i].shader_visibility)) - goto fail; + vkd3d_put_u32(buffer, samplers[i].filter); + vkd3d_put_u32(buffer, samplers[i].address_u); + vkd3d_put_u32(buffer, samplers[i].address_v); + vkd3d_put_u32(buffer, samplers[i].address_w); + vkd3d_put_float(buffer, samplers[i].mip_lod_bias); + vkd3d_put_u32(buffer, samplers[i].max_anisotropy); + vkd3d_put_u32(buffer, samplers[i].comparison_func); + vkd3d_put_u32(buffer, samplers[i].border_colour); + vkd3d_put_float(buffer, samplers[i].min_lod); + vkd3d_put_float(buffer, samplers[i].max_lod); + vkd3d_put_u32(buffer, samplers[i].shader_register); + vkd3d_put_u32(buffer, samplers[i].register_space); + vkd3d_put_u32(buffer, samplers[i].shader_visibility); } - - return VKD3D_OK; - -fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature static samplers."); - return VKD3D_ERROR_OUT_OF_MEMORY; }
-static int shader_write_root_signature(struct root_signature_writer_context *context, +static void 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;
- if (!write_dword(context, desc->version)) - goto fail; + vkd3d_put_u32(buffer, desc->version); + vkd3d_put_u32(buffer, versioned_root_signature_get_parameter_count(desc)); + vkd3d_put_u32(buffer, get_chunk_offset(context) + 4 * sizeof(uint32_t)); /* offset */ + vkd3d_put_u32(buffer, versioned_root_signature_get_static_sampler_count(desc)); + samplers_offset_position = vkd3d_put_u32(buffer, 0xffffffff); + vkd3d_put_u32(buffer, versioned_root_signature_get_flags(desc));
- if (!write_dword(context, versioned_root_signature_get_parameter_count(desc))) - goto fail; - if (!write_dword(context, get_chunk_offset(context) + 4 * sizeof(DWORD))) /* offset */ - goto fail; + shader_write_root_parameters(context, desc);
- if (!write_dword(context, versioned_root_signature_get_static_sampler_count(desc))) - goto fail; - samplers_offset_position = context->position; - if (!write_dword(context, 0xffffffff)) /* offset */ - goto fail; - - if (!write_dword(context, versioned_root_signature_get_flags(desc))) - goto fail; - - if ((ret = shader_write_root_parameters(context, desc)) < 0) - return ret; - - context->data[samplers_offset_position] = get_chunk_offset(context); - return shader_write_static_samplers(context, desc); - -fail: - vkd3d_shader_error(&context->message_context, NULL, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY, - "Out of memory while writing root signature."); - return VKD3D_ERROR_OUT_OF_MEMORY; + vkd3d_set_u32(buffer, samplers_offset_position, get_chunk_offset(context)); + shader_write_static_samplers(buffer, desc); }
static int validate_descriptor_table_v_1_0(const struct vkd3d_shader_root_descriptor_table *descriptor_table, @@ -3373,6 +3215,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); @@ -3397,30 +3240,23 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro goto done;
memset(dxbc, 0, sizeof(*dxbc)); - if ((ret = shader_write_root_signature_header(&context)) < 0) - { - vkd3d_free(context.data); - goto done; - } - - if ((ret = shader_write_root_signature(&context, root_signature)) < 0) - { - vkd3d_free(context.data); - goto done; - } + shader_write_root_signature_header(&context); + shader_write_root_signature(&context, root_signature);
- total_size = context.position * sizeof(DWORD); + total_size = context.buffer.size; chunk_size = get_chunk_offset(&context); - context.data[context.total_size_position] = total_size; - context.data[context.chunk_position - 1] = chunk_size; + vkd3d_set_u32(&context.buffer, context.total_size_position, total_size); + vkd3d_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) + vkd3d_set_u32(&context.buffer, (i + 1) * sizeof(uint32_t), checksum[i]);
- ret = VKD3D_OK; + if (!(ret = context.buffer.status)) + ret = context.status;
done: vkd3d_shader_message_context_trace_messages(&context.message_context);