Wine-devel
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
July 2020
- 75 participants
- 841 discussions
[PATCH vkd3d 5/5] vkd3d-shader: Report error messages from vkd3d_shader_serialize_root_signature().
by Henri Verbeet 30 Jul '20
by Henri Verbeet 30 Jul '20
30 Jul '20
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
include/vkd3d_shader.h | 6 +-
libs/vkd3d-shader/dxbc.c | 221 +++++++++++++++++++++----------
libs/vkd3d-shader/vkd3d_shader_private.h | 21 ++-
libs/vkd3d/vkd3d_main.c | 26 +++-
tests/vkd3d_shader_api.c | 2 +-
5 files changed, 192 insertions(+), 84 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 8ee6724..140744c 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -756,9 +756,8 @@ int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_versioned_root_signature_desc *root_signature, char **messages);
void vkd3d_shader_free_root_signature(struct vkd3d_shader_versioned_root_signature_desc *root_signature);
-/* FIXME: Add support for returning error messages (ID3DBlob). */
int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_root_signature_desc *root_signature,
- struct vkd3d_shader_code *dxbc);
+ struct vkd3d_shader_code *dxbc, char **messages);
int vkd3d_shader_convert_root_signature(struct vkd3d_shader_versioned_root_signature_desc *dst,
enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src);
@@ -788,7 +787,8 @@ typedef int (*PFN_vkd3d_shader_parse_root_signature)(const struct vkd3d_shader_c
typedef void (*PFN_vkd3d_shader_free_root_signature)(struct vkd3d_shader_versioned_root_signature_desc *root_signature);
typedef int (*PFN_vkd3d_shader_serialize_root_signature)(
- const struct vkd3d_shader_versioned_root_signature_desc *root_signature, struct vkd3d_shader_code *dxbc);
+ const struct vkd3d_shader_versioned_root_signature_desc *root_signature,
+ struct vkd3d_shader_code *dxbc, char **messages);
typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_shader_versioned_root_signature_desc *dst,
enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src);
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 28159a9..df5f6a2 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -2768,6 +2768,8 @@ static unsigned int versioned_root_signature_get_flags(const struct vkd3d_shader
struct root_signature_writer_context
{
+ struct vkd3d_shader_message_context message_context;
+
DWORD *data;
size_t position;
size_t capacity;
@@ -2813,33 +2815,38 @@ static size_t get_chunk_offset(struct root_signature_writer_context *context)
static int shader_write_root_signature_header(struct root_signature_writer_context *context)
{
if (!write_dword(context, TAG_DXBC))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
/* The checksum is computed when all data is generated. */
if (!write_dwords(context, 4, 0x00000000))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, 0x00000001))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
context->total_size_position = context->position;
if (!write_dword(context, 0xffffffff)) /* total size */
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, 1)) /* chunk count */
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
/* chunk offset */
if (!write_dword(context, (context->position + 1) * sizeof(DWORD)))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, TAG_RTS0))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, 0xffffffff)) /* chunk size */
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
context->chunk_position = context->position;
return VKD3D_OK;
+
+fail:
+ vkd3d_shader_error(&context->message_context, 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,
@@ -2851,18 +2858,23 @@ 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))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, ranges[i].descriptor_count))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, ranges[i].base_shader_register))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, ranges[i].register_space))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, ranges[i].descriptor_table_offset))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
}
return VKD3D_OK;
+
+fail:
+ vkd3d_shader_error(&context->message_context, 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,
@@ -2874,79 +2886,109 @@ 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))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, ranges[i].descriptor_count))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, ranges[i].base_shader_register))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, ranges[i].register_space))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, ranges[i].flags))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, ranges[i].descriptor_table_offset))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
}
return VKD3D_OK;
+
+fail:
+ vkd3d_shader_error(&context->message_context, 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,
const struct vkd3d_shader_root_descriptor_table *table)
{
if (!write_dword(context, table->descriptor_range_count))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, get_chunk_offset(context) + sizeof(DWORD))) /* offset */
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
return shader_write_descriptor_ranges(context, table);
+
+fail:
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ "Out of memory while writing root signature root descriptor table.");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
}
static int 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))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, get_chunk_offset(context) + sizeof(DWORD))) /* offset */
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
return shader_write_descriptor_ranges1(context, table);
+
+fail:
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ "Out of memory while writing root signature root descriptor table.");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
}
static int shader_write_root_constants(struct root_signature_writer_context *context,
const struct vkd3d_shader_root_constants *constants)
{
if (!write_dword(context, constants->shader_register))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, constants->register_space))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, constants->value_count))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
return VKD3D_OK;
+
+fail:
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ "Out of memory while writing root signature root constants.");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
}
static int shader_write_root_descriptor(struct root_signature_writer_context *context,
const struct vkd3d_shader_root_descriptor *descriptor)
{
if (!write_dword(context, descriptor->shader_register))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, descriptor->register_space))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
return VKD3D_OK;
+
+fail:
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ "Out of memory while writing root signature root descriptor.");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
}
static int shader_write_root_descriptor1(struct root_signature_writer_context *context,
const struct vkd3d_shader_root_descriptor1 *descriptor)
{
if (!write_dword(context, descriptor->shader_register))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, descriptor->register_space))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, descriptor->flags))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
return VKD3D_OK;
+
+fail:
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ "Out of memory while writing root signature root descriptor.");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
}
static int shader_write_root_parameters(struct root_signature_writer_context *context,
@@ -2961,11 +3003,11 @@ static int shader_write_root_parameters(struct root_signature_writer_context *co
for (i = 0; i < parameter_count; ++i)
{
if (!write_dword(context, versioned_root_signature_get_parameter_type(desc, i)))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, versioned_root_signature_get_parameter_shader_visibility(desc, i)))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, 0xffffffff)) /* offset */
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
}
for (i = 0; i < parameter_count; ++i)
@@ -2993,6 +3035,9 @@ static int shader_write_root_parameters(struct root_signature_writer_context *co
break;
default:
FIXME("Unrecognized type %#x.\n", versioned_root_signature_get_parameter_type(desc, i));
+ vkd3d_shader_error(&context->message_context, 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;
}
@@ -3001,6 +3046,11 @@ static int shader_write_root_parameters(struct root_signature_writer_context *co
}
return VKD3D_OK;
+
+fail:
+ vkd3d_shader_error(&context->message_context, 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,
@@ -3012,34 +3062,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))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, samplers[i].address_u))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, samplers[i].address_v))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, samplers[i].address_w))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_float(context, samplers[i].mip_lod_bias))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, samplers[i].max_anisotropy))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, samplers[i].comparison_func))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, samplers[i].border_colour))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_float(context, samplers[i].min_lod))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_float(context, samplers[i].max_lod))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, samplers[i].shader_register))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, samplers[i].register_space))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, samplers[i].shader_visibility))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
}
return VKD3D_OK;
+
+fail:
+ vkd3d_shader_error(&context->message_context, 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,
@@ -3049,30 +3104,36 @@ static int shader_write_root_signature(struct root_signature_writer_context *con
int ret;
if (!write_dword(context, desc->version))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, versioned_root_signature_get_parameter_count(desc)))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, get_chunk_offset(context) + 4 * sizeof(DWORD))) /* offset */
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, versioned_root_signature_get_static_sampler_count(desc)))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
samplers_offset_position = context->position;
if (!write_dword(context, 0xffffffff)) /* offset */
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ goto fail;
if (!write_dword(context, versioned_root_signature_get_flags(desc)))
- return VKD3D_ERROR_OUT_OF_MEMORY;
+ 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, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ "Out of memory while writing root signature.");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
}
-static int validate_descriptor_table_v_1_0(const struct vkd3d_shader_root_descriptor_table *descriptor_table)
+static int validate_descriptor_table_v_1_0(const struct vkd3d_shader_root_descriptor_table *descriptor_table,
+ struct vkd3d_shader_message_context *message_context)
{
bool have_srv_uav_cbv = false;
bool have_sampler = false;
@@ -3095,6 +3156,8 @@ static int validate_descriptor_table_v_1_0(const struct vkd3d_shader_root_descri
else
{
WARN("Invalid descriptor range type %#x.\n", r->range_type);
+ vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_RS_INVALID_DESCRIPTOR_RANGE_TYPE,
+ "Invalid root signature descriptor range type %#x.", r->range_type);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
}
@@ -3102,13 +3165,16 @@ static int validate_descriptor_table_v_1_0(const struct vkd3d_shader_root_descri
if (have_srv_uav_cbv && have_sampler)
{
WARN("Samplers cannot be mixed with CBVs/SRVs/UAVs in descriptor tables.\n");
+ vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_RS_MIXED_DESCRIPTOR_RANGE_TYPES,
+ "Encountered both CBV/SRV/UAV and sampler descriptor ranges in the same root descriptor table.");
return VKD3D_ERROR_INVALID_ARGUMENT;
}
return VKD3D_OK;
}
-static int validate_descriptor_table_v_1_1(const struct vkd3d_shader_root_descriptor_table1 *descriptor_table)
+static int validate_descriptor_table_v_1_1(const struct vkd3d_shader_root_descriptor_table1 *descriptor_table,
+ struct vkd3d_shader_message_context *message_context)
{
bool have_srv_uav_cbv = false;
bool have_sampler = false;
@@ -3131,6 +3197,8 @@ static int validate_descriptor_table_v_1_1(const struct vkd3d_shader_root_descri
else
{
WARN("Invalid descriptor range type %#x.\n", r->range_type);
+ vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_RS_INVALID_DESCRIPTOR_RANGE_TYPE,
+ "Invalid root signature descriptor range type %#x.", r->range_type);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
}
@@ -3138,13 +3206,16 @@ static int validate_descriptor_table_v_1_1(const struct vkd3d_shader_root_descri
if (have_srv_uav_cbv && have_sampler)
{
WARN("Samplers cannot be mixed with CBVs/SRVs/UAVs in descriptor tables.\n");
+ vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_RS_MIXED_DESCRIPTOR_RANGE_TYPES,
+ "Encountered both CBV/SRV/UAV and sampler descriptor ranges in the same root descriptor table.");
return VKD3D_ERROR_INVALID_ARGUMENT;
}
return VKD3D_OK;
}
-static int validate_root_signature_desc(const struct vkd3d_shader_versioned_root_signature_desc *desc)
+static int validate_root_signature_desc(const struct vkd3d_shader_versioned_root_signature_desc *desc,
+ struct vkd3d_shader_message_context *message_context)
{
int ret = VKD3D_OK;
unsigned int i;
@@ -3157,9 +3228,9 @@ static int validate_root_signature_desc(const struct vkd3d_shader_versioned_root
if (type == VKD3D_SHADER_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE)
{
if (desc->version == VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_0)
- ret = validate_descriptor_table_v_1_0(&desc->u.v_1_0.parameters[i].u.descriptor_table);
+ ret = validate_descriptor_table_v_1_0(&desc->u.v_1_0.parameters[i].u.descriptor_table, message_context);
else
- ret = validate_descriptor_table_v_1_1(&desc->u.v_1_1.parameters[i].u.descriptor_table);
+ ret = validate_descriptor_table_v_1_1(&desc->u.v_1_1.parameters[i].u.descriptor_table, message_context);
}
if (ret < 0)
@@ -3170,37 +3241,46 @@ static int validate_root_signature_desc(const struct vkd3d_shader_versioned_root
}
int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_root_signature_desc *root_signature,
- struct vkd3d_shader_code *dxbc)
+ struct vkd3d_shader_code *dxbc, char **messages)
{
struct root_signature_writer_context context;
size_t total_size, chunk_size;
uint32_t checksum[4];
int ret;
- TRACE("root_signature %p, dxbc %p.\n", root_signature, dxbc);
+ TRACE("root_signature %p, dxbc %p, messages %p.\n", root_signature, dxbc, messages);
+
+ if (messages)
+ *messages = NULL;
+
+ memset(&context, 0, sizeof(context));
+ if (!vkd3d_shader_message_context_init(&context.message_context, VKD3D_SHADER_LOG_INFO, NULL))
+ return VKD3D_ERROR;
if (root_signature->version != VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_0
&& root_signature->version != VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_1)
{
+ ret = VKD3D_ERROR_INVALID_ARGUMENT;
WARN("Root signature version %#x not supported.\n", root_signature->version);
- return VKD3D_ERROR_INVALID_ARGUMENT;
+ vkd3d_shader_error(&context.message_context, VKD3D_SHADER_ERROR_RS_INVALID_VERSION,
+ "Root signature version %#x is not supported.", root_signature->version);
+ goto done;
}
- if ((ret = validate_root_signature_desc(root_signature)) < 0)
- return ret;
+ if ((ret = validate_root_signature_desc(root_signature, &context.message_context)) < 0)
+ goto done;
memset(dxbc, 0, sizeof(*dxbc));
- memset(&context, 0, sizeof(context));
if ((ret = shader_write_root_signature_header(&context)) < 0)
{
vkd3d_free(context.data);
- return ret;
+ goto done;
}
if ((ret = shader_write_root_signature(&context, root_signature)) < 0)
{
vkd3d_free(context.data);
- return ret;
+ goto done;
}
total_size = context.position * sizeof(DWORD);
@@ -3214,7 +3294,14 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro
vkd3d_compute_dxbc_checksum(dxbc->code, dxbc->size, checksum);
memcpy((uint32_t *)dxbc->code + 1, checksum, sizeof(checksum));
- return VKD3D_OK;
+ ret = VKD3D_OK;
+
+done:
+ vkd3d_shader_message_context_trace_messages(&context.message_context);
+ if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(&context.message_context)))
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
+ vkd3d_shader_message_context_cleanup(&context.message_context);
+ return ret;
}
static void free_descriptor_ranges(const struct vkd3d_shader_root_parameter *parameters, unsigned int count)
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 3161087..d728fdc 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -61,13 +61,20 @@
enum vkd3d_shader_error
{
- VKD3D_SHADER_ERROR_DXBC_INVALID_SIZE = 1,
- VKD3D_SHADER_ERROR_DXBC_INVALID_MAGIC = 2,
- VKD3D_SHADER_ERROR_DXBC_INVALID_CHECKSUM = 3,
- VKD3D_SHADER_ERROR_DXBC_INVALID_VERSION = 4,
- VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET = 5,
- VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE = 6,
- VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF = 1000,
+ VKD3D_SHADER_ERROR_DXBC_INVALID_SIZE = 1,
+ VKD3D_SHADER_ERROR_DXBC_INVALID_MAGIC = 2,
+ VKD3D_SHADER_ERROR_DXBC_INVALID_CHECKSUM = 3,
+ VKD3D_SHADER_ERROR_DXBC_INVALID_VERSION = 4,
+ VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET = 5,
+ VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE = 6,
+
+ VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF = 1000,
+
+ VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY = 3000,
+ VKD3D_SHADER_ERROR_RS_INVALID_VERSION = 3001,
+ VKD3D_SHADER_ERROR_RS_INVALID_ROOT_PARAMETER_TYPE = 3002,
+ VKD3D_SHADER_ERROR_RS_INVALID_DESCRIPTOR_RANGE_TYPE = 3003,
+ VKD3D_SHADER_ERROR_RS_MIXED_DESCRIPTOR_RANGE_TYPES = 3004,
};
enum VKD3D_SHADER_INSTRUCTION_HANDLER
diff --git a/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/vkd3d_main.c
index 3fd9c1b..327cdf8 100644
--- a/libs/vkd3d/vkd3d_main.c
+++ b/libs/vkd3d/vkd3d_main.c
@@ -543,6 +543,7 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc,
struct vkd3d_shader_versioned_root_signature_desc vkd3d_desc;
struct vkd3d_shader_code dxbc;
struct d3d_blob *blob_object;
+ char *messages;
HRESULT hr;
int ret;
@@ -565,13 +566,19 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc,
vkd3d_desc.version = VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_0;
vkd3d_desc.u.v_1_0 = *(const struct vkd3d_shader_root_signature_desc *)desc;
- if ((ret = vkd3d_shader_serialize_root_signature(&vkd3d_desc, &dxbc)) < 0)
+ if ((ret = vkd3d_shader_serialize_root_signature(&vkd3d_desc, &dxbc, &messages)) < 0)
{
WARN("Failed to serialize root signature, vkd3d result %d.\n", ret);
- if (error_blob)
- FIXME("Ignoring error blob %p.\n", error_blob);
+ if (error_blob && messages)
+ {
+ if (FAILED(hr = d3d_blob_create(messages, strlen(messages), &blob_object)))
+ ERR("Failed to create error blob, hr %#x.\n", hr);
+ else
+ *error_blob = &blob_object->ID3DBlob_iface;
+ }
return hresult_from_vkd3d_result(ret);
}
+ vkd3d_shader_free_messages(messages);
if (FAILED(hr = d3d_blob_create((void *)dxbc.code, dxbc.size, &blob_object)))
{
@@ -591,6 +598,7 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN
const struct vkd3d_shader_versioned_root_signature_desc *vkd3d_desc;
struct vkd3d_shader_code dxbc;
struct d3d_blob *blob_object;
+ char *messages;
HRESULT hr;
int ret;
@@ -606,13 +614,19 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN
*error_blob = NULL;
vkd3d_desc = (const struct vkd3d_shader_versioned_root_signature_desc *)desc;
- if ((ret = vkd3d_shader_serialize_root_signature(vkd3d_desc, &dxbc)) < 0)
+ if ((ret = vkd3d_shader_serialize_root_signature(vkd3d_desc, &dxbc, &messages)) < 0)
{
WARN("Failed to serialize root signature, vkd3d result %d.\n", ret);
- if (error_blob)
- FIXME("Ignoring error blob %p.\n", error_blob);
+ if (error_blob && messages)
+ {
+ if (FAILED(hr = d3d_blob_create(messages, strlen(messages), &blob_object)))
+ ERR("Failed to create error blob, hr %#x.\n", hr);
+ else
+ *error_blob = &blob_object->ID3DBlob_iface;
+ }
return hresult_from_vkd3d_result(ret);
}
+ vkd3d_shader_free_messages(messages);
if (FAILED(hr = d3d_blob_create((void *)dxbc.code, dxbc.size, &blob_object)))
{
diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c
index a730c86..e25dd20 100644
--- a/tests/vkd3d_shader_api.c
+++ b/tests/vkd3d_shader_api.c
@@ -127,7 +127,7 @@ static void test_vkd3d_shader_pfns(void)
pfn_vkd3d_shader_compile = vkd3d_shader_compile;
pfn_vkd3d_shader_scan = vkd3d_shader_scan;
- rc = pfn_vkd3d_shader_serialize_root_signature(&empty_rs_desc, &dxbc);
+ rc = pfn_vkd3d_shader_serialize_root_signature(&empty_rs_desc, &dxbc, NULL);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
rc = pfn_vkd3d_shader_parse_root_signature(&dxbc, &root_signature_desc, NULL);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
--
2.11.0
1
0
[PATCH vkd3d 4/5] vkd3d-shader: Report error messages from vkd3d_shader_parse_root_signature().
by Henri Verbeet 30 Jul '20
by Henri Verbeet 30 Jul '20
30 Jul '20
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
include/vkd3d_shader.h | 4 ++--
libs/vkd3d-shader/dxbc.c | 13 ++++++++++---
libs/vkd3d-shader/vkd3d_shader_main.c | 6 ++----
libs/vkd3d-shader/vkd3d_shader_private.h | 5 +++++
libs/vkd3d/vkd3d_main.c | 4 ++--
tests/vkd3d_shader_api.c | 2 +-
6 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 0dd9829..8ee6724 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -753,7 +753,7 @@ void vkd3d_shader_free_messages(char *messages);
void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code);
int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
- struct vkd3d_shader_versioned_root_signature_desc *root_signature);
+ struct vkd3d_shader_versioned_root_signature_desc *root_signature, char **messages);
void vkd3d_shader_free_root_signature(struct vkd3d_shader_versioned_root_signature_desc *root_signature);
/* FIXME: Add support for returning error messages (ID3DBlob). */
@@ -784,7 +784,7 @@ typedef void (*PFN_vkd3d_shader_free_messages)(char *messages);
typedef void (*PFN_vkd3d_shader_free_shader_code)(struct vkd3d_shader_code *code);
typedef int (*PFN_vkd3d_shader_parse_root_signature)(const struct vkd3d_shader_code *dxbc,
- struct vkd3d_shader_versioned_root_signature_desc *root_signature);
+ struct vkd3d_shader_versioned_root_signature_desc *root_signature, char **messages);
typedef void (*PFN_vkd3d_shader_free_root_signature)(struct vkd3d_shader_versioned_root_signature_desc *root_signature);
typedef int (*PFN_vkd3d_shader_serialize_root_signature)(
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index a00dbe9..28159a9 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -2679,17 +2679,24 @@ static int rts0_handler(const char *data, DWORD data_size, DWORD tag, void *cont
}
int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
- struct vkd3d_shader_versioned_root_signature_desc *root_signature)
+ struct vkd3d_shader_versioned_root_signature_desc *root_signature, char **messages)
{
struct vkd3d_shader_message_context message_context;
int ret;
- TRACE("dxbc {%p, %zu}, root_signature %p.\n", dxbc->code, dxbc->size, root_signature);
+ TRACE("dxbc {%p, %zu}, root_signature %p, messages %p.\n", dxbc->code, dxbc->size, root_signature, messages);
memset(root_signature, 0, sizeof(*root_signature));
- if (!vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_NONE, NULL))
+ if (messages)
+ *messages = NULL;
+ if (!vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO, NULL))
return VKD3D_ERROR;
+
ret = parse_dxbc(dxbc->code, dxbc->size, &message_context, rts0_handler, root_signature);
+ vkd3d_shader_message_context_trace_messages(&message_context);
+ if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(&message_context)))
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
+
vkd3d_shader_message_context_cleanup(&message_context);
if (ret < 0)
vkd3d_shader_free_root_signature(root_signature);
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 6511a89..0785c14 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -133,15 +133,13 @@ void vkd3d_shader_message_context_cleanup(struct vkd3d_shader_message_context *c
vkd3d_string_buffer_cleanup(&context->messages);
}
-#define vkd3d_shader_message_context_trace_messages(context) \
- vkd3d_shader_message_context_trace_messages_(context, __FUNCTION__)
-static void vkd3d_shader_message_context_trace_messages_(const struct vkd3d_shader_message_context *context,
+void vkd3d_shader_message_context_trace_messages_(const struct vkd3d_shader_message_context *context,
const char *function)
{
vkd3d_string_buffer_trace_(&context->messages, function);
}
-static char *vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context)
+char *vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context)
{
char *messages;
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 79056b3..3161087 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -830,8 +830,13 @@ struct vkd3d_shader_message_context
};
void vkd3d_shader_message_context_cleanup(struct vkd3d_shader_message_context *context) DECLSPEC_HIDDEN;
+char *vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context) DECLSPEC_HIDDEN;
bool vkd3d_shader_message_context_init(struct vkd3d_shader_message_context *context,
enum vkd3d_shader_log_level log_level, const char *source_name) DECLSPEC_HIDDEN;
+void vkd3d_shader_message_context_trace_messages_(const struct vkd3d_shader_message_context *context,
+ const char *function) DECLSPEC_HIDDEN;
+#define vkd3d_shader_message_context_trace_messages(context) \
+ vkd3d_shader_message_context_trace_messages_(context, __FUNCTION__)
void vkd3d_shader_error(struct vkd3d_shader_message_context *context, enum vkd3d_shader_error error,
const char *format, ...) VKD3D_PRINTF_FUNC(3, 4) DECLSPEC_HIDDEN;
diff --git a/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/vkd3d_main.c
index 5d7c71e..3fd9c1b 100644
--- a/libs/vkd3d/vkd3d_main.c
+++ b/libs/vkd3d/vkd3d_main.c
@@ -174,7 +174,7 @@ int vkd3d_parse_root_signature_v_1_0(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_versioned_root_signature_desc desc, converted_desc;
int ret;
- if ((ret = vkd3d_shader_parse_root_signature(dxbc, &desc)) < 0)
+ if ((ret = vkd3d_shader_parse_root_signature(dxbc, &desc, NULL)) < 0)
{
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
return ret;
@@ -389,7 +389,7 @@ static HRESULT d3d12_versioned_root_signature_deserializer_init(struct d3d12_ver
deserializer->ID3D12VersionedRootSignatureDeserializer_iface.lpVtbl = &d3d12_versioned_root_signature_deserializer_vtbl;
deserializer->refcount = 1;
- if ((ret = vkd3d_shader_parse_root_signature(dxbc, &deserializer->desc.vkd3d)) < 0)
+ if ((ret = vkd3d_shader_parse_root_signature(dxbc, &deserializer->desc.vkd3d, NULL)) < 0)
{
WARN("Failed to parse root signature, vkd3d result %d.\n", ret);
return hresult_from_vkd3d_result(ret);
diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c
index 6977945..a730c86 100644
--- a/tests/vkd3d_shader_api.c
+++ b/tests/vkd3d_shader_api.c
@@ -129,7 +129,7 @@ static void test_vkd3d_shader_pfns(void)
rc = pfn_vkd3d_shader_serialize_root_signature(&empty_rs_desc, &dxbc);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
- rc = pfn_vkd3d_shader_parse_root_signature(&dxbc, &root_signature_desc);
+ rc = pfn_vkd3d_shader_parse_root_signature(&dxbc, &root_signature_desc, NULL);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
pfn_vkd3d_shader_free_root_signature(&root_signature_desc);
pfn_vkd3d_shader_free_shader_code(&dxbc);
--
2.11.0
1
0
[PATCH vkd3d 3/5] vkd3d-shader: Report error messages from vkd3d_shader_parse_input_signature().
by Henri Verbeet 30 Jul '20
by Henri Verbeet 30 Jul '20
30 Jul '20
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
include/vkd3d_shader.h | 4 ++--
libs/vkd3d-shader/dxbc.c | 8 ++------
libs/vkd3d-shader/vkd3d_shader_main.c | 21 ++++++++++++++++++---
libs/vkd3d-shader/vkd3d_shader_private.h | 2 +-
libs/vkd3d/state.c | 2 +-
tests/vkd3d_shader_api.c | 2 +-
6 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 96d0545..0dd9829 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -767,7 +767,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
- struct vkd3d_shader_signature *signature);
+ struct vkd3d_shader_signature *signature, char **messages);
struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element(
const struct vkd3d_shader_signature *signature, const char *semantic_name,
unsigned int semantic_index, unsigned int stream_index);
@@ -798,7 +798,7 @@ typedef void (*PFN_vkd3d_shader_free_scan_descriptor_info)(
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc,
- struct vkd3d_shader_signature *signature);
+ struct vkd3d_shader_signature *signature, char **messages);
typedef struct vkd3d_shader_signature_element * (*PFN_vkd3d_shader_find_signature_element)(
const struct vkd3d_shader_signature *signature, const char *semantic_name,
unsigned int semantic_index, unsigned int stream_index);
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index f738abe..a00dbe9 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -2132,17 +2132,13 @@ static int isgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
}
int shader_parse_input_signature(const void *dxbc, size_t dxbc_length,
- struct vkd3d_shader_signature *signature)
+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *signature)
{
- struct vkd3d_shader_message_context message_context;
int ret;
memset(signature, 0, sizeof(*signature));
- if (!vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_NONE, NULL))
- return VKD3D_ERROR;
- if ((ret = parse_dxbc(dxbc, dxbc_length, &message_context, isgn_handler, signature)) < 0)
+ if ((ret = parse_dxbc(dxbc, dxbc_length, message_context, isgn_handler, signature)) < 0)
ERR("Failed to parse input signature.\n");
- vkd3d_shader_message_context_cleanup(&message_context);
return ret;
}
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 5d50487..6511a89 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -971,11 +971,26 @@ void vkd3d_shader_free_root_signature(struct vkd3d_shader_versioned_root_signatu
}
int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
- struct vkd3d_shader_signature *signature)
+ struct vkd3d_shader_signature *signature, char **messages)
{
- TRACE("dxbc {%p, %zu}, signature %p.\n", dxbc->code, dxbc->size, signature);
+ struct vkd3d_shader_message_context message_context;
+ int ret;
+
+ TRACE("dxbc {%p, %zu}, signature %p, messages %p.\n", dxbc->code, dxbc->size, signature, messages);
+
+ if (messages)
+ *messages = NULL;
+ if (!vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO, NULL))
+ return VKD3D_ERROR;
- return shader_parse_input_signature(dxbc->code, dxbc->size, signature);
+ ret = shader_parse_input_signature(dxbc->code, dxbc->size, &message_context, signature);
+ vkd3d_shader_message_context_trace_messages(&message_context);
+ if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(&message_context)))
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
+
+ vkd3d_shader_message_context_cleanup(&message_context);
+
+ return ret;
}
struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element(
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index ae2f6c2..79056b3 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -840,7 +840,7 @@ int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length,
void free_shader_desc(struct vkd3d_shader_desc *desc) DECLSPEC_HIDDEN;
int shader_parse_input_signature(const void *dxbc, size_t dxbc_length,
- struct vkd3d_shader_signature *signature) DECLSPEC_HIDDEN;
+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *signature) DECLSPEC_HIDDEN;
struct vkd3d_dxbc_compiler;
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 93f22ce..449f242 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -2316,7 +2316,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
switch (shader_stages[i].stage)
{
case VK_SHADER_STAGE_VERTEX_BIT:
- if ((ret = vkd3d_shader_parse_input_signature(&dxbc, &input_signature)) < 0)
+ if ((ret = vkd3d_shader_parse_input_signature(&dxbc, &input_signature, NULL)) < 0)
{
hr = hresult_from_vkd3d_result(ret);
goto fail;
diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c
index be63b39..6977945 100644
--- a/tests/vkd3d_shader_api.c
+++ b/tests/vkd3d_shader_api.c
@@ -134,7 +134,7 @@ static void test_vkd3d_shader_pfns(void)
pfn_vkd3d_shader_free_root_signature(&root_signature_desc);
pfn_vkd3d_shader_free_shader_code(&dxbc);
- rc = pfn_vkd3d_shader_parse_input_signature(&vs, &signature);
+ rc = pfn_vkd3d_shader_parse_input_signature(&vs, &signature, NULL);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
element = pfn_vkd3d_shader_find_signature_element(&signature, "position", 0, 0);
ok(element, "Could not find shader signature element.\n");
--
2.11.0
1
0
[PATCH vkd3d 2/5] vkd3d-shader: Pass a vkd3d_shader_compile_info structure to vkd3d_shader_scan_dxbc().
by Henri Verbeet 30 Jul '20
by Henri Verbeet 30 Jul '20
30 Jul '20
In order to allow it to handle different source types.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
include/vkd3d_shader.h | 18 +++---
libs/vkd3d-shader/spirv.c | 33 ++---------
libs/vkd3d-shader/vkd3d_shader.map | 4 +-
libs/vkd3d-shader/vkd3d_shader_main.c | 97 +++++++++++++++++++-------------
libs/vkd3d-shader/vkd3d_shader_private.h | 23 +++++++-
libs/vkd3d/state.c | 41 ++++++++++----
tests/vkd3d_shader_api.c | 20 +++++--
7 files changed, 141 insertions(+), 95 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 69a98e0..96d0545 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -32,7 +32,7 @@ enum vkd3d_shader_structure_type
/* 1.2 */
VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO,
- VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO,
+ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_DOMAIN_SHADER_TARGET_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO,
@@ -653,10 +653,11 @@ struct vkd3d_shader_descriptor_info
unsigned int count;
};
-struct vkd3d_shader_scan_info
+/* Extends vkd3d_shader_compile_info. */
+struct vkd3d_shader_scan_descriptor_info
{
enum vkd3d_shader_structure_type type;
- void *next;
+ const void *next;
struct vkd3d_shader_descriptor_info *descriptors;
unsigned int descriptor_count;
@@ -762,9 +763,8 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro
int vkd3d_shader_convert_root_signature(struct vkd3d_shader_versioned_root_signature_desc *dst,
enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src);
-int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
- struct vkd3d_shader_scan_info *scan_info, char **messages);
-void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info);
+int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages);
+void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_signature *signature);
@@ -793,9 +793,9 @@ typedef int (*PFN_vkd3d_shader_serialize_root_signature)(
typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_shader_versioned_root_signature_desc *dst,
enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src);
-typedef int (*PFN_vkd3d_shader_scan_dxbc)(const struct vkd3d_shader_code *dxbc,
- struct vkd3d_shader_scan_info *scan_info, char **messages);
-typedef void (*PFN_vkd3d_shader_free_scan_info)(struct vkd3d_shader_scan_info *scan_info);
+typedef int (*PFN_vkd3d_shader_scan)(const struct vkd3d_shader_compile_info *compile_info, char **messages);
+typedef void (*PFN_vkd3d_shader_free_scan_descriptor_info)(
+ struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_signature *signature);
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 3ece044..86ee263 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -111,27 +111,6 @@ static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv,
#endif /* HAVE_SPIRV_TOOLS */
-struct vkd3d_struct
-{
- enum vkd3d_shader_structure_type type;
- const void *next;
-};
-
-#define vkd3d_find_struct(c, t) vkd3d_find_struct_(c, VKD3D_SHADER_STRUCTURE_TYPE_##t)
-static const void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
- enum vkd3d_shader_structure_type type)
-{
- while (chain)
- {
- if (chain->type == type)
- return chain;
-
- chain = chain->next;
- }
-
- return NULL;
-}
-
static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval,
unsigned int index)
{
@@ -2103,7 +2082,7 @@ struct vkd3d_dxbc_compiler
uint32_t binding_idx;
- const struct vkd3d_shader_scan_info *scan_info;
+ const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
unsigned int input_control_point_count;
unsigned int output_control_point_count;
bool use_vocp;
@@ -2134,7 +2113,7 @@ static const char *vkd3d_dxbc_compiler_get_entry_point_name(const struct vkd3d_d
struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version,
const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info,
- const struct vkd3d_shader_scan_info *scan_info)
+ const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info)
{
const struct vkd3d_shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature;
const struct vkd3d_shader_signature *output_signature = &shader_desc->output_signature;
@@ -2216,7 +2195,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
}
}
- compiler->scan_info = scan_info;
+ compiler->scan_descriptor_info = scan_descriptor_info;
vkd3d_dxbc_compiler_emit_initial_declarations(compiler);
@@ -5177,13 +5156,13 @@ static const struct vkd3d_shader_descriptor_info *vkd3d_dxbc_compiler_get_descri
struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_descriptor_type type,
unsigned int register_space, unsigned int register_index)
{
- const struct vkd3d_shader_scan_info *scan_info = compiler->scan_info;
+ const struct vkd3d_shader_scan_descriptor_info *descriptor_info = compiler->scan_descriptor_info;
const struct vkd3d_shader_descriptor_info *d;
unsigned int i;
- for (i = 0; i < scan_info->descriptor_count; ++i)
+ for (i = 0; i < descriptor_info->descriptor_count; ++i)
{
- d = &scan_info->descriptors[i];
+ d = &descriptor_info->descriptors[i];
if (d->type == type && d->register_space == register_space && d->register_index == register_index)
return d;
}
diff --git a/libs/vkd3d-shader/vkd3d_shader.map b/libs/vkd3d-shader/vkd3d_shader.map
index 55b50ad..9c9f0a5 100644
--- a/libs/vkd3d-shader/vkd3d_shader.map
+++ b/libs/vkd3d-shader/vkd3d_shader.map
@@ -6,12 +6,12 @@ global:
vkd3d_shader_find_signature_element;
vkd3d_shader_free_messages;
vkd3d_shader_free_root_signature;
- vkd3d_shader_free_scan_info;
+ vkd3d_shader_free_scan_descriptor_info;
vkd3d_shader_free_shader_code;
vkd3d_shader_free_shader_signature;
vkd3d_shader_parse_input_signature;
vkd3d_shader_parse_root_signature;
- vkd3d_shader_scan_dxbc;
+ vkd3d_shader_scan;
vkd3d_shader_serialize_root_signature;
local: *;
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index cf8b289..5d50487 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -285,10 +285,11 @@ void vkd3d_shader_free_messages(char *messages)
int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, char **messages)
{
+ struct vkd3d_shader_scan_descriptor_info scan_descriptor_info;
struct vkd3d_shader_message_context message_context;
struct vkd3d_shader_instruction instruction;
+ struct vkd3d_shader_compile_info scan_info;
struct vkd3d_dxbc_compiler *spirv_compiler;
- struct vkd3d_shader_scan_info scan_info;
struct vkd3d_shader_parser parser;
int ret;
@@ -300,9 +301,12 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
if ((ret = vkd3d_shader_validate_compile_info(compile_info)) < 0)
return ret;
- scan_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO;
- scan_info.next = NULL;
- if ((ret = vkd3d_shader_scan_dxbc(&compile_info->source, &scan_info, messages)) < 0)
+ scan_info = *compile_info;
+ scan_descriptor_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
+ scan_descriptor_info.next = scan_info.next;
+ scan_info.next = &scan_descriptor_info;
+
+ if ((ret = vkd3d_shader_scan(&scan_info, messages)) < 0)
return ret;
if (!vkd3d_shader_message_context_init(&message_context, compile_info->log_level, compile_info->source_name))
@@ -317,15 +321,19 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
}
vkd3d_shader_message_context_cleanup(&message_context);
if (ret < 0)
+ {
+ vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return ret;
+ }
vkd3d_shader_dump_shader(parser.shader_version.type, &compile_info->source);
if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version,
- &parser.shader_desc, compile_info, &scan_info)))
+ &parser.shader_desc, compile_info, &scan_descriptor_info)))
{
ERR("Failed to create DXBC compiler.\n");
vkd3d_shader_parser_destroy(&parser);
+ vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return VKD3D_ERROR;
}
@@ -336,9 +344,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
if (instruction.handler_idx == VKD3DSIH_INVALID)
{
WARN("Encountered unrecognized or invalid instruction.\n");
- vkd3d_dxbc_compiler_destroy(spirv_compiler);
- vkd3d_shader_parser_destroy(&parser);
- return VKD3D_ERROR_INVALID_ARGUMENT;
+ ret = VKD3D_ERROR_INVALID_SHADER;
+ break;
}
if ((ret = vkd3d_dxbc_compiler_handle_instruction(spirv_compiler, &instruction)) < 0)
@@ -350,13 +357,13 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
vkd3d_dxbc_compiler_destroy(spirv_compiler);
vkd3d_shader_parser_destroy(&parser);
- vkd3d_shader_free_scan_info(&scan_info);
+ vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info);
return ret;
}
struct vkd3d_shader_scan_context
{
- struct vkd3d_shader_scan_info *scan_info;
+ struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
size_t descriptors_size;
struct vkd3d_shader_message_context message_context;
@@ -385,11 +392,12 @@ struct vkd3d_shader_scan_context
};
static bool vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *context,
- struct vkd3d_shader_scan_info *scan_info)
+ struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info,
+ enum vkd3d_shader_log_level log_level, const char *source_name)
{
memset(context, 0, sizeof(*context));
- context->scan_info = scan_info;
- return vkd3d_shader_message_context_init(&context->message_context, VKD3D_SHADER_LOG_INFO, NULL);
+ context->scan_descriptor_info = scan_descriptor_info;
+ return vkd3d_shader_message_context_init(&context->message_context, log_level, source_name);
}
static void vkd3d_shader_scan_context_cleanup(struct vkd3d_shader_scan_context *context)
@@ -471,7 +479,7 @@ static struct vkd3d_shader_descriptor_info *vkd3d_shader_scan_get_uav_descriptor
for (i = 0; i < context->uav_range_count; ++i)
{
if (context->uav_ranges[i].id == range_id)
- return &context->scan_info->descriptors[context->uav_ranges[i].descriptor_idx];
+ return &context->scan_descriptor_info->descriptors[context->uav_ranges[i].descriptor_idx];
}
return NULL;
@@ -492,7 +500,7 @@ static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *
{
struct vkd3d_shader_descriptor_info *d;
- if (!context->scan_info)
+ if (!context->scan_descriptor_info)
return;
d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset);
@@ -511,7 +519,7 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_contex
{
struct vkd3d_shader_descriptor_info *d;
- if (!context->scan_info)
+ if (!context->scan_descriptor_info)
return;
d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset);
@@ -523,17 +531,17 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c
enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type,
unsigned int flags)
{
- struct vkd3d_shader_scan_info *scan_info = context->scan_info;
+ struct vkd3d_shader_scan_descriptor_info *info = context->scan_descriptor_info;
struct vkd3d_shader_descriptor_info *d;
- if (!vkd3d_array_reserve((void **)&scan_info->descriptors, &context->descriptors_size,
- scan_info->descriptor_count + 1, sizeof(*scan_info->descriptors)))
+ if (!vkd3d_array_reserve((void **)&info->descriptors, &context->descriptors_size,
+ info->descriptor_count + 1, sizeof(*info->descriptors)))
{
ERR("Failed to allocate descriptor info.\n");
return false;
}
- d = &scan_info->descriptors[scan_info->descriptor_count];
+ d = &info->descriptors[info->descriptor_count];
d->type = type;
d->register_space = register_space;
d->register_index = register_index;
@@ -541,7 +549,7 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c
d->resource_data_type = resource_data_type;
d->flags = flags;
d->count = 1;
- ++scan_info->descriptor_count;
+ ++info->descriptor_count;
return true;
}
@@ -568,7 +576,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc
{
const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
- if (!context->scan_info)
+ if (!context->scan_descriptor_info)
return;
vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, cb->register_space,
@@ -581,7 +589,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte
const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler;
unsigned int flags;
- if (!context->scan_info)
+ if (!context->scan_descriptor_info)
return;
if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE)
@@ -598,7 +606,7 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
{
enum vkd3d_shader_descriptor_type type;
- if (!context->scan_info)
+ if (!context->scan_descriptor_info)
return;
if (resource->reg.reg.type == VKD3DSPR_UAV)
@@ -609,7 +617,7 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
resource->register_index, resource_type, resource_data_type, 0);
if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
vkd3d_shader_scan_add_uav_range(context, resource->reg.reg.idx[0].offset,
- context->scan_info->descriptor_count - 1);
+ context->scan_descriptor_info->descriptor_count - 1);
}
static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context,
@@ -811,31 +819,44 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
return VKD3D_OK;
}
-int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
- struct vkd3d_shader_scan_info *scan_info, char **messages)
+int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages)
{
+ struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info;
struct vkd3d_shader_message_context *message_context;
struct vkd3d_shader_instruction instruction;
struct vkd3d_shader_scan_context context;
struct vkd3d_shader_parser parser;
int ret;
- TRACE("dxbc {%p, %zu}, scan_info %p, messages %p.\n", dxbc->code, dxbc->size, scan_info, messages);
+ TRACE("compile_info %p, messages %p.\n", compile_info, messages);
if (messages)
*messages = NULL;
- if (scan_info->type != VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO)
+ if (compile_info->type != VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO)
{
- WARN("Invalid structure type %#x.\n", scan_info->type);
+ WARN("Invalid structure type %#x.\n", compile_info->type);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- if (!vkd3d_shader_scan_context_init(&context, scan_info))
+ if (compile_info->source_type != VKD3D_SHADER_SOURCE_DXBC_TPF)
+ {
+ WARN("Unsupported source type %#x.\n", compile_info->source_type);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+
+ if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO)))
+ {
+ scan_descriptor_info->descriptors = NULL;
+ scan_descriptor_info->descriptor_count = 0;
+ }
+
+ if (!vkd3d_shader_scan_context_init(&context, scan_descriptor_info,
+ compile_info->log_level, compile_info->source_name))
return VKD3D_ERROR;
message_context = &context.message_context;
- if ((ret = vkd3d_shader_parser_init(&parser, dxbc, message_context)) < 0)
+ if ((ret = vkd3d_shader_parser_init(&parser, &compile_info->source, message_context)) < 0)
{
vkd3d_shader_message_context_trace_messages(message_context);
if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(message_context)))
@@ -847,8 +868,6 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
if (TRACE_ON())
vkd3d_shader_trace(parser.data);
- memset(scan_info, 0, sizeof(*scan_info));
-
message_context->line = 2; /* Line 1 is the version token. */
message_context->column = 1;
while (!shader_sm4_is_end(parser.data, &parser.ptr))
@@ -858,14 +877,14 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
if (instruction.handler_idx == VKD3DSIH_INVALID)
{
WARN("Encountered unrecognized or invalid instruction.\n");
- vkd3d_shader_free_scan_info(scan_info);
+ vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
ret = VKD3D_ERROR_INVALID_SHADER;
goto done;
}
if ((ret = vkd3d_shader_scan_instruction(&context, &instruction)) < 0)
{
- vkd3d_shader_free_scan_info(scan_info);
+ vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
goto done;
}
++message_context->line;
@@ -882,12 +901,12 @@ done:
return ret;
}
-void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info)
+void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info)
{
- if (!scan_info)
+ if (!scan_descriptor_info)
return;
- vkd3d_free(scan_info->descriptors);
+ vkd3d_free(scan_descriptor_info->descriptors);
}
void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code)
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 4fa17d6..ae2f6c2 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -846,7 +846,7 @@ struct vkd3d_dxbc_compiler;
struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version,
const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info,
- const struct vkd3d_shader_scan_info *scan_info) DECLSPEC_HIDDEN;
+ const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info) DECLSPEC_HIDDEN;
int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction) DECLSPEC_HIDDEN;
int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
@@ -941,6 +941,27 @@ static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned
return compacted_swizzle;
}
+struct vkd3d_struct
+{
+ enum vkd3d_shader_structure_type type;
+ const void *next;
+};
+
+#define vkd3d_find_struct(c, t) vkd3d_find_struct_(c, VKD3D_SHADER_STRUCTURE_TYPE_##t)
+static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
+ enum vkd3d_shader_structure_type type)
+{
+ while (chain)
+ {
+ if (chain->type == type)
+ return (void *)chain;
+
+ chain = chain->next;
+ }
+
+ return NULL;
+}
+
#define VKD3D_DXBC_MAX_SOURCE_COUNT 6
#define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t))
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 316132b..93f22ce 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -1376,6 +1376,25 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
return S_OK;
}
+static int vkd3d_scan_dxbc(const D3D12_SHADER_BYTECODE *code,
+ struct vkd3d_shader_scan_descriptor_info *descriptor_info)
+{
+ struct vkd3d_shader_compile_info compile_info;
+
+ compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
+ compile_info.next = descriptor_info;
+ compile_info.source.code = code->pShaderBytecode;
+ compile_info.source.size = code->BytecodeLength;
+ compile_info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
+ compile_info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
+ compile_info.options = NULL;
+ compile_info.option_count = 0;
+ compile_info.log_level = VKD3D_SHADER_LOG_NONE;
+ compile_info.source_name = NULL;
+
+ return vkd3d_shader_scan(&compile_info, NULL);
+}
+
static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
const D3D12_SHADER_BYTECODE *code, const struct vkd3d_shader_interface_info *shader_interface,
VkPipelineLayout vk_pipeline_layout, VkPipeline *vk_pipeline)
@@ -1409,7 +1428,7 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipeline_state *state,
struct d3d12_device *device, const struct d3d12_root_signature *root_signature,
- const struct vkd3d_shader_scan_info *shader_info)
+ const struct vkd3d_shader_scan_descriptor_info *shader_info)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct vkd3d_descriptor_set_context context;
@@ -1503,11 +1522,10 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+ struct vkd3d_shader_scan_descriptor_info shader_info;
struct vkd3d_shader_interface_info shader_interface;
const struct d3d12_root_signature *root_signature;
- struct vkd3d_shader_scan_info shader_info;
VkPipelineLayout vk_pipeline_layout;
- struct vkd3d_shader_code dxbc;
HRESULT hr;
int ret;
@@ -1525,11 +1543,9 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
return E_INVALIDARG;
}
- dxbc.code = desc->CS.pShaderBytecode;
- dxbc.size = desc->CS.BytecodeLength;
- shader_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO;
+ shader_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
shader_info.next = NULL;
- if ((ret = vkd3d_shader_scan_dxbc(&dxbc, &shader_info, NULL)) < 0)
+ if ((ret = vkd3d_scan_dxbc(&desc->CS, &shader_info)) < 0)
{
WARN("Failed to scan shader bytecode, vkd3d result %d.\n", ret);
return hresult_from_vkd3d_result(ret);
@@ -1541,7 +1557,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
WARN("Failed to create descriptor set layout for UAV counters, hr %#x.\n", hr);
return hr;
}
- vkd3d_shader_free_scan_info(&shader_info);
+ vkd3d_shader_free_scan_descriptor_info(&shader_info);
shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
shader_interface.next = NULL;
@@ -2266,14 +2282,17 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
for (i = 0; i < ARRAY_SIZE(shader_stages); ++i)
{
+ struct vkd3d_shader_scan_descriptor_info shader_info =
+ {
+ .type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO,
+ };
const D3D12_SHADER_BYTECODE *b = (const void *)((uintptr_t)desc + shader_stages[i].offset);
- struct vkd3d_shader_scan_info shader_info = {VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO};
const struct vkd3d_shader_code dxbc = {b->pShaderBytecode, b->BytecodeLength};
if (!b->pShaderBytecode)
continue;
- if ((ret = vkd3d_shader_scan_dxbc(&dxbc, &shader_info, NULL)) < 0)
+ if ((ret = vkd3d_scan_dxbc(b, &shader_info)) < 0)
{
WARN("Failed to scan shader bytecode, stage %#x, vkd3d result %d.\n",
shader_stages[i].stage, ret);
@@ -2291,7 +2310,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
break;
}
}
- vkd3d_shader_free_scan_info(&shader_info);
+ vkd3d_shader_free_scan_descriptor_info(&shader_info);
target_info = NULL;
switch (shader_stages[i].stage)
diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c
index 079559a..be63b39 100644
--- a/tests/vkd3d_shader_api.c
+++ b/tests/vkd3d_shader_api.c
@@ -68,10 +68,14 @@ static void test_invalid_shaders(void)
rc = vkd3d_shader_compile(&info, &spirv, NULL);
ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
+
+ rc = vkd3d_shader_scan(&info, NULL);
+ ok(rc == VKD3D_ERROR_INVALID_SHADER, "Got unexpected error code %d.\n", rc);
}
static void test_vkd3d_shader_pfns(void)
{
+ PFN_vkd3d_shader_free_scan_descriptor_info pfn_vkd3d_shader_free_scan_descriptor_info;
PFN_vkd3d_shader_serialize_root_signature pfn_vkd3d_shader_serialize_root_signature;
PFN_vkd3d_shader_find_signature_element pfn_vkd3d_shader_find_signature_element;
PFN_vkd3d_shader_free_shader_signature pfn_vkd3d_shader_free_shader_signature;
@@ -79,13 +83,13 @@ static void test_vkd3d_shader_pfns(void)
PFN_vkd3d_shader_parse_root_signature pfn_vkd3d_shader_parse_root_signature;
PFN_vkd3d_shader_free_root_signature pfn_vkd3d_shader_free_root_signature;
PFN_vkd3d_shader_free_shader_code pfn_vkd3d_shader_free_shader_code;
- PFN_vkd3d_shader_scan_dxbc pfn_vkd3d_shader_scan_dxbc;
PFN_vkd3d_shader_compile pfn_vkd3d_shader_compile;
+ PFN_vkd3d_shader_scan pfn_vkd3d_shader_scan;
struct vkd3d_shader_versioned_root_signature_desc root_signature_desc;
+ struct vkd3d_shader_scan_descriptor_info descriptor_info;
struct vkd3d_shader_signature_element *element;
struct vkd3d_shader_compile_info compile_info;
- struct vkd3d_shader_scan_info scan_info;
struct vkd3d_shader_signature signature;
struct vkd3d_shader_code dxbc, spirv;
int rc;
@@ -112,6 +116,7 @@ static void test_vkd3d_shader_pfns(void)
};
static const struct vkd3d_shader_code vs = {vs_code, sizeof(vs_code)};
+ pfn_vkd3d_shader_free_scan_descriptor_info = vkd3d_shader_free_scan_descriptor_info;
pfn_vkd3d_shader_serialize_root_signature = vkd3d_shader_serialize_root_signature;
pfn_vkd3d_shader_find_signature_element = vkd3d_shader_find_signature_element;
pfn_vkd3d_shader_free_shader_signature = vkd3d_shader_free_shader_signature;
@@ -119,8 +124,8 @@ static void test_vkd3d_shader_pfns(void)
pfn_vkd3d_shader_parse_root_signature = vkd3d_shader_parse_root_signature;
pfn_vkd3d_shader_free_root_signature = vkd3d_shader_free_root_signature;
pfn_vkd3d_shader_free_shader_code = vkd3d_shader_free_shader_code;
- pfn_vkd3d_shader_scan_dxbc = vkd3d_shader_scan_dxbc;
pfn_vkd3d_shader_compile = vkd3d_shader_compile;
+ pfn_vkd3d_shader_scan = vkd3d_shader_scan;
rc = pfn_vkd3d_shader_serialize_root_signature(&empty_rs_desc, &dxbc);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
@@ -149,10 +154,13 @@ static void test_vkd3d_shader_pfns(void)
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
pfn_vkd3d_shader_free_shader_code(&spirv);
- memset(&scan_info, 0, sizeof(scan_info));
- scan_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO;
- rc = pfn_vkd3d_shader_scan_dxbc(&vs, &scan_info, NULL);
+ memset(&descriptor_info, 0, sizeof(descriptor_info));
+ descriptor_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
+ compile_info.next = &descriptor_info;
+
+ rc = pfn_vkd3d_shader_scan(&compile_info, NULL);
ok(rc == VKD3D_OK, "Got unexpected error code %d.\n", rc);
+ pfn_vkd3d_shader_free_scan_descriptor_info(&descriptor_info);
}
START_TEST(vkd3d_shader_api)
--
2.11.0
1
0
[PATCH vkd3d 1/5] vkd3d-shader: Validate control flow instructions in vkd3d_shader_scan_dxbc().
by Henri Verbeet 30 Jul '20
by Henri Verbeet 30 Jul '20
30 Jul '20
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
libs/vkd3d-shader/vkd3d_shader_main.c | 276 +++++++++++++++++++++++++++++--
libs/vkd3d-shader/vkd3d_shader_private.h | 1 +
2 files changed, 259 insertions(+), 18 deletions(-)
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 5597992..cf8b289 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -359,6 +359,22 @@ struct vkd3d_shader_scan_context
struct vkd3d_shader_scan_info *scan_info;
size_t descriptors_size;
+ struct vkd3d_shader_message_context message_context;
+
+ struct vkd3d_shader_cf_info
+ {
+ enum
+ {
+ VKD3D_SHADER_BLOCK_IF,
+ VKD3D_SHADER_BLOCK_LOOP,
+ VKD3D_SHADER_BLOCK_SWITCH,
+ } type;
+ bool inside_block;
+ bool has_default;
+ } *cf_info;
+ size_t cf_info_size;
+ size_t cf_info_count;
+
struct
{
unsigned int id;
@@ -368,6 +384,85 @@ struct vkd3d_shader_scan_context
size_t uav_range_count;
};
+static bool vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *context,
+ struct vkd3d_shader_scan_info *scan_info)
+{
+ memset(context, 0, sizeof(*context));
+ context->scan_info = scan_info;
+ return vkd3d_shader_message_context_init(&context->message_context, VKD3D_SHADER_LOG_INFO, NULL);
+}
+
+static void vkd3d_shader_scan_context_cleanup(struct vkd3d_shader_scan_context *context)
+{
+ vkd3d_free(context->uav_ranges);
+ vkd3d_free(context->cf_info);
+ vkd3d_shader_message_context_cleanup(&context->message_context);
+}
+
+static struct vkd3d_shader_cf_info *vkd3d_shader_scan_get_current_cf_info(struct vkd3d_shader_scan_context *context)
+{
+ if (!context->cf_info_count)
+ return NULL;
+ return &context->cf_info[context->cf_info_count - 1];
+}
+
+static struct vkd3d_shader_cf_info *vkd3d_shader_scan_push_cf_info(struct vkd3d_shader_scan_context *context)
+{
+ struct vkd3d_shader_cf_info *cf_info;
+
+ if (!vkd3d_array_reserve((void **)&context->cf_info, &context->cf_info_size,
+ context->cf_info_count + 1, sizeof(*context->cf_info)))
+ {
+ ERR("Failed to allocate UAV range.\n");
+ return false;
+ }
+
+ cf_info = &context->cf_info[context->cf_info_count++];
+ memset(cf_info, 0, sizeof(*cf_info));
+
+ return cf_info;
+}
+
+static void vkd3d_shader_scan_pop_cf_info(struct vkd3d_shader_scan_context *context)
+{
+ assert(context->cf_info_count);
+
+ --context->cf_info_count;
+}
+
+static struct vkd3d_shader_cf_info *vkd3d_shader_scan_find_innermost_breakable_cf_info(
+ struct vkd3d_shader_scan_context *context)
+{
+ size_t count = context->cf_info_count;
+ struct vkd3d_shader_cf_info *cf_info;
+
+ while (count)
+ {
+ cf_info = &context->cf_info[--count];
+ if (cf_info->type == VKD3D_SHADER_BLOCK_LOOP
+ || cf_info->type == VKD3D_SHADER_BLOCK_SWITCH)
+ return cf_info;
+ }
+
+ return NULL;
+}
+
+static struct vkd3d_shader_cf_info *vkd3d_shader_scan_find_innermost_loop_cf_info(
+ struct vkd3d_shader_scan_context *context)
+{
+ size_t count = context->cf_info_count;
+ struct vkd3d_shader_cf_info *cf_info;
+
+ while (count)
+ {
+ cf_info = &context->cf_info[--count];
+ if (cf_info->type == VKD3D_SHADER_BLOCK_LOOP)
+ return cf_info;
+ }
+
+ return NULL;
+}
+
static struct vkd3d_shader_descriptor_info *vkd3d_shader_scan_get_uav_descriptor_info(
const struct vkd3d_shader_scan_context *context, unsigned int range_id)
{
@@ -397,6 +492,9 @@ static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *
{
struct vkd3d_shader_descriptor_info *d;
+ if (!context->scan_info)
+ return;
+
d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset);
d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ;
}
@@ -413,6 +511,9 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_contex
{
struct vkd3d_shader_descriptor_info *d;
+ if (!context->scan_info)
+ return;
+
d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset);
d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER;
}
@@ -467,6 +568,9 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc
{
const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
+ if (!context->scan_info)
+ return;
+
vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, cb->register_space,
cb->register_index, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0);
}
@@ -477,6 +581,9 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte
const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler;
unsigned int flags;
+ if (!context->scan_info)
+ return;
+
if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE)
flags = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE;
else
@@ -491,6 +598,9 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
{
enum vkd3d_shader_descriptor_type type;
+ if (!context->scan_info)
+ return;
+
if (resource->reg.reg.type == VKD3DSPR_UAV)
type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
else
@@ -534,9 +644,10 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca
semantic->resource_type, resource_data_type);
}
-static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context,
+static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_instruction *instruction)
{
+ struct vkd3d_shader_cf_info *cf_info;
unsigned int i;
switch (instruction->handler_idx)
@@ -561,6 +672,121 @@ static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *cont
vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource,
VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT);
break;
+ case VKD3DSIH_IF:
+ cf_info = vkd3d_shader_scan_push_cf_info(context);
+ cf_info->type = VKD3D_SHADER_BLOCK_IF;
+ cf_info->inside_block = true;
+ break;
+ case VKD3DSIH_ELSE:
+ if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_IF)
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘else’ instruction without corresponding ‘if’ block.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ cf_info->inside_block = true;
+ break;
+ case VKD3DSIH_ENDIF:
+ if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_IF)
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘endif’ instruction without corresponding ‘if’ block.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ vkd3d_shader_scan_pop_cf_info(context);
+ break;
+ case VKD3DSIH_LOOP:
+ cf_info = vkd3d_shader_scan_push_cf_info(context);
+ cf_info->type = VKD3D_SHADER_BLOCK_LOOP;
+ break;
+ case VKD3DSIH_ENDLOOP:
+ if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_LOOP)
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘endloop’ instruction without corresponding ‘loop’ block.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ vkd3d_shader_scan_pop_cf_info(context);
+ break;
+ case VKD3DSIH_SWITCH:
+ cf_info = vkd3d_shader_scan_push_cf_info(context);
+ cf_info->type = VKD3D_SHADER_BLOCK_SWITCH;
+ break;
+ case VKD3DSIH_ENDSWITCH:
+ if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context))
+ || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH || cf_info->inside_block)
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘endswitch’ instruction without corresponding ‘switch’ block.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ vkd3d_shader_scan_pop_cf_info(context);
+ break;
+ case VKD3DSIH_CASE:
+ if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context))
+ || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH)
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘case’ instruction outside switch block.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ cf_info->inside_block = true;
+ break;
+ case VKD3DSIH_DEFAULT:
+ if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context))
+ || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH)
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘default’ instruction outside switch block.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ if (cf_info->has_default)
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered duplicate ‘default’ instruction inside the current switch block.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ cf_info->inside_block = true;
+ cf_info->has_default = true;
+ break;
+ case VKD3DSIH_BREAK:
+ if (!(cf_info = vkd3d_shader_scan_find_innermost_breakable_cf_info(context)))
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘break’ instruction outside breakable block.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ cf_info->inside_block = false;
+ break;
+ case VKD3DSIH_BREAKP:
+ if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context)))
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘breakp’ instruction outside loop.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ break;
+ case VKD3DSIH_CONTINUE:
+ if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context)))
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘continue’ instruction outside loop.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ cf_info->inside_block = false;
+ break;
+ case VKD3DSIH_CONTINUEP:
+ if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context)))
+ {
+ vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
+ "Encountered ‘continue’ instruction outside loop.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ break;
+ case VKD3DSIH_RET:
+ if (context->cf_info_count)
+ context->cf_info[context->cf_info_count - 1].inside_block = false;
+ break;
default:
break;
}
@@ -581,12 +807,14 @@ static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *cont
if (vkd3d_shader_instruction_is_uav_counter(instruction))
vkd3d_shader_scan_record_uav_counter(context, &instruction->src[0].reg);
+
+ return VKD3D_OK;
}
int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_scan_info *scan_info, char **messages)
{
- struct vkd3d_shader_message_context message_context;
+ struct vkd3d_shader_message_context *message_context;
struct vkd3d_shader_instruction instruction;
struct vkd3d_shader_scan_context context;
struct vkd3d_shader_parser parser;
@@ -603,24 +831,26 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- if (!vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO, NULL))
+ if (!vkd3d_shader_scan_context_init(&context, scan_info))
return VKD3D_ERROR;
- ret = vkd3d_shader_parser_init(&parser, dxbc, &message_context);
- vkd3d_shader_message_context_trace_messages(&message_context);
- if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(&message_context)))
- ret = VKD3D_ERROR_OUT_OF_MEMORY;
- vkd3d_shader_message_context_cleanup(&message_context);
- if (ret < 0)
+ message_context = &context.message_context;
+
+ if ((ret = vkd3d_shader_parser_init(&parser, dxbc, message_context)) < 0)
+ {
+ vkd3d_shader_message_context_trace_messages(message_context);
+ if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(message_context)))
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
+ vkd3d_shader_scan_context_cleanup(&context);
return ret;
+ }
if (TRACE_ON())
vkd3d_shader_trace(parser.data);
memset(scan_info, 0, sizeof(*scan_info));
- memset(&context, 0, sizeof(context));
- context.scan_info = scan_info;
-
+ message_context->line = 2; /* Line 1 is the version token. */
+ message_context->column = 1;
while (!shader_sm4_is_end(parser.data, &parser.ptr))
{
shader_sm4_read_instruction(parser.data, &parser.ptr, &instruction);
@@ -628,18 +858,28 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
if (instruction.handler_idx == VKD3DSIH_INVALID)
{
WARN("Encountered unrecognized or invalid instruction.\n");
- vkd3d_free(context.uav_ranges);
vkd3d_shader_free_scan_info(scan_info);
- vkd3d_shader_parser_destroy(&parser);
- return VKD3D_ERROR_INVALID_ARGUMENT;
+ ret = VKD3D_ERROR_INVALID_SHADER;
+ goto done;
}
- vkd3d_shader_scan_instruction(&context, &instruction);
+ if ((ret = vkd3d_shader_scan_instruction(&context, &instruction)) < 0)
+ {
+ vkd3d_shader_free_scan_info(scan_info);
+ goto done;
+ }
+ ++message_context->line;
}
- vkd3d_free(context.uav_ranges);
+ ret = VKD3D_OK;
+
+done:
+ vkd3d_shader_message_context_trace_messages(message_context);
+ if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(message_context)))
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
+ vkd3d_shader_scan_context_cleanup(&context);
vkd3d_shader_parser_destroy(&parser);
- return VKD3D_OK;
+ return ret;
}
void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info)
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index c6796bb..4fa17d6 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -67,6 +67,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_DXBC_INVALID_VERSION = 4,
VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET = 5,
VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE = 6,
+ VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF = 1000,
};
enum VKD3D_SHADER_INSTRUCTION_HANDLER
--
2.11.0
1
0
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/dmime/timesigtrack.c | 54 +++++++++++++++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 2 deletions(-)
diff --git a/dlls/dmime/timesigtrack.c b/dlls/dmime/timesigtrack.c
index 697b3e3593b..5bb38254d43 100644
--- a/dlls/dmime/timesigtrack.c
+++ b/dlls/dmime/timesigtrack.c
@@ -37,6 +37,11 @@ static inline IDirectMusicTimeSigTrack *impl_from_IDirectMusicTrack(IDirectMusic
return CONTAINING_RECORD(iface, IDirectMusicTimeSigTrack, IDirectMusicTrack_iface);
}
+static inline IDirectMusicTimeSigTrack *impl_from_IPersistStream(IPersistStream *iface)
+{
+ return CONTAINING_RECORD(iface, IDirectMusicTimeSigTrack, dmobj.IPersistStream_iface);
+}
+
static HRESULT WINAPI IDirectMusicTrackImpl_QueryInterface(IDirectMusicTrack *iface, REFIID riid,
void **ret_iface)
{
@@ -207,10 +212,55 @@ static const IDirectMusicTrackVtbl dmtack_vtbl = {
IDirectMusicTrackImpl_Clone
};
+
+static HRESULT parse_timetrack_list(IDirectMusicTimeSigTrack *This, IStream *stream,
+ struct chunk_entry *timesig)
+{
+ HRESULT hr;
+ struct chunk_entry chunk = {.parent = timesig};
+ DMUS_IO_TIMESIGNATURE_ITEM item;
+
+ TRACE("Parsing segment form in %p: %s\n", stream, debugstr_chunk(timesig));
+
+ while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) {
+ if (chunk.id != DMUS_FOURCC_TIMESIGNATURE_TRACK)
+ return DMUS_E_UNSUPPORTED_STREAM;
+
+ if (FAILED(hr = stream_chunk_get_data(stream, &chunk, &item, chunk.size))) {
+ WARN("Failed to read data of %s\n", debugstr_chunk(&chunk));
+ return hr;
+ }
+
+ TRACE("Found DMUS_IO_TIMESIGNATURE_ITEM\n");
+ TRACE(" - lTime %d\n", item.lTime);
+ TRACE(" - bBeatsPerMeasure %d\n", item.bBeatsPerMeasure);
+ TRACE(" - bBeat %d\n", item.bBeat);
+ TRACE(" - wGridsPerBeat %d\n", item.wGridsPerBeat);
+ }
+
+ return SUCCEEDED(hr) ? S_OK : hr;
+}
+
static HRESULT WINAPI time_IPersistStream_Load(IPersistStream *iface, IStream *stream)
{
- FIXME(": Loading not implemented yet\n");
- return S_OK;
+ IDirectMusicTimeSigTrack *This = impl_from_IPersistStream(iface);
+ HRESULT hr;
+ struct chunk_entry chunk = {0};
+
+ TRACE("%p, %p\n", This, stream);
+
+ if (!stream)
+ return E_POINTER;
+
+ if ((hr = stream_get_chunk(stream, &chunk) != S_OK))
+ return hr;
+
+ if (chunk.id == FOURCC_LIST && chunk.type == DMUS_FOURCC_TIMESIGTRACK_LIST)
+ hr = parse_timetrack_list(This, stream, &chunk);
+ else
+ hr = DMUS_E_UNSUPPORTED_STREAM;
+
+ return hr;
}
static const IPersistStreamVtbl persiststream_vtbl = {
--
2.27.0
1
0
29 Jul '20
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/usp10/usp10.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 322091c5472..719fa3aae5c 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -169,7 +169,7 @@ script_ranges[] =
/* Control Pictures : U+2400 –U+243f */
/* Optical Character Recognition : U+2440 –U+245f */
/* Enclosed Alphanumerics : U+2460 –U+24ff */
- /* Box Drawing : U+2500 –U+25ff */
+ /* Box Drawing : U+2500 –U+257f */
/* Block Elements : U+2580 –U+259f */
/* Geometric Shapes : U+25a0 –U+25ff */
/* Miscellaneous Symbols : U+2600 –U+26ff */
--
2.23.0
1
0
[PATCH] user32: Support undocumented SC_SIZE flag that can be used to move window.
by Piotr Caban 29 Jul '20
by Piotr Caban 29 Jul '20
29 Jul '20
Fixes main window moving in Quicken 2020.
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/user32/tests/win.c | 40 +++++++++++++++++++++++++++++++++++++++
dlls/user32/winpos.c | 4 ++--
dlls/winex11.drv/window.c | 1 +
3 files changed, 43 insertions(+), 2 deletions(-)
2
1
[PATCH 1/2] ntdll: Compare builtins by their device and inode number directly.
by Zebediah Figura 29 Jul '20
by Zebediah Figura 29 Jul '20
29 Jul '20
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/ntdll/unix/loader.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index afb6405864a..499d9bf58b1 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -129,7 +129,8 @@ static HMODULE ntdll_module;
struct file_id
{
- BYTE ObjectId[16];
+ dev_t dev;
+ ino_t ino;
};
struct builtin_module
@@ -142,13 +143,17 @@ struct builtin_module
static struct list builtin_modules = LIST_INIT( builtin_modules );
-static NTSTATUS add_builtin_module( void *module, void *handle, const FILE_OBJECTID_BUFFER *id )
+static NTSTATUS add_builtin_module( void *module, void *handle, const struct stat *st )
{
struct builtin_module *builtin;
if (!(builtin = malloc( sizeof(*builtin) ))) return STATUS_NO_MEMORY;
builtin->handle = handle;
builtin->module = module;
- if (id) memcpy( &builtin->id, id->ObjectId, sizeof(builtin->id) );
+ if (st)
+ {
+ builtin->id.dev = st->st_dev;
+ builtin->id.ino = st->st_ino;
+ }
else memset( &builtin->id, 0, sizeof(builtin->id) );
list_add_tail( &builtin_modules, &builtin->entry );
return STATUS_SUCCESS;
@@ -996,9 +1001,7 @@ static NTSTATUS open_dll_file( const char *name, void **module, pe_image_info_t
{
struct builtin_module *builtin;
OBJECT_ATTRIBUTES attr = { sizeof(attr) };
- IO_STATUS_BLOCK io;
LARGE_INTEGER size;
- FILE_OBJECTID_BUFFER id;
struct stat st;
SIZE_T len = 0;
NTSTATUS status;
@@ -1017,11 +1020,11 @@ static NTSTATUS open_dll_file( const char *name, void **module, pe_image_info_t
return STATUS_DLL_NOT_FOUND;
}
- if (!NtFsControlFile( handle, 0, NULL, NULL, &io, FSCTL_GET_OBJECT_ID, NULL, 0, &id, sizeof(id) ))
+ if (!stat( name, &st ))
{
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
{
- if (!memcmp( &builtin->id, id.ObjectId, sizeof(builtin->id) ))
+ if (builtin->id.dev == st.st_dev && builtin->id.ino == st.st_ino)
{
TRACE( "%s is the same file as existing module %p\n", debugstr_a(name),
builtin->module );
@@ -1032,7 +1035,7 @@ static NTSTATUS open_dll_file( const char *name, void **module, pe_image_info_t
}
}
}
- else memset( id.ObjectId, 0, sizeof(id.ObjectId) );
+ else memset( &st, 0, sizeof(st) );
size.QuadPart = 0;
status = NtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY |
@@ -1063,7 +1066,7 @@ static NTSTATUS open_dll_file( const char *name, void **module, pe_image_info_t
status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
}
- if (!status) status = add_builtin_module( *module, NULL, &id );
+ if (!status) status = add_builtin_module( *module, NULL, &st );
if (status)
{
--
2.27.0
1
1
[PATCH 1/6] amstream: Return correct media type info when enumerating AMAudioStream media types.
by Gijs Vermeulen 29 Jul '20
by Gijs Vermeulen 29 Jul '20
29 Jul '20
Signed-off-by: Gijs Vermeulen <gijsvrm(a)gmail.com>
---
dlls/amstream/audiostream.c | 20 +++++++++++++++++++-
dlls/amstream/tests/amstream.c | 10 +++++-----
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/dlls/amstream/audiostream.c b/dlls/amstream/audiostream.c
index 112891eeb7..c3831544d6 100644
--- a/dlls/amstream/audiostream.c
+++ b/dlls/amstream/audiostream.c
@@ -821,6 +821,17 @@ static HRESULT WINAPI enum_media_types_Next(IEnumMediaTypes *iface, ULONG count,
{
struct enum_media_types *enum_media_types = impl_from_IEnumMediaTypes(iface);
+ static const WAVEFORMATEX wfx =
+ {
+ .wFormatTag = WAVE_FORMAT_PCM,
+ .nChannels = 1,
+ .nSamplesPerSec = 11025,
+ .nAvgBytesPerSec = 11025 * 2,
+ .nBlockAlign = 2,
+ .wBitsPerSample = 16,
+ .cbSize = 0,
+ };
+
TRACE("iface %p, count %u, mts %p, ret_count %p.\n", iface, count, mts, ret_count);
if (!ret_count)
@@ -831,7 +842,14 @@ static HRESULT WINAPI enum_media_types_Next(IEnumMediaTypes *iface, ULONG count,
mts[0] = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
memset(mts[0], 0, sizeof(AM_MEDIA_TYPE));
mts[0]->majortype = MEDIATYPE_Audio;
- mts[0]->subtype = MEDIASUBTYPE_PCM;
+ mts[0]->subtype = GUID_NULL;
+ mts[0]->bFixedSizeSamples = TRUE;
+ mts[0]->bTemporalCompression = FALSE;
+ mts[0]->lSampleSize = 2;
+ mts[0]->formattype = FORMAT_WaveFormatEx;
+ mts[0]->cbFormat = sizeof(WAVEFORMATEX);
+ mts[0]->pbFormat = (BYTE *)&wfx;
+
++enum_media_types->index;
*ret_count = 1;
return count == 1 ? S_OK : S_FALSE;
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c
index 68d2b9c18f..da9633feec 100644
--- a/dlls/amstream/tests/amstream.c
+++ b/dlls/amstream/tests/amstream.c
@@ -2426,15 +2426,15 @@ static void test_media_types(void)
ok(count == 1, "Got count %u.\n", count);
ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s\n",
wine_dbgstr_guid(&pmt->majortype));
- todo_wine ok(IsEqualGUID(&pmt->subtype, &GUID_NULL), "Got subtype %s\n",
+ ok(IsEqualGUID(&pmt->subtype, &GUID_NULL), "Got subtype %s\n",
wine_dbgstr_guid(&pmt->subtype));
- todo_wine ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
+ ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
- todo_wine ok(pmt->lSampleSize == 2, "Got sample size %u.\n", pmt->lSampleSize);
- todo_wine ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
+ ok(pmt->lSampleSize == 2, "Got sample size %u.\n", pmt->lSampleSize);
+ ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
wine_dbgstr_guid(&pmt->formattype));
ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
- todo_wine ok(pmt->cbFormat == sizeof(WAVEFORMATEX), "Got format size %u.\n", pmt->cbFormat);
+ ok(pmt->cbFormat == sizeof(WAVEFORMATEX), "Got format size %u.\n", pmt->cbFormat);
ok(!memcmp(pmt->pbFormat, &expect_wfx, pmt->cbFormat), "Format blocks didn't match.\n");
hr = IPin_QueryAccept(pin, pmt);
--
2.27.0
2
9