[PATCH vkd3d 4/5] vkd3d-shader: Use struct vkd3d_bytecode_buffer in vkd3d_shader_serialize_root_signature().

Zebediah Figura zfigura at codeweavers.com
Tue Jun 29 13:00:29 CDT 2021


Signed-off-by: Zebediah Figura <zfigura at 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);
-- 
2.32.0




More information about the wine-devel mailing list