Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 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
December 2020
- 68 participants
- 931 messages
Re: [PATCH] qcap/tests: Use wide-char string literals.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
Dec. 15, 2020
[PATCH vkd3d 2/2] vkd3d-shader: Move location tracking out of the vkd3d_shader_message_context structure.
by Zebediah Figura
Includes a slight change in behaviour: parse_dxbc() and
vkd3d_shader_serialize_root_signature() now print nothing instead of
"<anonymous>".
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
libs/vkd3d-shader/dxbc.c | 50 ++++++++++++------------
libs/vkd3d-shader/spirv.c | 6 ++-
libs/vkd3d-shader/vkd3d_shader_main.c | 41 +++++++++----------
libs/vkd3d-shader/vkd3d_shader_private.h | 16 +++++---
4 files changed, 58 insertions(+), 55 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 9977d1a3..df9245de 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -2036,7 +2036,7 @@ static int parse_dxbc(const char *data, size_t data_size, struct vkd3d_shader_me
if (data_size < VKD3D_DXBC_HEADER_SIZE)
{
WARN("Invalid data size %zu.\n", data_size);
- vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_DXBC_INVALID_SIZE,
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIZE,
"DXBC size %zu is smaller than the DXBC header size.", data_size);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
@@ -2047,7 +2047,7 @@ static int parse_dxbc(const char *data, size_t data_size, struct vkd3d_shader_me
if (tag != TAG_DXBC)
{
WARN("Wrong tag.\n");
- vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_DXBC_INVALID_MAGIC, "Invalid DXBC magic.");
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_MAGIC, "Invalid DXBC magic.");
return VKD3D_ERROR_INVALID_ARGUMENT;
}
@@ -2063,7 +2063,7 @@ static int parse_dxbc(const char *data, size_t data_size, struct vkd3d_shader_me
checksum[0], checksum[1], checksum[2], checksum[3],
calculated_checksum[0], calculated_checksum[1],
calculated_checksum[2], calculated_checksum[3]);
- vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_DXBC_INVALID_CHECKSUM, "Invalid DXBC checksum.");
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_CHECKSUM, "Invalid DXBC checksum.");
return VKD3D_ERROR_INVALID_ARGUMENT;
}
@@ -2072,7 +2072,7 @@ static int parse_dxbc(const char *data, size_t data_size, struct vkd3d_shader_me
if (version != 0x00000001)
{
WARN("Got unexpected DXBC version %#x.\n", version);
- vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_DXBC_INVALID_VERSION,
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_VERSION,
"DXBC version %#x is not supported.", version);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
@@ -2095,7 +2095,7 @@ static int parse_dxbc(const char *data, size_t data_size, struct vkd3d_shader_me
if (chunk_offset >= data_size || !require_space(chunk_offset, 2, sizeof(DWORD), data_size))
{
WARN("Invalid chunk offset %#x (data size %zu).\n", chunk_offset, data_size);
- vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET,
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET,
"DXBC chunk %u has invalid offset %#x (data size %#zx).", i, chunk_offset, data_size);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
@@ -2109,7 +2109,7 @@ static int parse_dxbc(const char *data, size_t data_size, struct vkd3d_shader_me
{
WARN("Invalid chunk size %#x (data size %zu, chunk offset %#x).\n",
chunk_size, data_size, chunk_offset);
- vkd3d_shader_error(message_context, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE,
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE,
"DXBC chunk %u has invalid size %#x (data size %#zx, chunk offset %#x).",
i, chunk_offset, data_size, chunk_offset);
return VKD3D_ERROR_INVALID_ARGUMENT;
@@ -2781,7 +2781,7 @@ int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
memset(root_signature, 0, sizeof(*root_signature));
if (messages)
*messages = NULL;
- vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO, NULL);
+ vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO);
ret = parse_dxbc(dxbc->code, dxbc->size, &message_context, rts0_handler, root_signature);
vkd3d_shader_message_context_trace_messages(&message_context);
@@ -2935,7 +2935,7 @@ static int shader_write_root_signature_header(struct root_signature_writer_conte
return VKD3D_OK;
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -2963,7 +2963,7 @@ static int shader_write_descriptor_ranges(struct root_signature_writer_context *
return VKD3D_OK;
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -2993,7 +2993,7 @@ static int shader_write_descriptor_ranges1(struct root_signature_writer_context
return VKD3D_OK;
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -3009,7 +3009,7 @@ static int shader_write_descriptor_table(struct root_signature_writer_context *c
return shader_write_descriptor_ranges(context, table);
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -3025,7 +3025,7 @@ static int shader_write_descriptor_table1(struct root_signature_writer_context *
return shader_write_descriptor_ranges1(context, table);
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -3043,7 +3043,7 @@ static int shader_write_root_constants(struct root_signature_writer_context *con
return VKD3D_OK;
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -3059,7 +3059,7 @@ static int shader_write_root_descriptor(struct root_signature_writer_context *co
return VKD3D_OK;
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -3077,7 +3077,7 @@ static int shader_write_root_descriptor1(struct root_signature_writer_context *c
return VKD3D_OK;
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -3126,7 +3126,7 @@ 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,
+ 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;
@@ -3139,7 +3139,7 @@ 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,
+ 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;
}
@@ -3183,7 +3183,7 @@ static int shader_write_static_samplers(struct root_signature_writer_context *co
return VKD3D_OK;
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -3218,7 +3218,7 @@ static int shader_write_root_signature(struct root_signature_writer_context *con
return shader_write_static_samplers(context, desc);
fail:
- vkd3d_shader_error(&context->message_context, VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY,
+ 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;
}
@@ -3247,7 +3247,7 @@ 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,
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_RS_INVALID_DESCRIPTOR_RANGE_TYPE,
"Invalid root signature descriptor range type %#x.", r->range_type);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
@@ -3256,7 +3256,7 @@ 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,
+ vkd3d_shader_error(message_context, NULL, 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;
}
@@ -3288,7 +3288,7 @@ 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,
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_RS_INVALID_DESCRIPTOR_RANGE_TYPE,
"Invalid root signature descriptor range type %#x.", r->range_type);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
@@ -3297,7 +3297,7 @@ 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,
+ vkd3d_shader_error(message_context, NULL, 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;
}
@@ -3345,14 +3345,14 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro
*messages = NULL;
memset(&context, 0, sizeof(context));
- vkd3d_shader_message_context_init(&context.message_context, VKD3D_SHADER_LOG_INFO, NULL);
+ vkd3d_shader_message_context_init(&context.message_context, VKD3D_SHADER_LOG_INFO);
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);
- vkd3d_shader_error(&context.message_context, VKD3D_SHADER_ERROR_RS_INVALID_VERSION,
+ vkd3d_shader_error(&context.message_context, NULL, VKD3D_SHADER_ERROR_RS_INVALID_VERSION,
"Root signature version %#x is not supported.", root_signature->version);
goto done;
}
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index cb9c7a12..61d0d472 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2155,6 +2155,7 @@ struct vkd3d_dxbc_compiler
struct vkd3d_spirv_builder spirv_builder;
struct vkd3d_shader_message_context *message_context;
+ struct vkd3d_shader_location location;
bool failed;
bool strip_debug;
@@ -2245,6 +2246,8 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
memset(compiler, 0, sizeof(*compiler));
compiler->message_context = message_context;
+ compiler->location.source_name = compile_info->source_name;
+ compiler->location.line = 2; /* Line 1 is the version token. */
if ((target_info = vkd3d_find_struct(compile_info->next, SPIRV_TARGET_INFO)))
{
@@ -2452,7 +2455,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_dxbc_compiler_error(struct vkd3d_dxbc_
va_list args;
va_start(args, format);
- vkd3d_shader_verror(compiler->message_context, error, format, args);
+ vkd3d_shader_verror(compiler->message_context, &compiler->location, error, format, args);
va_end(args);
compiler->failed = true;
}
@@ -9194,6 +9197,7 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
FIXME("Unhandled instruction %#x.\n", instruction->handler_idx);
}
+ ++compiler->location.line;
return ret;
}
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 2ea233bb..53e22789 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -108,13 +108,9 @@ void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const
}
void vkd3d_shader_message_context_init(struct vkd3d_shader_message_context *context,
- enum vkd3d_shader_log_level log_level, const char *source_name)
+ enum vkd3d_shader_log_level log_level)
{
context->log_level = log_level;
- context->source_name = source_name ? source_name : "<anonymous>";
- context->line = 0;
- context->column = 0;
-
vkd3d_string_buffer_init(&context->messages);
}
@@ -148,28 +144,28 @@ bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_cont
return true;
}
-void vkd3d_shader_verror(struct vkd3d_shader_message_context *context,
+void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, va_list args)
{
if (context->log_level < VKD3D_SHADER_LOG_ERROR)
return;
- if (context->line)
+ if (location)
vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: E%04u: ",
- context->source_name, context->line, context->column, error);
+ location->source_name ? location->source_name : "<anonymous>", location->line, location->column, error);
else
- vkd3d_string_buffer_printf(&context->messages, "%s: E%04u: ", context->source_name, error);
+ vkd3d_string_buffer_printf(&context->messages, "E%04u: ", error);
vkd3d_string_buffer_vprintf(&context->messages, format, args);
vkd3d_string_buffer_printf(&context->messages, "\n");
}
-void vkd3d_shader_error(struct vkd3d_shader_message_context *context,
+void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, ...)
{
va_list args;
va_start(args, format);
- vkd3d_shader_verror(context, error, format, args);
+ vkd3d_shader_verror(context, location, error, format, args);
va_end(args);
}
@@ -307,6 +303,7 @@ struct vkd3d_shader_scan_context
size_t descriptors_size;
struct vkd3d_shader_message_context *message_context;
+ struct vkd3d_shader_location location;
struct vkd3d_shader_cf_info
{
@@ -332,12 +329,15 @@ struct vkd3d_shader_scan_context
};
static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *context,
+ const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info,
struct vkd3d_shader_message_context *message_context)
{
memset(context, 0, sizeof(*context));
context->scan_descriptor_info = scan_descriptor_info;
context->message_context = message_context;
+ context->location.source_name = compile_info->source_name;
+ context->location.line = 2; /* Line 1 is the version token. */
}
static void vkd3d_shader_scan_context_cleanup(struct vkd3d_shader_scan_context *context)
@@ -606,7 +606,7 @@ static void vkd3d_shader_scan_error(struct vkd3d_shader_scan_context *context,
va_list args;
va_start(args, format);
- vkd3d_shader_verror(context->message_context, error, format, args);
+ vkd3d_shader_verror(context->message_context, &context->location, error, format, args);
va_end(args);
}
@@ -774,6 +774,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
if (vkd3d_shader_instruction_is_uav_counter(instruction))
vkd3d_shader_scan_record_uav_counter(context, &instruction->src[0].reg);
+ ++context->location.line;
return VKD3D_OK;
}
@@ -792,7 +793,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
scan_descriptor_info->descriptor_count = 0;
}
- vkd3d_shader_scan_context_init(&context, scan_descriptor_info, message_context);
+ vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context);
if ((ret = vkd3d_shader_parser_init(&parser, &compile_info->source, message_context)) < 0)
{
@@ -803,8 +804,6 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
if (TRACE_ON())
vkd3d_shader_trace(parser.data);
- 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);
@@ -824,7 +823,6 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info,
vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info);
goto done;
}
- ++message_context->line;
}
ret = VKD3D_OK;
@@ -848,7 +846,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
if ((ret = vkd3d_shader_validate_compile_info(compile_info, true)) < 0)
return ret;
- vkd3d_shader_message_context_init(&message_context, compile_info->log_level, compile_info->source_name);
+ vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
ret = scan_dxbc(compile_info, &message_context);
@@ -902,8 +900,6 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
return VKD3D_ERROR;
}
- 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);
@@ -917,7 +913,6 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info
if ((ret = vkd3d_dxbc_compiler_handle_instruction(spirv_compiler, &instruction)) < 0)
break;
- ++message_context->line;
}
if (ret >= 0)
@@ -949,7 +944,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
if ((ret = vkd3d_shader_validate_compile_info(compile_info, true)) < 0)
return ret;
- vkd3d_shader_message_context_init(&message_context, compile_info->log_level, compile_info->source_name);
+ vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
switch (compile_info->source_type)
{
@@ -1051,7 +1046,7 @@ int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
if (messages)
*messages = NULL;
- vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO, NULL);
+ vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO);
ret = shader_parse_input_signature(dxbc->code, dxbc->size, &message_context, signature);
vkd3d_shader_message_context_trace_messages(&message_context);
@@ -1174,7 +1169,7 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info
if ((ret = vkd3d_shader_validate_compile_info(compile_info, false)) < 0)
return ret;
- vkd3d_shader_message_context_init(&message_context, compile_info->log_level, compile_info->source_name);
+ vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
ret = preproc_lexer_parse(compile_info, out, &message_context);
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 83038384..7b0e0fc0 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -844,11 +844,15 @@ int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer,
void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function) DECLSPEC_HIDDEN;
int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args) DECLSPEC_HIDDEN;
-struct vkd3d_shader_message_context
+struct vkd3d_shader_location
{
- enum vkd3d_shader_log_level log_level;
const char *source_name;
unsigned int line, column;
+};
+
+struct vkd3d_shader_message_context
+{
+ enum vkd3d_shader_log_level log_level;
struct vkd3d_string_buffer messages;
};
@@ -856,14 +860,14 @@ void vkd3d_shader_message_context_cleanup(struct vkd3d_shader_message_context *c
bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context,
char **out) DECLSPEC_HIDDEN;
void vkd3d_shader_message_context_init(struct vkd3d_shader_message_context *context,
- enum vkd3d_shader_log_level log_level, const char *source_name) DECLSPEC_HIDDEN;
+ enum vkd3d_shader_log_level log_level) 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;
-void vkd3d_shader_verror(struct vkd3d_shader_message_context *context,
+void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
+ enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(4, 5) DECLSPEC_HIDDEN;
+void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, va_list args) DECLSPEC_HIDDEN;
int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length,
--
2.29.2
Dec. 15, 2020
[PATCH vkd3d 1/2] vkd3d-shader: Introduce a helper to report errors while scanning.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
libs/vkd3d-shader/vkd3d_shader_main.c | 32 ++++++++++++++++++---------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index eed0316c..2ea233bb 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -600,6 +600,16 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca
semantic->resource_type, resource_data_type);
}
+static void vkd3d_shader_scan_error(struct vkd3d_shader_scan_context *context,
+ enum vkd3d_shader_error error, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vkd3d_shader_verror(context->message_context, error, format, args);
+ va_end(args);
+}
+
static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_instruction *instruction)
{
@@ -636,7 +646,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered ‘else’ instruction without corresponding ‘if’ block.");
return VKD3D_ERROR_INVALID_SHADER;
}
@@ -645,7 +655,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered ‘endif’ instruction without corresponding ‘if’ block.");
return VKD3D_ERROR_INVALID_SHADER;
}
@@ -658,7 +668,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered ‘endloop’ instruction without corresponding ‘loop’ block.");
return VKD3D_ERROR_INVALID_SHADER;
}
@@ -672,7 +682,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered ‘endswitch’ instruction without corresponding ‘switch’ block.");
return VKD3D_ERROR_INVALID_SHADER;
}
@@ -682,7 +692,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered ‘case’ instruction outside switch block.");
return VKD3D_ERROR_INVALID_SHADER;
}
@@ -692,13 +702,13 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered duplicate ‘default’ instruction inside the current switch block.");
return VKD3D_ERROR_INVALID_SHADER;
}
@@ -708,7 +718,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered ‘break’ instruction outside breakable block.");
return VKD3D_ERROR_INVALID_SHADER;
}
@@ -717,7 +727,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered ‘breakp’ instruction outside loop.");
return VKD3D_ERROR_INVALID_SHADER;
}
@@ -725,7 +735,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered ‘continue’ instruction outside loop.");
return VKD3D_ERROR_INVALID_SHADER;
}
@@ -734,7 +744,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
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,
+ vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
"Encountered ‘continue’ instruction outside loop.");
return VKD3D_ERROR_INVALID_SHADER;
}
--
2.29.2
Dec. 15, 2020
[PATCH vkd3d] build: Create object directories before running bison or flex.
by Zebediah Figura
Vkd3d-Bug: https://bugs.winehq.org/show_bug.cgi?id=50334
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
Makefile.am | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index 32c8777f..bf1d7bfa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -119,9 +119,11 @@ vkd3d_v_bison_0 = @echo " BISON " $@;
vkd3d_v_bison_1 =
libs/vkd3d-shader/preproc.yy.c: libs/vkd3d-shader/preproc.l
+ @$(MKDIR_P) libs/vkd3d-shader
$(VKD3D_V_FLEX)$(FLEX) $(LFLAGS) -o $@ $<
libs/vkd3d-shader/preproc.tab.c libs/vkd3d-shader/preproc.tab.h &: libs/vkd3d-shader/preproc.y
+ @$(MKDIR_P) libs/vkd3d-shader
$(VKD3D_V_BISON)$(BISON) $(YFLAGS) -d -o libs/vkd3d-shader/preproc.tab.c $<
BUILT_SOURCES += libs/vkd3d-shader/preproc.tab.h
--
2.29.2
Dec. 15, 2020
[PATCH] qcap/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/qcap/tests/audiorecord.c | 9 ++----
dlls/qcap/tests/avico.c | 54 +++++++++++++-------------------
dlls/qcap/tests/avimux.c | 31 +++++++++---------
dlls/qcap/tests/smartteefilter.c | 36 ++++++++++-----------
4 files changed, 55 insertions(+), 75 deletions(-)
diff --git a/dlls/qcap/tests/audiorecord.c b/dlls/qcap/tests/audiorecord.c
index dc74c3cfc15..350ae986b44 100644
--- a/dlls/qcap/tests/audiorecord.c
+++ b/dlls/qcap/tests/audiorecord.c
@@ -176,18 +176,15 @@ static ULONG WINAPI property_bag_Release(IPropertyBag *iface)
ok(0, "Unexpected call.\n");
return 1;
}
-
-static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0};
-static const WCHAR usemixerW[] = {'U','s','e','M','i','x','e','r',0};
static int ppb_id;
static unsigned int ppb_got_read;
static HRESULT WINAPI property_bag_Read(IPropertyBag *iface, const WCHAR *name, VARIANT *var, IErrorLog *log)
{
- if (!lstrcmpW(name, usemixerW))
+ if (!lstrcmpW(name, L"UseMixer"))
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- todo_wine ok(!lstrcmpW(name, waveinidW), "Got unexpected name %s.\n", wine_dbgstr_w(name));
+ todo_wine ok(!lstrcmpW(name, L"WaveInId"), "Got unexpected name %s.\n", wine_dbgstr_w(name));
ok(V_VT(var) == VT_I4, "Got unexpected type %u.\n", V_VT(var));
ok(!log, "Got unexpected error log %p.\n", log);
ppb_got_read++;
@@ -222,7 +219,7 @@ static void test_property_bag(IMoniker *mon)
ok(hr == S_OK, "Got hr %#x.\n", hr);
VariantInit(&var);
- hr = IPropertyBag_Read(devenum_bag, waveinidW, &var, NULL);
+ hr = IPropertyBag_Read(devenum_bag, L"WaveInId", &var, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ppb_id = V_I4(&var);
diff --git a/dlls/qcap/tests/avico.c b/dlls/qcap/tests/avico.c
index b4f52f10210..332ca5a8e7d 100644
--- a/dlls/qcap/tests/avico.c
+++ b/dlls/qcap/tests/avico.c
@@ -23,11 +23,6 @@
#include "vfw.h"
#include "wine/test.h"
-static const WCHAR sink_id[] = {'I','n',0};
-static const WCHAR source_id[] = {'O','u','t',0};
-static const WCHAR sink_name[] = {'I','n','p','u','t',0};
-static const WCHAR source_name[] = {'O','u','t','p','u','t',0};
-
static const DWORD test_fourcc = mmioFOURCC('w','t','s','t');
#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
@@ -74,7 +69,7 @@ static void test_interfaces(IBaseFilter *filter)
check_interface(filter, &IID_IReferenceClock, FALSE);
check_interface(filter, &IID_IVideoWindow, FALSE);
- IBaseFilter_FindPin(filter, sink_id, &pin);
+ IBaseFilter_FindPin(filter, L"In", &pin);
check_interface(pin, &IID_IMemInputPin, TRUE);
check_interface(pin, &IID_IPin, TRUE);
@@ -85,7 +80,7 @@ static void test_interfaces(IBaseFilter *filter)
check_interface(pin, &IID_IMediaSeeking, FALSE);
IPin_Release(pin);
- IBaseFilter_FindPin(filter, source_id, &pin);
+ IBaseFilter_FindPin(filter, L"Out", &pin);
todo_wine check_interface(pin, &IID_IMediaPosition, TRUE);
todo_wine check_interface(pin, &IID_IMediaSeeking, TRUE);
@@ -319,7 +314,7 @@ static void test_find_pin(IBaseFilter *filter)
hr = IBaseFilter_EnumPins(filter, &enum_pins);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IBaseFilter_FindPin(filter, sink_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"In", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -327,7 +322,7 @@ static void test_find_pin(IBaseFilter *filter)
IPin_Release(pin);
IPin_Release(pin2);
- hr = IBaseFilter_FindPin(filter, source_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Out", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -335,9 +330,9 @@ static void test_find_pin(IBaseFilter *filter)
IPin_Release(pin);
IPin_Release(pin2);
- hr = IBaseFilter_FindPin(filter, sink_name, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Input", &pin);
ok(hr == VFW_E_NOT_FOUND, "Got hr %#x.\n", hr);
- hr = IBaseFilter_FindPin(filter, source_name, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Output", &pin);
ok(hr == VFW_E_NOT_FOUND, "Got hr %#x.\n", hr);
IEnumPins_Release(enum_pins);
@@ -351,14 +346,14 @@ static void test_pin_info(IBaseFilter *filter)
WCHAR *id;
IPin *pin;
- hr = IBaseFilter_FindPin(filter, sink_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"In", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IPin_QueryPinInfo(pin, &info);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
- todo_wine ok(!lstrcmpW(info.achName, sink_name), "Got name %s.\n", wine_dbgstr_w(info.achName));
+ todo_wine ok(!lstrcmpW(info.achName, L"Input"), "Got name %s.\n", wine_dbgstr_w(info.achName));
IBaseFilter_Release(info.pFilter);
hr = IPin_QueryDirection(pin, &dir);
@@ -367,19 +362,19 @@ static void test_pin_info(IBaseFilter *filter)
hr = IPin_QueryId(pin, &id);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- ok(!lstrcmpW(id, sink_id), "Got id %s.\n", wine_dbgstr_w(id));
+ ok(!lstrcmpW(id, L"In"), "Got id %s.\n", wine_dbgstr_w(id));
CoTaskMemFree(id);
IPin_Release(pin);
- hr = IBaseFilter_FindPin(filter, source_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Out", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IPin_QueryPinInfo(pin, &info);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
ok(info.dir == PINDIR_OUTPUT, "Got direction %d.\n", info.dir);
- todo_wine ok(!lstrcmpW(info.achName, source_name), "Got name %s.\n", wine_dbgstr_w(info.achName));
+ todo_wine ok(!lstrcmpW(info.achName, L"Output"), "Got name %s.\n", wine_dbgstr_w(info.achName));
IBaseFilter_Release(info.pFilter);
hr = IPin_QueryDirection(pin, &dir);
@@ -388,7 +383,7 @@ static void test_pin_info(IBaseFilter *filter)
hr = IPin_QueryId(pin, &id);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- ok(!lstrcmpW(id, source_id), "Got id %s.\n", wine_dbgstr_w(id));
+ ok(!lstrcmpW(id, L"Out"), "Got id %s.\n", wine_dbgstr_w(id));
CoTaskMemFree(id);
IPin_Release(pin);
@@ -397,7 +392,6 @@ static void test_pin_info(IBaseFilter *filter)
static LRESULT CALLBACK driver_proc(DWORD_PTR id, HDRVR driver, UINT msg,
LPARAM lparam1, LPARAM lparam2)
{
- static const WCHAR nameW[] = {'f','o','o',0};
if (winetest_debug > 1) trace("msg %#x, lparam1 %#lx, lparam2 %#lx.\n", msg, lparam1, lparam2);
switch (msg)
@@ -415,8 +409,8 @@ static LRESULT CALLBACK driver_proc(DWORD_PTR id, HDRVR driver, UINT msg,
info->dwFlags = VIDCF_TEMPORAL;
info->dwVersion = 0x10101;
info->dwVersionICM = ICVERSION;
- lstrcpyW(info->szName, nameW);
- lstrcpyW(info->szDescription, nameW);
+ lstrcpyW(info->szName, L"foo");
+ lstrcpyW(info->szDescription, L"foo");
return sizeof(ICINFO);
}
case ICM_COMPRESS_QUERY:
@@ -446,14 +440,12 @@ static ULONG WINAPI property_bag_Release(IPropertyBag *iface)
ok(0, "Unexpected call.\n");
return 1;
}
-
-static const WCHAR fcchandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0};
static BSTR ppb_handler;
static unsigned int ppb_got_read;
static HRESULT WINAPI property_bag_Read(IPropertyBag *iface, const WCHAR *name, VARIANT *var, IErrorLog *log)
{
- ok(!lstrcmpW(name, fcchandlerW), "Got unexpected name %s.\n", wine_dbgstr_w(name));
+ ok(!lstrcmpW(name, L"FccHandler"), "Got unexpected name %s.\n", wine_dbgstr_w(name));
ok(V_VT(var) == VT_BSTR, "Got unexpected type %u.\n", V_VT(var));
ok(!log, "Got unexpected error log %p.\n", log);
V_BSTR(var) = SysAllocString(ppb_handler);
@@ -489,7 +481,7 @@ static void test_property_bag(IMoniker *mon)
ok(hr == S_OK, "Got hr %#x.\n", hr);
VariantInit(&var);
- hr = IPropertyBag_Read(devenum_bag, fcchandlerW, &var, NULL);
+ hr = IPropertyBag_Read(devenum_bag, L"FccHandler", &var, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ppb_handler = V_BSTR(&var);
@@ -525,7 +517,7 @@ static void test_media_types(IBaseFilter *filter)
HRESULT hr;
IPin *pin;
- IBaseFilter_FindPin(filter, sink_id, &pin);
+ IBaseFilter_FindPin(filter, L"In", &pin);
hr = IPin_EnumMediaTypes(pin, &enummt);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -572,7 +564,7 @@ static void test_media_types(IBaseFilter *filter)
IPin_Release(pin);
- IBaseFilter_FindPin(filter, source_id, &pin);
+ IBaseFilter_FindPin(filter, L"Out", &pin);
hr = IPin_EnumMediaTypes(pin, &enummt);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -592,7 +584,7 @@ static void test_enum_media_types(IBaseFilter *filter)
HRESULT hr;
IPin *pin;
- IBaseFilter_FindPin(filter, sink_id, &pin);
+ IBaseFilter_FindPin(filter, L"In", &pin);
hr = IPin_EnumMediaTypes(pin, &enum1);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -623,7 +615,7 @@ static void test_enum_media_types(IBaseFilter *filter)
IEnumMediaTypes_Release(enum2);
IPin_Release(pin);
- IBaseFilter_FindPin(filter, source_id, &pin);
+ IBaseFilter_FindPin(filter, L"Out", &pin);
hr = IPin_EnumMediaTypes(pin, &enum1);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -709,10 +701,8 @@ static void test_unconnected_filter_state(IBaseFilter *filter)
START_TEST(avico)
{
- static const WCHAR test_display_name[] = {'@','d','e','v','i','c','e',':',
- 'c','m',':','{','3','3','D','9','A','7','6','0','-','9','0','C','8',
- '-','1','1','D','0','-','B','D','4','3','-','0','0','A','0','C','9',
- '1','1','C','E','8','6','}','\\','w','t','s','t',0};
+ static const WCHAR test_display_name[] =
+ L"@device:cm:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\wtst";
ICreateDevEnum *devenum;
IEnumMoniker *enummon;
IBaseFilter *filter;
diff --git a/dlls/qcap/tests/avimux.c b/dlls/qcap/tests/avimux.c
index d1a67a01a11..3f43ff569cf 100644
--- a/dlls/qcap/tests/avimux.c
+++ b/dlls/qcap/tests/avimux.c
@@ -23,9 +23,6 @@
#include "vfw.h"
#include "wine/test.h"
-static const WCHAR source_id[] = {'A','V','I',' ','O','u','t',0};
-static const WCHAR sink0_id[] = {'I','n','p','u','t',' ','0','1',0};
-
static const GUID testguid = {0xfacade};
static IBaseFilter *create_avi_mux(void)
@@ -86,7 +83,7 @@ static void test_interfaces(void)
check_interface(filter, &IID_IReferenceClock, FALSE);
check_interface(filter, &IID_IVideoWindow, FALSE);
- IBaseFilter_FindPin(filter, source_id, &pin);
+ IBaseFilter_FindPin(filter, L"AVI Out", &pin);
check_interface(pin, &IID_IPin, TRUE);
check_interface(pin, &IID_IQualityControl, TRUE);
@@ -99,7 +96,7 @@ static void test_interfaces(void)
IPin_Release(pin);
- IBaseFilter_FindPin(filter, sink0_id, &pin);
+ IBaseFilter_FindPin(filter, L"Input 01", &pin);
check_interface(pin, &IID_IAMStreamControl, TRUE);
check_interface(pin, &IID_IMemInputPin, TRUE);
@@ -343,7 +340,7 @@ static void test_find_pin(void)
hr = IBaseFilter_EnumPins(filter, &enum_pins);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IBaseFilter_FindPin(filter, source_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"AVI Out", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -351,7 +348,7 @@ static void test_find_pin(void)
IPin_Release(pin);
IPin_Release(pin2);
- hr = IBaseFilter_FindPin(filter, sink0_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Input 01", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -374,7 +371,7 @@ static void test_pin_info(void)
ULONG ref;
IPin *pin;
- hr = IBaseFilter_FindPin(filter, source_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"AVI Out", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = get_refcount(filter);
ok(ref == 2, "Got unexpected refcount %d.\n", ref);
@@ -385,7 +382,7 @@ static void test_pin_info(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
ok(info.dir == PINDIR_OUTPUT, "Got direction %d.\n", info.dir);
- ok(!lstrcmpW(info.achName, source_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
+ ok(!lstrcmpW(info.achName, L"AVI Out"), "Got name %s.\n", wine_dbgstr_w(info.achName));
ref = get_refcount(filter);
ok(ref == 3, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pin);
@@ -398,7 +395,7 @@ static void test_pin_info(void)
hr = IPin_QueryId(pin, &id);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- ok(!lstrcmpW(id, source_id), "Got id %s.\n", wine_dbgstr_w(id));
+ ok(!lstrcmpW(id, L"AVI Out"), "Got id %s.\n", wine_dbgstr_w(id));
CoTaskMemFree(id);
hr = IPin_QueryInternalConnections(pin, NULL, NULL);
@@ -406,14 +403,14 @@ static void test_pin_info(void)
IPin_Release(pin);
- hr = IBaseFilter_FindPin(filter, sink0_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Input 01", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IPin_QueryPinInfo(pin, &info);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
- ok(!lstrcmpW(info.achName, sink0_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
+ ok(!lstrcmpW(info.achName, L"Input 01"), "Got name %s.\n", wine_dbgstr_w(info.achName));
IBaseFilter_Release(info.pFilter);
hr = IPin_QueryDirection(pin, &dir);
@@ -422,7 +419,7 @@ static void test_pin_info(void)
hr = IPin_QueryId(pin, &id);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- ok(!lstrcmpW(id, sink0_id), "Got id %s.\n", wine_dbgstr_w(id));
+ ok(!lstrcmpW(id, L"Input 01"), "Got id %s.\n", wine_dbgstr_w(id));
CoTaskMemFree(id);
hr = IPin_QueryInternalConnections(pin, NULL, NULL);
@@ -445,7 +442,7 @@ static void test_media_types(void)
ULONG ref;
IPin *pin;
- IBaseFilter_FindPin(filter, source_id, &pin);
+ IBaseFilter_FindPin(filter, L"AVI Out", &pin);
hr = IPin_EnumMediaTypes(pin, &enummt);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -498,7 +495,7 @@ static void test_media_types(void)
IEnumMediaTypes_Release(enummt);
IPin_Release(pin);
- IBaseFilter_FindPin(filter, sink0_id, &pin);
+ IBaseFilter_FindPin(filter, L"Input 01", &pin);
hr = IPin_EnumMediaTypes(pin, &enummt);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -565,7 +562,7 @@ static void test_enum_media_types(void)
HRESULT hr;
IPin *pin;
- IBaseFilter_FindPin(filter, source_id, &pin);
+ IBaseFilter_FindPin(filter, L"AVI Out", &pin);
hr = IPin_EnumMediaTypes(pin, &enum1);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -629,7 +626,7 @@ static void test_enum_media_types(void)
IEnumMediaTypes_Release(enum2);
IPin_Release(pin);
- IBaseFilter_FindPin(filter, sink0_id, &pin);
+ IBaseFilter_FindPin(filter, L"Input 01", &pin);
hr = IPin_EnumMediaTypes(pin, &enum1);
ok(hr == S_OK, "Got hr %#x.\n", hr);
diff --git a/dlls/qcap/tests/smartteefilter.c b/dlls/qcap/tests/smartteefilter.c
index df741ba1284..e5ae66ff2d3 100644
--- a/dlls/qcap/tests/smartteefilter.c
+++ b/dlls/qcap/tests/smartteefilter.c
@@ -23,10 +23,6 @@
#include "wine/strmbase.h"
#include "wine/test.h"
-static const WCHAR sink_id[] = {'I','n','p','u','t',0};
-static const WCHAR capture_id[] = {'C','a','p','t','u','r','e',0};
-static const WCHAR preview_id[] = {'P','r','e','v','i','e','w',0};
-
static HANDLE event;
static IBaseFilter *create_smart_tee(void)
@@ -90,7 +86,7 @@ static void test_interfaces(void)
check_interface(filter, &IID_IReferenceClock, FALSE);
check_interface(filter, &IID_IVideoWindow, FALSE);
- IBaseFilter_FindPin(filter, sink_id, &pin);
+ IBaseFilter_FindPin(filter, L"Input", &pin);
check_interface(pin, &IID_IMemInputPin, TRUE);
check_interface(pin, &IID_IPin, TRUE);
@@ -106,7 +102,7 @@ static void test_interfaces(void)
IPin_Release(pin);
- IBaseFilter_FindPin(filter, capture_id, &pin);
+ IBaseFilter_FindPin(filter, L"Capture", &pin);
todo_wine check_interface(pin, &IID_IAMStreamControl, TRUE);
check_interface(pin, &IID_IPin, TRUE);
@@ -122,7 +118,7 @@ static void test_interfaces(void)
IPin_Release(pin);
- IBaseFilter_FindPin(filter, preview_id, &pin);
+ IBaseFilter_FindPin(filter, L"Preview", &pin);
todo_wine check_interface(pin, &IID_IAMStreamControl, TRUE);
check_interface(pin, &IID_IPin, TRUE);
@@ -387,7 +383,7 @@ static void test_find_pin(void)
hr = IBaseFilter_EnumPins(filter, &enum_pins);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IBaseFilter_FindPin(filter, sink_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Input", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -395,7 +391,7 @@ static void test_find_pin(void)
IPin_Release(pin2);
IPin_Release(pin);
- hr = IBaseFilter_FindPin(filter, capture_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Capture", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -403,7 +399,7 @@ static void test_find_pin(void)
IPin_Release(pin2);
IPin_Release(pin);
- hr = IBaseFilter_FindPin(filter, preview_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Preview", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -427,7 +423,7 @@ static void test_pin_info(void)
ULONG ref;
IPin *pin;
- hr = IBaseFilter_FindPin(filter, sink_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Input", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = get_refcount(filter);
ok(ref == 2, "Got unexpected refcount %d.\n", ref);
@@ -438,7 +434,7 @@ static void test_pin_info(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
- ok(!lstrcmpW(info.achName, sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
+ ok(!lstrcmpW(info.achName, L"Input"), "Got name %s.\n", wine_dbgstr_w(info.achName));
ref = get_refcount(filter);
ok(ref == 3, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pin);
@@ -451,7 +447,7 @@ static void test_pin_info(void)
hr = IPin_QueryId(pin, &id);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- ok(!lstrcmpW(id, sink_id), "Got id %s.\n", wine_dbgstr_w(id));
+ ok(!lstrcmpW(id, L"Input"), "Got id %s.\n", wine_dbgstr_w(id));
CoTaskMemFree(id);
hr = IPin_QueryInternalConnections(pin, NULL, &count);
@@ -459,14 +455,14 @@ static void test_pin_info(void)
IPin_Release(pin);
- hr = IBaseFilter_FindPin(filter, capture_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Capture", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IPin_QueryPinInfo(pin, &info);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
ok(info.dir == PINDIR_OUTPUT, "Got direction %d.\n", info.dir);
- ok(!lstrcmpW(info.achName, capture_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
+ ok(!lstrcmpW(info.achName, L"Capture"), "Got name %s.\n", wine_dbgstr_w(info.achName));
ref = get_refcount(filter);
ok(ref == 3, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pin);
@@ -479,7 +475,7 @@ static void test_pin_info(void)
hr = IPin_QueryId(pin, &id);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- ok(!lstrcmpW(id, capture_id), "Got id %s.\n", wine_dbgstr_w(id));
+ ok(!lstrcmpW(id, L"Capture"), "Got id %s.\n", wine_dbgstr_w(id));
CoTaskMemFree(id);
hr = IPin_QueryInternalConnections(pin, NULL, &count);
@@ -487,14 +483,14 @@ static void test_pin_info(void)
IPin_Release(pin);
- hr = IBaseFilter_FindPin(filter, preview_id, &pin);
+ hr = IBaseFilter_FindPin(filter, L"Preview", &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IPin_QueryPinInfo(pin, &info);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
ok(info.dir == PINDIR_OUTPUT, "Got direction %d.\n", info.dir);
- ok(!lstrcmpW(info.achName, preview_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
+ ok(!lstrcmpW(info.achName, L"Preview"), "Got name %s.\n", wine_dbgstr_w(info.achName));
ref = get_refcount(filter);
ok(ref == 3, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pin);
@@ -507,7 +503,7 @@ static void test_pin_info(void)
hr = IPin_QueryId(pin, &id);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- ok(!lstrcmpW(id, preview_id), "Got id %s.\n", wine_dbgstr_w(id));
+ ok(!lstrcmpW(id, L"Preview"), "Got id %s.\n", wine_dbgstr_w(id));
CoTaskMemFree(id);
hr = IPin_QueryInternalConnections(pin, NULL, &count);
@@ -528,7 +524,7 @@ static void test_enum_media_types(void)
HRESULT hr;
IPin *pin;
- IBaseFilter_FindPin(filter, sink_id, &pin);
+ IBaseFilter_FindPin(filter, L"Input", &pin);
hr = IPin_EnumMediaTypes(pin, &enum1);
ok(hr == S_OK, "Got hr %#x.\n", hr);
--
2.26.2
Dec. 14, 2020
[PATCH] -Add SORT_DIGITSASNUMBERS flag to CompareStringsEx (Fixes FL Studio 20.8 crash on startup)
by John Zourlios
---
dlls/kernelbase/locale.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index c60b796aa48..51085f4377a 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -3021,7 +3021,7 @@ INT WINAPI CompareStringEx( const WCHAR *locale, DWORD flags, const WCHAR *str1,
{
DWORD supported_flags = NORM_IGNORECASE | NORM_IGNORENONSPACE | NORM_IGNORESYMBOLS | SORT_STRINGSORT |
NORM_IGNOREKANATYPE | NORM_IGNOREWIDTH | LOCALE_USE_CP_ACP;
- DWORD semistub_flags = NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE | 0x10000000;
+ DWORD semistub_flags = NORM_LINGUISTIC_CASING | LINGUISTIC_IGNORECASE | 0x10000000 | SORT_DIGITSASNUMBERS;
/* 0x10000000 is related to diacritics in Arabic, Japanese, and Hebrew */
INT ret;
static int once;
--
2.29.2
Dec. 14, 2020
Re: [PATCH v2 vkd3d 2/4] vkd3d-shader: Implement basic support for #if and #endif.
by Zebediah Figura (she/her)
On 12/14/20 9:26 AM, Henri Verbeet wrote:
> On Sat, 12 Dec 2020 at 01:57, Zebediah Figura (she/her)
> <zfigura(a)codeweavers.com> wrote:
>> On 12/11/20 12:11 PM, Henri Verbeet wrote:
>>> Is reusing enum vkd3d_shader_error for warnings instead of introducing
>>> a separate enumeration here intentional?
>>>
>>
>> It was intentional, though of course not necessary. I guess my reasoning
>> was that there's no reason to let any numerical values coincide, and
>> hence no reason to bother separating the enumerations...
>
> Fair enough, although it does look a bit odd to pass an enum
> vkd3d_shader_error to vkd3d_shader_warning(). We may want to consider
> starting the preprocessor warning range at e.g. 4200 or 4300 in that
> case though; if we were to add VKD3D_SHADER_LOG_WARNING and
> VKD3D_SHADER_LOG_INFO ranges for all the existing
> VKD3D_SHADER_LOG_ERROR ranges using the current allocation scheme,
> 4-digit error codes would already be insufficient. (And there are
> still some sources/targets we may potentially add; HLSL of course, but
> also GLSL, perhaps MSL, probably DXIL, D3D shader model 1-3 bytecode.)
>
I hadn't thought about keeping error codes four digits long; that makes
sense to me. I'll adjust the numerical values.
Dec. 14, 2020
Re: [PATCH v2 vkd3d 1/4] vkd3d-shader: Handle preprocessor parsing errors.
by Zebediah Figura (she/her)
On 12/14/20 9:26 AM, Henri Verbeet wrote:
> On Sat, 12 Dec 2020 at 01:52, Zebediah Figura (she/her)
> <zfigura(a)codeweavers.com> wrote:
>>
>> On 12/11/20 12:11 PM, Henri Verbeet wrote:
>>> On Fri, 11 Dec 2020 at 00:27, Zebediah Figura <zfigura(a)codeweavers.com> wrote:
>>>> +struct preproc_location
>>>> +{
>>>> + const char *filename;
>>>> + unsigned int first_line, first_column;
>>>> +};
>>>> +
>>>> struct preproc_ctx
>>>> {
>>>> void *scanner;
>>>>
>>>> + struct vkd3d_shader_message_context *message_context;
>>>> struct vkd3d_string_buffer buffer;
>>>> + unsigned int line, column;
>>>> + const char *source_name;
>>>> +
>>>> + bool error;
>>>> };
>>>>
>>> There seems to be some duplication of location information between
>>> struct vkd3d_shader_message_context, struct preproc_ctx, and struct
>>> preproc_location. Is that intentional? If it is, would it make sense
>>> to introduce e.g. a struct vkd3d_shader_source_location instead of
>>> struct preproc_location, and then use that structure in both struct
>>> vkd3d_shader_message_context and struct preproc_ctx?
>>
>> Wrt the vkd3d_shader_message_context part—the current structure
>> definitely isn't a great fit for the preprocessor or HLSL parser (i.e.
>> the parts that use yacc) because the location tracking means that we'll
>> be setting a new location on every error call. (And of course most of
>> the other parsers we have don't really have a meaningful concept of
>> line/column locations...) But I wasn't sure enough to actually try to
>> redesign those parts, and it seemed like something that could be
>> deferred, so I just left it alone...
>>
> I probably haven't looked at this series in enough detail, so I may be
> missing something obvious, but is the issue that we're getting an
> explicit location in yyerror() that may not match the location stored
> in struct preproc_ctx? I think it would be fine to pass an explicit
> location to vkd3d_shader_error() and similar functions as well, and
> moving location tracking out of struct vkd3d_shader_message_context.
yyerror() is one example where we need to preserve a location that's not
the "current" one, but it actually ends up being most errors.
In the case of the HLSL compiler, except for a scant few errors
generated by the lexer, pretty much everything has a location attached
that doesn't match the lexer's current location. This is partly because
of lookahead (e.g. we want to complain about variable attributes on a
function, and have the caret point toward the invalid attribute, but we
don't know which one we've parsed yet), partly because bison makes no
guarantees about where the lexer actually is when a given rule is
parsed, and partly because we report some errors *after* having parsed
the whole file [which we do by saving the locations of code that caused
us to generate instructions and other IR objects].
In the case of the preprocessor, it's a bit odd, because most errors can
be blamed on a malformed or misplaced directive [and so even including
the column in the first place doesn't necessarily make a lot of sense].
It'd be arguably possible to always pass the current line and file name,
except that it'd actually need to be the previous line and file name,
since we've already parsed a newline at that point. But this is also
sort of depending on bison internals that I don't think are guaranteed.
> That probably doesn't need to delay this series, but if that change is
> what we want, it seems easier to make it sooner rather than later.
Well, I did add preproc_error() as a helper (and there are already
similar helpers for the HLSL compiler) so that it wouldn't be too much
of a problem. But it is of course nice to not punt the problem, and it's
not too hard...
>
> It does look like we'd want a struct vkd3d_shader_source_location
> instead of struct preproc_location in that case.
>
>> Wrt preproc_location vs preproc_ctx—part of the rub here is that {line,
>> column} is a bit different from {first_line, first_column}; i.e. if we
>> were to add {last_line, last_column}, that wouldn't be a part of
>> preproc_ctx.
>>
> Hmm, right.
>
Dec. 14, 2020
[PATCH] dbghelp: Fetch version info only for PE modules in minidumps.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/dbghelp/minidump.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Dec. 14, 2020
Re: [PATCH] gdi32/tests: Add tests for zero-width control characters.
by Nikolay Sivov
On 12/14/20 5:53 PM, Sven Baars wrote:
> Signed-off-by: Sven Baars <sbaars(a)codeweavers.com>
> ---
> Some tests with zero-width control characters for inconsistent behavior
> that I observed while trying to fix the ID3DXFont implementation. In our
> implementation these functions all use the same internal function, but on
> Windows none of them seem to do exactly the same.
Have you tried with different fonts? Especially with fonts not shipped
with Windows.
As I remember certain system fonts were updated in Windows 10 to have
empty glyphs for control characters. So what you see and this whole test
might be unnecessary tailored for Tahoma (including broken parts
reflecting font changes across windows releases).
Easy way to test is to use some modified Noto font to see when metrics
are used and when metrics are ignored for certain characters.
Dec. 14, 2020
[PATCH 5/5] winapi: Use __alignof__ on clang.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/gdi32/tests/generated.c | 2 +-
dlls/kernel32/tests/generated.c | 2 +-
dlls/ntdll/tests/generated.c | 2 +-
dlls/rpcrt4/tests/generated.c | 2 +-
dlls/shell32/tests/generated.c | 2 +-
dlls/shlwapi/tests/generated.c | 2 +-
dlls/urlmon/tests/generated.c | 90 +--------------------------------
dlls/user32/tests/generated.c | 2 +-
dlls/wininet/tests/generated.c | 2 +-
dlls/winmm/tests/generated.c | 2 +-
tools/winapi/winapi_test | 2 +-
11 files changed, 11 insertions(+), 99 deletions(-)
Dec. 14, 2020
[PATCH 4/5] msvcrt: Use __ASM_USE_THISCALL_WRAPPER in cxx.h.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/msvcrt/cxx.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Dec. 14, 2020
[PATCH 3/5] msvcrt: Use GCC-style assembly on Clang MSVC target.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/msvcrt/math.c | 14 +++++++-------
dlls/msvcrt/misc.c | 6 +++---
2 files changed, 10 insertions(+), 10 deletions(-)
Dec. 14, 2020
[PATCH 2/5] msvcrt: Prefix *rot* functions.
by Jacek Caban
MSVC does not allow overriding those intrinsic functions.
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/crtdll/crtdll.spec | 8 ++++----
dlls/msvcr100/msvcr100.spec | 12 ++++++------
dlls/msvcr110/msvcr110.spec | 12 ++++++------
dlls/msvcr120/msvcr120.spec | 12 ++++++------
dlls/msvcr70/msvcr70.spec | 8 ++++----
dlls/msvcr71/msvcr71.spec | 8 ++++----
dlls/msvcr80/msvcr80.spec | 12 ++++++------
dlls/msvcr90/msvcr90.spec | 12 ++++++------
dlls/msvcrt/math.c | 12 ++++++------
dlls/msvcrt/msvcrt.spec | 12 ++++++------
dlls/msvcrtd/msvcrtd.spec | 8 ++++----
dlls/ucrtbase/ucrtbase.spec | 12 ++++++------
12 files changed, 64 insertions(+), 64 deletions(-)
Dec. 14, 2020
[PATCH 1/5] ucrtbase: Improve __intrinsic_abnormal_termination stub.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
The real motivation is renaming _abnormal_termination, which is not
allowed on MSVC.
dlls/crtdll/crtdll.spec | 2 +-
dlls/msvcr100/msvcr100.spec | 2 +-
dlls/msvcr110/msvcr110.spec | 2 +-
dlls/msvcr120/msvcr120.spec | 2 +-
dlls/msvcr70/msvcr70.spec | 2 +-
dlls/msvcr71/msvcr71.spec | 2 +-
dlls/msvcr80/msvcr80.spec | 2 +-
dlls/msvcr90/msvcr90.spec | 2 +-
dlls/msvcrt/except.c | 2 +-
dlls/msvcrt/msvcrt.spec | 2 +-
dlls/msvcrtd/msvcrtd.spec | 2 +-
dlls/ucrtbase/ucrtbase.spec | 2 +-
12 files changed, 12 insertions(+), 12 deletions(-)
Dec. 14, 2020
Re: [PATCH] crypt32/tests: Fix a registerOIDInfo() failure when missing elevated privileges.
by Francois Gouget
On Mon, 14 Dec 2020, Dmitry Timoshkov wrote:
[...]
> If the intent to add is_process_elevated() checks to every place where
> ERROR_ACCESS_DENIED error returned then it's not justified.
Ok.
> > > > @@ -645,7 +661,11 @@ static void test_registerOIDInfo(void)
> > > > info1.pszOID = test_oid;
> > > > SetLastError(0xdeadbeef);
> > > > ret = CryptUnregisterOIDInfo(&info1);
> > > > - ok(!ret, "should fail\n");
> > > > + if (!ret && GetLastError() == ERROR_ACCESS_DENIED && !is_process_elevated())
> > > > + {
> > > > + skip("Need admin rights FIXME\n");
> > > > + return;
> > > > + } ok(!ret, "should fail\n");
> > >
> > > This change doesn't look right. Most likely it's not needed here.
> >
> > It is needed:
> > https://test.winehq.org/data/3acb0b3326c4120ea0c4c6076bd03c9cfe82c744/win10…
>
> In addition to broken indentation and strange skip message the test bot
> results seem not related, in both cases !ret is the only accepted value.
Oh, right. I missed the cleanup step and mixed it up with the fix
for another test too. I will resubmit it.
--
Francois Gouget <fgouget(a)codeweavers.com>
Dec. 14, 2020
[PATCH v2 2/2] ntdll: Save unwind information in KiUserApcDispatcher() on x64.
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
v2:
- fix build for other archs.
dlls/ntdll/tests/exception.c | 53 +++++++++++++++++++++++++++++++++
dlls/ntdll/thread.c | 28 ++++++++++++++++-
dlls/ntdll/unix/signal_x86_64.c | 23 ++++++++++++--
3 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 5686e39ab9e..3a0a5ac049c 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -37,6 +37,8 @@ static void *code_mem;
static NTSTATUS (WINAPI *pNtGetContextThread)(HANDLE,CONTEXT*);
static NTSTATUS (WINAPI *pNtSetContextThread)(HANDLE,CONTEXT*);
+static NTSTATUS (WINAPI *pNtQueueApcThread)(HANDLE handle, PNTAPCFUNC func,
+ ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3);
static NTSTATUS (WINAPI *pRtlRaiseException)(EXCEPTION_RECORD *rec);
static PVOID (WINAPI *pRtlUnwind)(PVOID, PVOID, PEXCEPTION_RECORD, PVOID);
static VOID (WINAPI *pRtlCaptureContext)(CONTEXT*);
@@ -4061,6 +4063,55 @@ static void test_nested_exception(void)
ok(got_prev_frame_exception, "Did not get nested exception in the previous frame.\n");
}
+static CONTEXT test_unwind_apc_context;
+static BOOL test_unwind_apc_called;
+
+static void CALLBACK test_unwind_apc(ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3)
+{
+ EXCEPTION_RECORD rec;
+
+ test_unwind_apc_called = TRUE;
+ memset(&rec, 0, sizeof(rec));
+ pRtlUnwind((void *)test_unwind_apc_context.Rsp, (void *)test_unwind_apc_context.Rip, &rec, (void *)0xdeadbeef);
+ ok(0, "Should not get here.\n");
+}
+
+static void test_unwind_from_apc(void)
+{
+ NTSTATUS status;
+ int pass;
+
+ if (!pNtQueueApcThread)
+ {
+ win_skip("NtQueueApcThread is not available.\n");
+ return;
+ }
+
+ pass = 0;
+ InterlockedIncrement(&pass);
+ RtlCaptureContext(&test_unwind_apc_context);
+ InterlockedIncrement(&pass);
+
+ if (pass == 2)
+ {
+ test_unwind_apc_called = FALSE;
+ status = pNtQueueApcThread(GetCurrentThread(), test_unwind_apc, 0, 0, 0);
+ ok(!status, "Got unexpected status %#x.\n", status);
+ SleepEx(0, TRUE);
+ ok(0, "Should not get here.\n");
+ }
+ if (pass == 3)
+ {
+ ok(test_unwind_apc_called, "Test user APC was not called.\n");
+ test_unwind_apc_called = FALSE;
+ status = pNtQueueApcThread(GetCurrentThread(), test_unwind_apc, 0, 0, 0);
+ ok(!status, "Got unexpected status %#x.\n", status);
+ NtContinue(&test_unwind_apc_context, TRUE );
+ ok(0, "Should not get here.\n");
+ }
+ ok(pass == 4, "Got unexpected pass %d.\n", pass);
+ ok(test_unwind_apc_called, "Test user APC was not called.\n");
+}
#elif defined(__arm__)
static void test_thread_context(void)
@@ -8073,6 +8124,7 @@ START_TEST(exception)
#define X(f) p##f = (void*)GetProcAddress(hntdll, #f)
X(NtGetContextThread);
X(NtSetContextThread);
+ X(NtQueueApcThread);
X(NtReadVirtualMemory);
X(NtClose);
X(RtlUnwind);
@@ -8241,6 +8293,7 @@ START_TEST(exception)
skip( "Dynamic unwind functions not found\n" );
test_extended_context();
test_copy_context();
+ test_unwind_from_apc();
#elif defined(__aarch64__)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 578c7a5436c..5bf456ec040 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -78,7 +78,7 @@ int __cdecl __wine_dbg_output( const char *str )
/*******************************************************************
* KiUserApcDispatcher (NTDLL.@)
*/
-void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
+void WINAPI dispatch_apc( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
PNTAPCFUNC func )
{
func( ctx, arg1, arg2 );
@@ -86,6 +86,32 @@ void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1
}
+#ifdef __x86_64__
+__ASM_GLOBAL_FUNC( KiUserApcDispatcher,
+ "addq $0x8,%rsp\n\t"
+ "mov 0x98(%rcx),%r10\n\t" /* context->Rsp */
+ "mov 0xf8(%rcx),%r11\n\t" /* context->Rip */
+ "mov %r11,-0x8(%r10)\n\t"
+ "mov %rbp,-0x10(%r10)\n\t"
+ "lea -0x10(%r10),%rbp\n\t"
+ __ASM_SEH(".seh_pushreg %rbp\n\t")
+ __ASM_SEH(".seh_setframe %rbp,0\n\t")
+ __ASM_SEH(".seh_endprologue\n\t")
+ __ASM_CFI(".cfi_signal_frame\n\t")
+ __ASM_CFI(".cfi_adjust_cfa_offset 0x10\n\t")
+ __ASM_CFI(".cfi_def_cfa %rbp,0x10\n\t")
+ __ASM_CFI(".cfi_rel_offset %rip,0x8\n\t")
+ __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
+ "call " __ASM_NAME("dispatch_apc") "\n\t"
+ "int3")
+#else
+void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
+ PNTAPCFUNC func )
+{
+ dispatch_apc( context, ctx, arg1, arg2, func );
+}
+#endif
+
/***********************************************************************
* RtlExitUserThread (NTDLL.@)
*/
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 09088b75750..4a03f3b3bac 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2076,9 +2076,28 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movq %r14,%r9\n" /* arg2 */
"movq $0,0x328(%rbx)\n\t" /* amd64_thread_data()->syscall_frame */
"movq %rsi,0x20(%rsp)\n\t" /* func */
- "movq 0xa0(%rcx),%rbp\n\t" /* context.Rbp */
+ "movq %rdi,%r10\n\t"
+ /* Set nonvolatile regs from context. */
+ "movq 0xa0(%rcx),%rbp\n\t"
+ "movq 0x90(%rcx),%rbx\n\t"
+ "movq 0xa8(%rcx),%rsi\n\t"
+ "movq 0xb0(%rcx),%rdi\n\t"
+ "movq 0xd8(%rcx),%r12\n\t"
+ "movq 0xe0(%rcx),%r13\n\t"
+ "movq 0xe8(%rcx),%r14\n\t"
+ "movq 0xf0(%rcx),%r15\n\t"
+ "movdqa 0x200(%rcx),%xmm6\n\t"
+ "movdqa 0x210(%rcx),%xmm7\n\t"
+ "movdqa 0x220(%rcx),%xmm8\n\t"
+ "movdqa 0x230(%rcx),%xmm9\n\t"
+ "movdqa 0x240(%rcx),%xmm10\n\t"
+ "movdqa 0x250(%rcx),%xmm11\n\t"
+ "movdqa 0x260(%rcx),%xmm12\n\t"
+ "movdqa 0x270(%rcx),%xmm13\n\t"
+ "movdqa 0x280(%rcx),%xmm14\n\t"
+ "movdqa 0x290(%rcx),%xmm15\n\t"
"pushq 0xf8(%rcx)\n\t" /* context.Rip */
- "jmp *%rdi" )
+ "jmp *%r10" )
/***********************************************************************
--
2.29.2
Dec. 14, 2020
[PATCH v2 1/2] ntdll: Always copy context in call_user_apc_dispatcher() on x64.
by Paul Gofman
Currently, if call_user_apc_dispatcher() is called with nonzero context,
there is no guarantee that the provided context is stored above the
rsp = context_ptr->Rsp - (sizeof(CONTEXT) + offsetof(frame,ret_addr))
being set.
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/unix/signal_x86_64.c | 61 +++++++++++++++++++++++++--------
1 file changed, 47 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 359f2d7c361..09088b75750 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -254,6 +254,22 @@ C_ASSERT((offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout)))
C_ASSERT( sizeof(XSTATE) == 0x140 );
C_ASSERT( sizeof(struct stack_layout) == 0x5b0 ); /* Should match the size in call_user_exception_dispatcher(). */
+/* stack layout when calling an user apc function.
+ * FIXME: match Windows ABI. */
+struct apc_stack_layout
+{
+ ULONG64 save_regs[4];
+ void *func;
+ ULONG64 align;
+ CONTEXT context;
+ ULONG64 rbp;
+ ULONG64 rip;
+};
+
+/* Should match size and offset in call_user_apc_dispatcher(). */
+C_ASSERT( offsetof(struct apc_stack_layout, context) == 0x30 );
+C_ASSERT( sizeof(struct apc_stack_layout) == 0x510 );
+
struct syscall_frame
{
ULONG64 xmm[10 * 2]; /* xmm6-xmm15 */
@@ -270,6 +286,9 @@ struct syscall_frame
ULONG64 ret_addr;
};
+/* Should match the offset in call_user_apc_dispatcher(). */
+C_ASSERT( offsetof( struct syscall_frame, ret_addr ) == 0xf0);
+
struct amd64_thread_data
{
DWORD_PTR dr0; /* 02f0 debug registers */
@@ -2017,31 +2036,45 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
/***********************************************************************
* call_user_apc_dispatcher
*/
+struct apc_stack_layout * WINAPI setup_user_apc_dispatcher_stack( CONTEXT *context, struct apc_stack_layout *stack )
+{
+ CONTEXT c;
+
+ if (!context)
+ {
+ c.ContextFlags = CONTEXT_FULL;
+ NtGetContextThread( GetCurrentThread(), &c );
+ context = &c;
+ }
+ memmove( &stack->context, context, sizeof(stack->context) );
+ return stack;
+}
+
__ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movq 0x28(%rsp),%rsi\n\t" /* func */
"movq 0x30(%rsp),%rdi\n\t" /* dispatcher */
"movq %gs:0x30,%rbx\n\t"
- "jrcxz 1f\n\t"
- "movq 0x98(%rcx),%rax\n\t" /* context_ptr->Rsp */
- "leaq -0x5c0(%rax),%rsp\n\t" /* sizeof(CONTEXT) + offsetof(frame,ret_addr) */
- "andq $~15,%rsp\n\t"
- "jmp 2f\n"
- "1:\tmovq 0x328(%rbx),%rax\n\t" /* amd64_thread_data()->syscall_frame */
- "leaq -0x4d0(%rax),%rsp\n\t"
- "andq $~15,%rsp\n\t"
"movq %rdx,%r12\n\t" /* ctx */
"movq %r8,%r13\n\t" /* arg1 */
"movq %r9,%r14\n\t" /* arg2 */
- "movq %rsp,%rdx\n\t" /* context */
- "movl $0x10000b,0x30(%rdx)\n\t" /* context.ContextFlags */
- "movq $~1,%rcx\n\t"
- "call " __ASM_NAME("NtGetContextThread") "\n\t"
- "movq %rsp,%rcx\n\t" /* context */
+ "jrcxz 1f\n\t"
+ "movq 0x98(%rcx),%rdx\n\t" /* context->Rsp */
+ "jmp 2f\n\t"
+ "1:\tmovq 0x328(%rbx),%rax\n\t" /* amd64_thread_data()->syscall_frame */
+ "leaq 0xf0(%rax),%rdx\n\t" /* &amd64_thread_data()->syscall_frame->ret_addr */
+ "2:\tsubq $0x510,%rdx\n\t" /* sizeof(struct apc_stack_layout) */
+ "andq $~0xf,%rdx\n\t"
+ "cmpq %rsp,%rdx\n\t"
+ "cmovbq %rdx,%rsp\n\t"
+ "subq $0x18,%rsp\n\t"
+ "call " __ASM_NAME("setup_user_apc_dispatcher_stack") "\n\t"
+ "movq %rax,%rsp\n\t"
+ "leaq 0x30(%rsp),%rcx\n\t" /* context */
"movq $0xc0,0x78(%rcx)\n\t" /* context.Rax = STATUS_USER_APC */
"movq %r12,%rdx\n\t" /* ctx */
"movq %r13,%r8\n\t" /* arg1 */
"movq %r14,%r9\n" /* arg2 */
- "2:\tmovq $0,0x328(%rbx)\n\t"
+ "movq $0,0x328(%rbx)\n\t" /* amd64_thread_data()->syscall_frame */
"movq %rsi,0x20(%rsp)\n\t" /* func */
"movq 0xa0(%rcx),%rbp\n\t" /* context.Rbp */
"pushq 0xf8(%rcx)\n\t" /* context.Rip */
--
2.29.2
Dec. 14, 2020
Re: [PATCH 2/2] ntdll: Save unwind information in KiUserApcDispatcher() on x64.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=83408
Your paranoid android.
=== debiant (build log) ===
../wine/dlls/ntdll/thread.c:111:5: error: too few arguments to function ‘dispatch_apc’
Task: The win32 Wine build failed
=== debiant (build log) ===
../wine/dlls/ntdll/thread.c:111:5: error: too few arguments to function ‘dispatch_apc’
Task: The wow32 Wine build failed
Dec. 14, 2020
[PATCH 2/2] ntdll: Save unwind information in KiUserApcDispatcher() on x64.
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/tests/exception.c | 53 +++++++++++++++++++++++++++++++++
dlls/ntdll/thread.c | 28 ++++++++++++++++-
dlls/ntdll/unix/signal_x86_64.c | 23 ++++++++++++--
3 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 5686e39ab9e..3a0a5ac049c 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -37,6 +37,8 @@ static void *code_mem;
static NTSTATUS (WINAPI *pNtGetContextThread)(HANDLE,CONTEXT*);
static NTSTATUS (WINAPI *pNtSetContextThread)(HANDLE,CONTEXT*);
+static NTSTATUS (WINAPI *pNtQueueApcThread)(HANDLE handle, PNTAPCFUNC func,
+ ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3);
static NTSTATUS (WINAPI *pRtlRaiseException)(EXCEPTION_RECORD *rec);
static PVOID (WINAPI *pRtlUnwind)(PVOID, PVOID, PEXCEPTION_RECORD, PVOID);
static VOID (WINAPI *pRtlCaptureContext)(CONTEXT*);
@@ -4061,6 +4063,55 @@ static void test_nested_exception(void)
ok(got_prev_frame_exception, "Did not get nested exception in the previous frame.\n");
}
+static CONTEXT test_unwind_apc_context;
+static BOOL test_unwind_apc_called;
+
+static void CALLBACK test_unwind_apc(ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3)
+{
+ EXCEPTION_RECORD rec;
+
+ test_unwind_apc_called = TRUE;
+ memset(&rec, 0, sizeof(rec));
+ pRtlUnwind((void *)test_unwind_apc_context.Rsp, (void *)test_unwind_apc_context.Rip, &rec, (void *)0xdeadbeef);
+ ok(0, "Should not get here.\n");
+}
+
+static void test_unwind_from_apc(void)
+{
+ NTSTATUS status;
+ int pass;
+
+ if (!pNtQueueApcThread)
+ {
+ win_skip("NtQueueApcThread is not available.\n");
+ return;
+ }
+
+ pass = 0;
+ InterlockedIncrement(&pass);
+ RtlCaptureContext(&test_unwind_apc_context);
+ InterlockedIncrement(&pass);
+
+ if (pass == 2)
+ {
+ test_unwind_apc_called = FALSE;
+ status = pNtQueueApcThread(GetCurrentThread(), test_unwind_apc, 0, 0, 0);
+ ok(!status, "Got unexpected status %#x.\n", status);
+ SleepEx(0, TRUE);
+ ok(0, "Should not get here.\n");
+ }
+ if (pass == 3)
+ {
+ ok(test_unwind_apc_called, "Test user APC was not called.\n");
+ test_unwind_apc_called = FALSE;
+ status = pNtQueueApcThread(GetCurrentThread(), test_unwind_apc, 0, 0, 0);
+ ok(!status, "Got unexpected status %#x.\n", status);
+ NtContinue(&test_unwind_apc_context, TRUE );
+ ok(0, "Should not get here.\n");
+ }
+ ok(pass == 4, "Got unexpected pass %d.\n", pass);
+ ok(test_unwind_apc_called, "Test user APC was not called.\n");
+}
#elif defined(__arm__)
static void test_thread_context(void)
@@ -8073,6 +8124,7 @@ START_TEST(exception)
#define X(f) p##f = (void*)GetProcAddress(hntdll, #f)
X(NtGetContextThread);
X(NtSetContextThread);
+ X(NtQueueApcThread);
X(NtReadVirtualMemory);
X(NtClose);
X(RtlUnwind);
@@ -8241,6 +8293,7 @@ START_TEST(exception)
skip( "Dynamic unwind functions not found\n" );
test_extended_context();
test_copy_context();
+ test_unwind_from_apc();
#elif defined(__aarch64__)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 578c7a5436c..c5dcb931ba5 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -78,7 +78,7 @@ int __cdecl __wine_dbg_output( const char *str )
/*******************************************************************
* KiUserApcDispatcher (NTDLL.@)
*/
-void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
+void WINAPI dispatch_apc( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
PNTAPCFUNC func )
{
func( ctx, arg1, arg2 );
@@ -86,6 +86,32 @@ void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1
}
+#ifdef __x86_64__
+__ASM_GLOBAL_FUNC( KiUserApcDispatcher,
+ "addq $0x8,%rsp\n\t"
+ "mov 0x98(%rcx),%r10\n\t" /* context->Rsp */
+ "mov 0xf8(%rcx),%r11\n\t" /* context->Rip */
+ "mov %r11,-0x8(%r10)\n\t"
+ "mov %rbp,-0x10(%r10)\n\t"
+ "lea -0x10(%r10),%rbp\n\t"
+ __ASM_SEH(".seh_pushreg %rbp\n\t")
+ __ASM_SEH(".seh_setframe %rbp,0\n\t")
+ __ASM_SEH(".seh_endprologue\n\t")
+ __ASM_CFI(".cfi_signal_frame\n\t")
+ __ASM_CFI(".cfi_adjust_cfa_offset 0x10\n\t")
+ __ASM_CFI(".cfi_def_cfa %rbp,0x10\n\t")
+ __ASM_CFI(".cfi_rel_offset %rip,0x8\n\t")
+ __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
+ "call " __ASM_NAME("dispatch_apc") "\n\t"
+ "int3")
+#else
+void WINAPI KiUserApcDispatcher( CONTEXT *context, ULONG_PTR ctx, ULONG_PTR arg1, ULONG_PTR arg2,
+ PNTAPCFUNC func )
+{
+ dispatch_apc();
+}
+#endif
+
/***********************************************************************
* RtlExitUserThread (NTDLL.@)
*/
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 09088b75750..4a03f3b3bac 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2076,9 +2076,28 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movq %r14,%r9\n" /* arg2 */
"movq $0,0x328(%rbx)\n\t" /* amd64_thread_data()->syscall_frame */
"movq %rsi,0x20(%rsp)\n\t" /* func */
- "movq 0xa0(%rcx),%rbp\n\t" /* context.Rbp */
+ "movq %rdi,%r10\n\t"
+ /* Set nonvolatile regs from context. */
+ "movq 0xa0(%rcx),%rbp\n\t"
+ "movq 0x90(%rcx),%rbx\n\t"
+ "movq 0xa8(%rcx),%rsi\n\t"
+ "movq 0xb0(%rcx),%rdi\n\t"
+ "movq 0xd8(%rcx),%r12\n\t"
+ "movq 0xe0(%rcx),%r13\n\t"
+ "movq 0xe8(%rcx),%r14\n\t"
+ "movq 0xf0(%rcx),%r15\n\t"
+ "movdqa 0x200(%rcx),%xmm6\n\t"
+ "movdqa 0x210(%rcx),%xmm7\n\t"
+ "movdqa 0x220(%rcx),%xmm8\n\t"
+ "movdqa 0x230(%rcx),%xmm9\n\t"
+ "movdqa 0x240(%rcx),%xmm10\n\t"
+ "movdqa 0x250(%rcx),%xmm11\n\t"
+ "movdqa 0x260(%rcx),%xmm12\n\t"
+ "movdqa 0x270(%rcx),%xmm13\n\t"
+ "movdqa 0x280(%rcx),%xmm14\n\t"
+ "movdqa 0x290(%rcx),%xmm15\n\t"
"pushq 0xf8(%rcx)\n\t" /* context.Rip */
- "jmp *%rdi" )
+ "jmp *%r10" )
/***********************************************************************
--
2.29.2
Dec. 14, 2020
[PATCH 1/2] ntdll: Always copy context in call_user_apc_dispatcher() on x64.
by Paul Gofman
Currently, if call_user_apc_dispatcher() is called with nonzero context,
there is no guarantee that the provided context is stored above the
rsp = context_ptr->Rsp - (sizeof(CONTEXT) + offsetof(frame,ret_addr))
being set.
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/unix/signal_x86_64.c | 61 +++++++++++++++++++++++++--------
1 file changed, 47 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 359f2d7c361..09088b75750 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -254,6 +254,22 @@ C_ASSERT((offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout)))
C_ASSERT( sizeof(XSTATE) == 0x140 );
C_ASSERT( sizeof(struct stack_layout) == 0x5b0 ); /* Should match the size in call_user_exception_dispatcher(). */
+/* stack layout when calling an user apc function.
+ * FIXME: match Windows ABI. */
+struct apc_stack_layout
+{
+ ULONG64 save_regs[4];
+ void *func;
+ ULONG64 align;
+ CONTEXT context;
+ ULONG64 rbp;
+ ULONG64 rip;
+};
+
+/* Should match size and offset in call_user_apc_dispatcher(). */
+C_ASSERT( offsetof(struct apc_stack_layout, context) == 0x30 );
+C_ASSERT( sizeof(struct apc_stack_layout) == 0x510 );
+
struct syscall_frame
{
ULONG64 xmm[10 * 2]; /* xmm6-xmm15 */
@@ -270,6 +286,9 @@ struct syscall_frame
ULONG64 ret_addr;
};
+/* Should match the offset in call_user_apc_dispatcher(). */
+C_ASSERT( offsetof( struct syscall_frame, ret_addr ) == 0xf0);
+
struct amd64_thread_data
{
DWORD_PTR dr0; /* 02f0 debug registers */
@@ -2017,31 +2036,45 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
/***********************************************************************
* call_user_apc_dispatcher
*/
+struct apc_stack_layout * WINAPI setup_user_apc_dispatcher_stack( CONTEXT *context, struct apc_stack_layout *stack )
+{
+ CONTEXT c;
+
+ if (!context)
+ {
+ c.ContextFlags = CONTEXT_FULL;
+ NtGetContextThread( GetCurrentThread(), &c );
+ context = &c;
+ }
+ memmove( &stack->context, context, sizeof(stack->context) );
+ return stack;
+}
+
__ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movq 0x28(%rsp),%rsi\n\t" /* func */
"movq 0x30(%rsp),%rdi\n\t" /* dispatcher */
"movq %gs:0x30,%rbx\n\t"
- "jrcxz 1f\n\t"
- "movq 0x98(%rcx),%rax\n\t" /* context_ptr->Rsp */
- "leaq -0x5c0(%rax),%rsp\n\t" /* sizeof(CONTEXT) + offsetof(frame,ret_addr) */
- "andq $~15,%rsp\n\t"
- "jmp 2f\n"
- "1:\tmovq 0x328(%rbx),%rax\n\t" /* amd64_thread_data()->syscall_frame */
- "leaq -0x4d0(%rax),%rsp\n\t"
- "andq $~15,%rsp\n\t"
"movq %rdx,%r12\n\t" /* ctx */
"movq %r8,%r13\n\t" /* arg1 */
"movq %r9,%r14\n\t" /* arg2 */
- "movq %rsp,%rdx\n\t" /* context */
- "movl $0x10000b,0x30(%rdx)\n\t" /* context.ContextFlags */
- "movq $~1,%rcx\n\t"
- "call " __ASM_NAME("NtGetContextThread") "\n\t"
- "movq %rsp,%rcx\n\t" /* context */
+ "jrcxz 1f\n\t"
+ "movq 0x98(%rcx),%rdx\n\t" /* context->Rsp */
+ "jmp 2f\n\t"
+ "1:\tmovq 0x328(%rbx),%rax\n\t" /* amd64_thread_data()->syscall_frame */
+ "leaq 0xf0(%rax),%rdx\n\t" /* &amd64_thread_data()->syscall_frame->ret_addr */
+ "2:\tsubq $0x510,%rdx\n\t" /* sizeof(struct apc_stack_layout) */
+ "andq $~0xf,%rdx\n\t"
+ "cmpq %rsp,%rdx\n\t"
+ "cmovbq %rdx,%rsp\n\t"
+ "subq $0x18,%rsp\n\t"
+ "call " __ASM_NAME("setup_user_apc_dispatcher_stack") "\n\t"
+ "movq %rax,%rsp\n\t"
+ "leaq 0x30(%rsp),%rcx\n\t" /* context */
"movq $0xc0,0x78(%rcx)\n\t" /* context.Rax = STATUS_USER_APC */
"movq %r12,%rdx\n\t" /* ctx */
"movq %r13,%r8\n\t" /* arg1 */
"movq %r14,%r9\n" /* arg2 */
- "2:\tmovq $0,0x328(%rbx)\n\t"
+ "movq $0,0x328(%rbx)\n\t" /* amd64_thread_data()->syscall_frame */
"movq %rsi,0x20(%rsp)\n\t" /* func */
"movq 0xa0(%rcx),%rbp\n\t" /* context.Rbp */
"pushq 0xf8(%rcx)\n\t" /* context.Rip */
--
2.29.2
Dec. 14, 2020
Re: [PATCH] crypt32/tests: Fix a registerOIDInfo() failure when missing elevated privileges.
by Dmitry Timoshkov
Francois Gouget <fgouget(a)codeweavers.com> wrote:
> > > @@ -499,7 +515,7 @@ static void test_getDefaultOIDFunctionAddress(void)
> > > SetLastError(0xdeadbeef);
> > > ret = CryptRegisterDefaultOIDFunction(0, "CertDllOpenStoreProv", 0,
> > > bogusDll);
> > > - if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
> > > + if (!ret && GetLastError() == ERROR_ACCESS_DENIED && !is_process_elevated())
> > > skip("Need admin rights\n");
> > > else
> > > ok(ret, "CryptRegisterDefaultOIDFunction failed: %08x\n", GetLastError());
> >
> > In which cases the changes above are needed? It seems that this only
> > complicates things without a reason and could potentially slow down
> > the tests execution.
>
> These are not strictly needed. Rather the goal is to verify that we only
> get ERROR_ACCESS_DENIED when missing elevated privileges rather than
> blindly assuming the access denied error is justified.
If the intent to add is_process_elevated() checks to every place where
ERROR_ACCESS_DENIED error returned then it's not justified.
> > > @@ -645,7 +661,11 @@ static void test_registerOIDInfo(void)
> > > info1.pszOID = test_oid;
> > > SetLastError(0xdeadbeef);
> > > ret = CryptUnregisterOIDInfo(&info1);
> > > - ok(!ret, "should fail\n");
> > > + if (!ret && GetLastError() == ERROR_ACCESS_DENIED && !is_process_elevated())
> > > + {
> > > + skip("Need admin rights FIXME\n");
> > > + return;
> > > + } ok(!ret, "should fail\n");
> >
> > This change doesn't look right. Most likely it's not needed here.
>
> It is needed:
> https://test.winehq.org/data/3acb0b3326c4120ea0c4c6076bd03c9cfe82c744/win10…
In addition to broken indentation and strange skip message the test bot
results seem not related, in both cases !ret is the only accepted value.
--
Dmitry.
Dec. 14, 2020
Re: [PATCH v2 vkd3d 2/4] vkd3d-shader: Implement basic support for #if and #endif.
by Henri Verbeet
On Sat, 12 Dec 2020 at 01:57, Zebediah Figura (she/her)
<zfigura(a)codeweavers.com> wrote:
> On 12/11/20 12:11 PM, Henri Verbeet wrote:
> > Is reusing enum vkd3d_shader_error for warnings instead of introducing
> > a separate enumeration here intentional?
> >
>
> It was intentional, though of course not necessary. I guess my reasoning
> was that there's no reason to let any numerical values coincide, and
> hence no reason to bother separating the enumerations...
Fair enough, although it does look a bit odd to pass an enum
vkd3d_shader_error to vkd3d_shader_warning(). We may want to consider
starting the preprocessor warning range at e.g. 4200 or 4300 in that
case though; if we were to add VKD3D_SHADER_LOG_WARNING and
VKD3D_SHADER_LOG_INFO ranges for all the existing
VKD3D_SHADER_LOG_ERROR ranges using the current allocation scheme,
4-digit error codes would already be insufficient. (And there are
still some sources/targets we may potentially add; HLSL of course, but
also GLSL, perhaps MSL, probably DXIL, D3D shader model 1-3 bytecode.)
Dec. 14, 2020
Re: [PATCH v2 vkd3d 1/4] vkd3d-shader: Handle preprocessor parsing errors.
by Henri Verbeet
On Sat, 12 Dec 2020 at 01:52, Zebediah Figura (she/her)
<zfigura(a)codeweavers.com> wrote:
>
> On 12/11/20 12:11 PM, Henri Verbeet wrote:
> > On Fri, 11 Dec 2020 at 00:27, Zebediah Figura <zfigura(a)codeweavers.com> wrote:
> >> +struct preproc_location
> >> +{
> >> + const char *filename;
> >> + unsigned int first_line, first_column;
> >> +};
> >> +
> >> struct preproc_ctx
> >> {
> >> void *scanner;
> >>
> >> + struct vkd3d_shader_message_context *message_context;
> >> struct vkd3d_string_buffer buffer;
> >> + unsigned int line, column;
> >> + const char *source_name;
> >> +
> >> + bool error;
> >> };
> >>
> > There seems to be some duplication of location information between
> > struct vkd3d_shader_message_context, struct preproc_ctx, and struct
> > preproc_location. Is that intentional? If it is, would it make sense
> > to introduce e.g. a struct vkd3d_shader_source_location instead of
> > struct preproc_location, and then use that structure in both struct
> > vkd3d_shader_message_context and struct preproc_ctx?
>
> Wrt the vkd3d_shader_message_context part—the current structure
> definitely isn't a great fit for the preprocessor or HLSL parser (i.e.
> the parts that use yacc) because the location tracking means that we'll
> be setting a new location on every error call. (And of course most of
> the other parsers we have don't really have a meaningful concept of
> line/column locations...) But I wasn't sure enough to actually try to
> redesign those parts, and it seemed like something that could be
> deferred, so I just left it alone...
>
I probably haven't looked at this series in enough detail, so I may be
missing something obvious, but is the issue that we're getting an
explicit location in yyerror() that may not match the location stored
in struct preproc_ctx? I think it would be fine to pass an explicit
location to vkd3d_shader_error() and similar functions as well, and
moving location tracking out of struct vkd3d_shader_message_context.
That probably doesn't need to delay this series, but if that change is
what we want, it seems easier to make it sooner rather than later.
It does look like we'd want a struct vkd3d_shader_source_location
instead of struct preproc_location in that case.
> Wrt preproc_location vs preproc_ctx—part of the rub here is that {line,
> column} is a bit different from {first_line, first_column}; i.e. if we
> were to add {last_line, last_column}, that wouldn't be a part of
> preproc_ctx.
>
Hmm, right.
Dec. 14, 2020
Re: [PATCH] crypt32/tests: Fix a registerOIDInfo() failure when missing elevated privileges.
by Francois Gouget
On Mon, 14 Dec 2020, Dmitry Timoshkov wrote:
> Francois Gouget <fgouget(a)codeweavers.com> wrote:
>
> > @@ -314,7 +330,7 @@ static void test_registerOIDFunction(void)
> > SetLastError(0xdeadbeef);
> > ret = CryptRegisterOIDFunction(X509_ASN_ENCODING, "CryptDllEncodeObject",
> > "1.2.3.4.5.6.7.8.9.10", bogusDll, NULL);
> > - if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
> > + if (!ret && GetLastError() == ERROR_ACCESS_DENIED && !is_process_elevated())
> > {
> > skip("Need admin rights\n");
> > return;
> > @@ -393,7 +409,7 @@ static void test_registerDefaultOIDFunction(void)
> > SetLastError(0xdeadbeef);
> > ret = CryptRegisterDefaultOIDFunction(0, "CertDllOpenStoreProv", 0,
> > bogusDll);
> > - if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
> > + if (!ret && GetLastError() == ERROR_ACCESS_DENIED && !is_process_elevated())
> > {
> > skip("Need admin rights\n");
> > return;
> > @@ -499,7 +515,7 @@ static void test_getDefaultOIDFunctionAddress(void)
> > SetLastError(0xdeadbeef);
> > ret = CryptRegisterDefaultOIDFunction(0, "CertDllOpenStoreProv", 0,
> > bogusDll);
> > - if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
> > + if (!ret && GetLastError() == ERROR_ACCESS_DENIED && !is_process_elevated())
> > skip("Need admin rights\n");
> > else
> > ok(ret, "CryptRegisterDefaultOIDFunction failed: %08x\n", GetLastError());
>
> In which cases the changes above are needed? It seems that this only
> complicates things without a reason and could potentially slow down
> the tests execution.
These are not strictly needed. Rather the goal is to verify that we only
get ERROR_ACCESS_DENIED when missing elevated privileges rather than
blindly assuming the access denied error is justified.
> > @@ -645,7 +661,11 @@ static void test_registerOIDInfo(void)
> > info1.pszOID = test_oid;
> > SetLastError(0xdeadbeef);
> > ret = CryptUnregisterOIDInfo(&info1);
> > - ok(!ret, "should fail\n");
> > + if (!ret && GetLastError() == ERROR_ACCESS_DENIED && !is_process_elevated())
> > + {
> > + skip("Need admin rights FIXME\n");
> > + return;
> > + } ok(!ret, "should fail\n");
>
> This change doesn't look right. Most likely it's not needed here.
It is needed:
https://test.winehq.org/data/3acb0b3326c4120ea0c4c6076bd03c9cfe82c744/win10…
--
Francois Gouget <fgouget(a)codeweavers.com>
Dec. 14, 2020