Wine-devel
Threads by month
- ----- 2026 -----
- 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
November 2019
- 85 participants
- 778 discussions
[PATCH v2 1/2] vkd3d: Deal correctly with SM 5.1 register spaces.
by Hans-Kristian Arntzen 26 Nov '19
by Hans-Kristian Arntzen 26 Nov '19
26 Nov '19
Resource index is found in idx[0] in SM 5.0, but idx[1] when using SM
5.1, and register space is encoded reparately. An rb_tree keeps track of
the internal resource index idx[0] and can map that to space/binding as
required when emitting SPIR-V.
For this to work, we must also make UAV counters register space aware.
In earlier implementation, UAV counter mask was assumed to correlate 1:1
with register_index, which breaks on SM 5.1.
Signed-off-by: Hans-Kristian Arntzen <post(a)arntzen-software.no>
---
include/vkd3d_shader.h | 22 +++
libs/vkd3d-shader/dxbc.c | 29 ++++
libs/vkd3d-shader/spirv.c | 193 ++++++++++++++++++++---
libs/vkd3d-shader/vkd3d_shader_private.h | 5 +
libs/vkd3d/command.c | 32 ++--
libs/vkd3d/state.c | 50 ++++--
libs/vkd3d/vkd3d_private.h | 1 +
7 files changed, 290 insertions(+), 42 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 6b4d3f5..e07d420 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -35,6 +35,7 @@ enum vkd3d_shader_structure_type
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO,
VKD3D_SHADER_STRUCTURE_TYPE_DOMAIN_SHADER_COMPILE_ARGUMENTS,
+ VKD3D_SHADER_STRUCTURE_TYPE_EFFECTIVE_UAV_COUNTER_BINDING_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
};
@@ -138,6 +139,7 @@ struct vkd3d_shader_parameter
struct vkd3d_shader_resource_binding
{
enum vkd3d_shader_descriptor_type type;
+ unsigned int register_space;
unsigned int register_index;
enum vkd3d_shader_visibility shader_visibility;
unsigned int flags; /* vkd3d_shader_binding_flags */
@@ -159,8 +161,10 @@ struct vkd3d_shader_combined_resource_sampler
struct vkd3d_shader_uav_counter_binding
{
+ unsigned int register_space;
unsigned int register_index; /* u# */
enum vkd3d_shader_visibility shader_visibility;
+ unsigned int counter_index;
struct vkd3d_shader_descriptor_binding binding;
unsigned int offset;
@@ -168,6 +172,7 @@ struct vkd3d_shader_uav_counter_binding
struct vkd3d_shader_push_constant_buffer
{
+ unsigned int register_space;
unsigned int register_index;
enum vkd3d_shader_visibility shader_visibility;
@@ -215,6 +220,17 @@ struct vkd3d_shader_transform_feedback_info
unsigned int buffer_stride_count;
};
+/* Extends vkd3d_shader_interface_info. */
+struct vkd3d_shader_effective_uav_counter_binding_info
+{
+ enum vkd3d_shader_structure_type type;
+ const void *next;
+
+ unsigned int *uav_register_spaces;
+ unsigned int *uav_register_bindings;
+ unsigned int uav_counter_count;
+};
+
enum vkd3d_shader_target
{
VKD3D_SHADER_TARGET_NONE,
@@ -536,6 +552,12 @@ struct vkd3d_versioned_root_signature_desc
/* FIXME: Add support for 64 UAV bind slots. */
#define VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS 8
+struct vkd3d_shader_scan_info_binding
+{
+ unsigned int register_space;
+ unsigned int register_idx;
+};
+
struct vkd3d_shader_scan_info
{
enum vkd3d_shader_structure_type type;
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 98c51e4..b3f53ab 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -624,6 +624,10 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins,
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.semantic.register_space);
+ if (shader_is_sm_5_1(priv))
+ ins->declaration.semantic.register_index = ins->declaration.semantic.reg.reg.idx[1].offset;
+ else
+ ins->declaration.semantic.register_index = ins->declaration.semantic.reg.reg.idx[0].offset;
}
static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction *ins,
@@ -647,9 +651,12 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction
return;
}
+ ins->declaration.cb.register_index = ins->declaration.cb.src.reg.idx[1].offset;
ins->declaration.cb.size = *tokens++;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.cb.register_space);
}
+ else
+ ins->declaration.cb.register_index = ins->declaration.cb.src.reg.idx[0].offset;
}
static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins,
@@ -663,6 +670,10 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins,
FIXME("Unhandled sampler mode %#x.\n", ins->flags);
shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_SAMPLER, &ins->declaration.sampler.src);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.sampler.register_space);
+ if (shader_is_sm_5_1(priv))
+ ins->declaration.sampler.register_index = ins->declaration.sampler.src.reg.idx[1].offset;
+ else
+ ins->declaration.sampler.register_index = ins->declaration.sampler.src.reg.idx[0].offset;
}
static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins,
@@ -863,6 +874,10 @@ static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins,
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &ins->declaration.raw_resource.dst);
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.raw_resource.register_space);
+ if (shader_is_sm_5_1(priv))
+ ins->declaration.raw_resource.register_index = ins->declaration.raw_resource.dst.reg.idx[1].offset;
+ else
+ ins->declaration.raw_resource.register_index = ins->declaration.raw_resource.dst.reg.idx[0].offset;
}
static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction *ins,
@@ -874,9 +889,14 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction *
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &ins->declaration.structured_resource.reg);
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
ins->declaration.structured_resource.byte_stride = *tokens;
+ tokens++;
if (ins->declaration.structured_resource.byte_stride % 4)
FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.structured_resource.register_space);
+ if (shader_is_sm_5_1(priv))
+ ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[1].offset;
+ else
+ ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[0].offset;
}
static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins,
@@ -909,9 +929,14 @@ static void shader_sm5_read_dcl_resource_structured(struct vkd3d_shader_instruct
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &ins->declaration.structured_resource.reg);
ins->declaration.structured_resource.byte_stride = *tokens;
+ tokens++;
if (ins->declaration.structured_resource.byte_stride % 4)
FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.structured_resource.register_space);
+ if (shader_is_sm_5_1(priv))
+ ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[1].offset;
+ else
+ ins->declaration.structured_resource.register_index = ins->declaration.structured_resource.reg.reg.idx[0].offset;
}
static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *ins,
@@ -922,6 +947,10 @@ static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *in
shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &ins->declaration.dst);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.raw_resource.register_space);
+ if (shader_is_sm_5_1(priv))
+ ins->declaration.raw_resource.register_index = ins->declaration.dst.reg.idx[1].offset;
+ else
+ ins->declaration.raw_resource.register_index = ins->declaration.dst.reg.idx[0].offset;
}
static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins,
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index a949e4a..f6e96bd 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1890,6 +1890,20 @@ struct vkd3d_symbol
} info;
};
+struct vkd3d_sm51_symbol_key
+{
+ enum vkd3d_shader_descriptor_type descriptor_type;
+ unsigned int idx;
+};
+
+struct vkd3d_sm51_symbol
+{
+ struct rb_entry entry;
+ struct vkd3d_sm51_symbol_key key;
+ unsigned int register_space;
+ unsigned int resource_idx;
+};
+
static int vkd3d_symbol_compare(const void *key, const struct rb_entry *entry)
{
const struct vkd3d_symbol *a = key;
@@ -1900,6 +1914,13 @@ static int vkd3d_symbol_compare(const void *key, const struct rb_entry *entry)
return memcmp(&a->key, &b->key, sizeof(a->key));
}
+static int vkd3d_sm51_symbol_compare(const void *key, const struct rb_entry *entry)
+{
+ const struct vkd3d_sm51_symbol_key *a = key;
+ const struct vkd3d_sm51_symbol *b = RB_ENTRY_VALUE(entry, const struct vkd3d_sm51_symbol, entry);
+ return memcmp(a, &b->key, sizeof(*a));
+}
+
static void vkd3d_symbol_free(struct rb_entry *entry, void *context)
{
struct vkd3d_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
@@ -1907,6 +1928,13 @@ static void vkd3d_symbol_free(struct rb_entry *entry, void *context)
vkd3d_free(s);
}
+static void vkd3d_sm51_symbol_free(struct rb_entry *entry, void *context)
+{
+ struct vkd3d_sm51_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_sm51_symbol, entry);
+
+ vkd3d_free(s);
+}
+
static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol,
const struct vkd3d_shader_register *reg)
{
@@ -2052,6 +2080,7 @@ struct vkd3d_hull_shader_variables
struct vkd3d_dxbc_compiler
{
+ struct vkd3d_shader_version shader_version;
struct vkd3d_spirv_builder spirv_builder;
uint32_t options;
@@ -2062,6 +2091,8 @@ struct vkd3d_dxbc_compiler
struct vkd3d_hull_shader_variables hs;
uint32_t sample_positions_id;
+ struct rb_tree sm51_resource_table;
+
enum vkd3d_shader_type shader_type;
unsigned int branch_id;
@@ -2107,6 +2138,11 @@ struct vkd3d_dxbc_compiler
size_t spec_constants_size;
};
+static bool shader_is_sm_5_1(const struct vkd3d_dxbc_compiler *compiler)
+{
+ return (compiler->shader_version.major * 100 + compiler->shader_version.minor) >= 501;
+}
+
static bool is_control_point_phase(const struct vkd3d_shader_phase *phase)
{
return phase && phase->type == VKD3DSIH_HS_CONTROL_POINT_PHASE;
@@ -2131,6 +2167,8 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
memset(compiler, 0, sizeof(*compiler));
+ compiler->shader_version = *shader_version;
+
max_element_count = max(output_signature->element_count, patch_constant_signature->element_count);
if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info))))
{
@@ -2142,6 +2180,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
compiler->options = compiler_options;
rb_init(&compiler->symbol_table, vkd3d_symbol_compare);
+ rb_init(&compiler->sm51_resource_table, vkd3d_sm51_symbol_compare);
compiler->shader_type = shader_version->type;
@@ -2227,9 +2266,10 @@ static bool vkd3d_dxbc_compiler_check_shader_visibility(const struct vkd3d_dxbc_
}
static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_constant_buffer(
- const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg)
+ const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_constant_buffer *cb)
{
- unsigned int reg_idx = reg->idx[0].offset;
+ unsigned int reg_idx = cb->register_index;
+ unsigned int reg_space = cb->register_space;
unsigned int i;
for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i)
@@ -2239,7 +2279,7 @@ static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_
if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->pc.shader_visibility))
continue;
- if (current->pc.register_index == reg_idx)
+ if (current->pc.register_index == reg_idx && current->pc.register_space == reg_space)
return current;
}
@@ -2274,6 +2314,49 @@ static bool vkd3d_dxbc_compiler_has_combined_sampler(const struct vkd3d_dxbc_com
return false;
}
+static bool vkd3d_get_binding_info_for_register(
+ struct vkd3d_dxbc_compiler *compiler,
+ const struct vkd3d_shader_register *reg,
+ unsigned int *reg_space, unsigned int *reg_binding)
+{
+ const struct vkd3d_sm51_symbol *symbol;
+ struct vkd3d_sm51_symbol_key key;
+ const struct rb_entry *entry;
+
+ if (shader_is_sm_5_1(compiler))
+ {
+ key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN;
+ if (reg->type == VKD3DSPR_CONSTBUFFER)
+ key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
+ else if (reg->type == VKD3DSPR_RESOURCE)
+ key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
+ else if (reg->type == VKD3DSPR_UAV)
+ key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
+ else if (reg->type == VKD3DSPR_SAMPLER)
+ key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
+ else
+ FIXME("Unhandled register type %#x.\n", reg->type);
+
+ key.idx = reg->idx[0].offset;
+ entry = rb_get(&compiler->sm51_resource_table, &key);
+ if (entry)
+ {
+ symbol = RB_ENTRY_VALUE(entry, const struct vkd3d_sm51_symbol, entry);
+ *reg_space = symbol->register_space;
+ *reg_binding = symbol->resource_idx;
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ {
+ *reg_space = 0;
+ *reg_binding = reg->idx[0].offset;
+ return true;
+ }
+}
+
static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding(
struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg,
enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
@@ -2282,8 +2365,9 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
enum vkd3d_shader_descriptor_type descriptor_type;
enum vkd3d_shader_binding_flag resource_type_flag;
struct vkd3d_shader_descriptor_binding binding;
- unsigned int reg_idx = reg->idx[0].offset;
unsigned int i;
+ unsigned int reg_space;
+ unsigned int reg_idx;
descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN;
if (reg->type == VKD3DSPR_CONSTBUFFER)
@@ -2300,6 +2384,11 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER
? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
+ if (!vkd3d_get_binding_info_for_register(compiler, reg, ®_space, ®_idx))
+ {
+ ERR("Failed to find binding for resource type %#x.\n", reg->type);
+ }
+
if (is_uav_counter)
{
assert(descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV);
@@ -2313,8 +2402,19 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
if (current->offset)
FIXME("Atomic counter offsets are not supported yet.\n");
- if (current->register_index == reg_idx)
+ /* Do not use space/binding, but just the plain index here, since that's how the UAV counter mask is exposed. */
+ if (current->register_index == reg->idx[0].offset)
+ {
+ /* Let pipeline know what the actual space/bindings for the counter are. */
+ const struct vkd3d_shader_effective_uav_counter_binding_info *binding_info =
+ vkd3d_find_struct(shader_interface->next, EFFECTIVE_UAV_COUNTER_BINDING_INFO);
+ if (binding_info && current->register_index < binding_info->uav_counter_count)
+ {
+ binding_info->uav_register_spaces[current->register_index] = reg_space;
+ binding_info->uav_register_bindings[current->register_index] = reg_idx;
+ }
return current->binding;
+ }
}
if (shader_interface->uav_counter_count)
FIXME("Could not find descriptor binding for UAV counter %u.\n", reg_idx);
@@ -2331,7 +2431,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->shader_visibility))
continue;
- if (current->type == descriptor_type && current->register_index == reg_idx)
+ if (current->type == descriptor_type && current->register_index == reg_idx && current->register_space == reg_space)
return current->binding;
}
if (shader_interface->binding_count)
@@ -2825,7 +2925,8 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp
{
assert(!reg->idx[0].rel_addr);
indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx);
- indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[1]);
+ indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler,
+ ®->idx[shader_is_sm_5_1(compiler) ? 2 : 1]);
}
else if (reg->type == VKD3DSPR_IMMCONSTBUFFER)
{
@@ -2835,6 +2936,11 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp
{
indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[1]);
}
+ else if (reg->type == VKD3DSPR_SAMPLER)
+ {
+ /* SM 5.1 will have an index here referring to something which we throw away. */
+ index_count = 0;
+ }
else if (register_info->is_aggregate)
{
struct vkd3d_shader_register_index reg_idx = reg->idx[0];
@@ -4957,10 +5063,19 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi
assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC));
- if (cb->register_space)
- FIXME("Unhandled register space %u.\n", cb->register_space);
+ if (shader_is_sm_5_1(compiler))
+ {
+ struct vkd3d_sm51_symbol *sym;
+ sym = vkd3d_calloc(1, sizeof(*sym));
+ sym->key.idx = reg->idx[0].offset;
+ sym->key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
+ sym->register_space = instruction->declaration.sampler.register_space;
+ sym->resource_idx = instruction->declaration.sampler.register_index;
+ if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
+ vkd3d_free(sym);
+ }
- if ((push_cb = vkd3d_dxbc_compiler_find_push_constant_buffer(compiler, reg)))
+ if ((push_cb = vkd3d_dxbc_compiler_find_push_constant_buffer(compiler, cb)))
{
/* Push constant buffers are handled in
* vkd3d_dxbc_compiler_emit_push_constant_buffers().
@@ -5042,8 +5157,17 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com
uint32_t type_id, ptr_type_id, var_id;
struct vkd3d_symbol reg_symbol;
- if (instruction->declaration.sampler.register_space)
- FIXME("Unhandled register space %u.\n", instruction->declaration.sampler.register_space);
+ if (shader_is_sm_5_1(compiler))
+ {
+ struct vkd3d_sm51_symbol *sym;
+ sym = vkd3d_calloc(1, sizeof(*sym));
+ sym->key.idx = reg->idx[0].offset;
+ sym->key.descriptor_type = VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
+ sym->register_space = instruction->declaration.sampler.register_space;
+ sym->resource_idx = instruction->declaration.sampler.register_index;
+ if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
+ vkd3d_free(sym);
+ }
if (vkd3d_dxbc_compiler_has_combined_sampler(compiler, NULL, reg))
return;
@@ -5054,7 +5178,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com
ptr_type_id, storage_class, 0);
vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler,
- var_id, reg, VKD3D_SHADER_RESOURCE_NONE, false);
+ var_id, reg,VKD3D_SHADER_RESOURCE_NONE, false);
vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
@@ -5264,8 +5388,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource(struct vkd3d_dxbc_compiler *co
{
const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic;
- if (semantic->register_space)
- FIXME("Unhandled register space %u.\n", semantic->register_space);
+ if (shader_is_sm_5_1(compiler))
+ {
+ struct vkd3d_sm51_symbol *sym;
+ sym = vkd3d_calloc(1, sizeof(*sym));
+ sym->key.idx = semantic->reg.reg.idx[0].offset;
+ sym->key.descriptor_type = semantic->reg.reg.type == VKD3DSPR_UAV ? VKD3D_SHADER_DESCRIPTOR_TYPE_UAV : VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
+ sym->register_space = semantic->register_space;
+ sym->resource_idx = semantic->register_index;
+ if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
+ vkd3d_free(sym);
+ }
+
if (instruction->flags)
FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
@@ -5278,8 +5412,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_raw(struct vkd3d_dxbc_compiler
{
const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource;
- if (resource->register_space)
- FIXME("Unhandled register space %u.\n", resource->register_space);
+ if (shader_is_sm_5_1(compiler))
+ {
+ struct vkd3d_sm51_symbol *sym;
+ sym = vkd3d_calloc(1, sizeof(*sym));
+ sym->key.idx = resource->dst.reg.idx[0].offset;
+ sym->key.descriptor_type = resource->dst.reg.type == VKD3DSPR_UAV ? VKD3D_SHADER_DESCRIPTOR_TYPE_UAV : VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
+ sym->register_space = resource->register_space;
+ sym->resource_idx = resource->register_index;
+ if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
+ vkd3d_free(sym);
+ }
+
if (instruction->flags)
FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
@@ -5294,8 +5438,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_structured(struct vkd3d_dxbc_c
const struct vkd3d_shader_register *reg = &resource->reg.reg;
unsigned int stride = resource->byte_stride;
- if (resource->register_space)
- FIXME("Unhandled register space %u.\n", resource->register_space);
+ if (shader_is_sm_5_1(compiler))
+ {
+ struct vkd3d_sm51_symbol *sym;
+ sym = vkd3d_calloc(1, sizeof(*sym));
+ sym->key.idx = resource->reg.reg.idx[0].offset;
+ sym->key.descriptor_type = resource->reg.reg.type == VKD3DSPR_UAV ? VKD3D_SHADER_DESCRIPTOR_TYPE_UAV : VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
+ sym->register_space = resource->register_space;
+ sym->resource_idx = resource->register_index;
+ if (rb_put(&compiler->sm51_resource_table, &sym->key, &sym->entry) == -1)
+ vkd3d_free(sym);
+ }
+
if (instruction->flags)
FIXME("Unhandled UAV flags %#x.\n", instruction->flags);
@@ -8709,6 +8863,7 @@ void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler)
vkd3d_spirv_builder_free(&compiler->spirv_builder);
rb_destroy(&compiler->symbol_table, vkd3d_symbol_free, NULL);
+ rb_destroy(&compiler->sm51_resource_table, vkd3d_sm51_symbol_free, NULL);
vkd3d_free(compiler->shader_phases);
vkd3d_free(compiler->spec_constants);
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 940cb76..1c052a0 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -615,6 +615,7 @@ struct vkd3d_shader_semantic
enum vkd3d_data_type resource_data_type;
struct vkd3d_shader_dst_param reg;
unsigned int register_space;
+ unsigned int register_index;
};
enum vkd3d_shader_input_sysval_semantic
@@ -662,6 +663,7 @@ struct vkd3d_shader_register_semantic
struct vkd3d_shader_sampler
{
struct vkd3d_shader_src_param src;
+ unsigned int register_index;
unsigned int register_space;
};
@@ -669,6 +671,7 @@ struct vkd3d_shader_constant_buffer
{
struct vkd3d_shader_src_param src;
unsigned int size;
+ unsigned int register_index;
unsigned int register_space;
};
@@ -676,12 +679,14 @@ struct vkd3d_shader_structured_resource
{
struct vkd3d_shader_dst_param reg;
unsigned int byte_stride;
+ unsigned int register_index;
unsigned int register_space;
};
struct vkd3d_shader_raw_resource
{
struct vkd3d_shader_dst_param dst;
+ unsigned int register_index;
unsigned int register_space;
};
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 297054b..4aad3e7 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -2654,7 +2654,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
const struct d3d12_root_descriptor_table *descriptor_table;
const struct d3d12_root_descriptor_table_range *range;
VkDevice vk_device = list->device->vk_device;
- unsigned int i, j, descriptor_count;
+ unsigned int i, j, k, descriptor_count;
struct d3d12_desc *descriptor;
descriptor_table = root_signature_get_descriptor_table(root_signature, index);
@@ -2677,14 +2677,26 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
unsigned int register_idx = range->base_register_idx + j;
/* Track UAV counters. */
- if (range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_UAV
- && register_idx < ARRAY_SIZE(bindings->vk_uav_counter_views))
+ if (list->state->uav_counter_mask != 0 && range->descriptor_magic == VKD3D_DESCRIPTOR_MAGIC_UAV)
{
- VkBufferView vk_counter_view = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV
- ? descriptor->u.view->vk_counter_view : VK_NULL_HANDLE;
- if (bindings->vk_uav_counter_views[register_idx] != vk_counter_view)
- bindings->uav_counter_dirty_mask |= 1u << register_idx;
- bindings->vk_uav_counter_views[register_idx] = vk_counter_view;
+ const struct vkd3d_shader_uav_counter_binding *counter_bindings = list->state->uav_counters;
+ for (k = 0; k < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; k++)
+ {
+ if ((list->state->uav_counter_mask & (1u << k)))
+ {
+ if (counter_bindings->register_space == range->register_space &&
+ counter_bindings->register_index == register_idx)
+ {
+ VkBufferView vk_counter_view = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV
+ ? descriptor->u.view->vk_counter_view : VK_NULL_HANDLE;
+ if (bindings->vk_uav_counter_views[k] != vk_counter_view)
+ bindings->uav_counter_dirty_mask |= 1u << k;
+ bindings->vk_uav_counter_views[k] = vk_counter_view;
+ break;
+ }
+ counter_bindings++;
+ }
+ }
}
if (!vk_write_descriptor_set_from_d3d12_desc(current_descriptor_write,
@@ -2840,7 +2852,7 @@ static void d3d12_command_list_update_uav_counter_descriptors(struct d3d12_comma
const struct vkd3d_shader_uav_counter_binding *uav_counter = &state->uav_counters[i];
const VkBufferView *vk_uav_counter_views = bindings->vk_uav_counter_views;
- assert(vk_uav_counter_views[uav_counter->register_index]);
+ assert(vk_uav_counter_views[uav_counter->counter_index]);
vk_descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
vk_descriptor_writes[i].pNext = NULL;
@@ -2851,7 +2863,7 @@ static void d3d12_command_list_update_uav_counter_descriptors(struct d3d12_comma
vk_descriptor_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
vk_descriptor_writes[i].pImageInfo = NULL;
vk_descriptor_writes[i].pBufferInfo = NULL;
- vk_descriptor_writes[i].pTexelBufferView = &vk_uav_counter_views[uav_counter->register_index];
+ vk_descriptor_writes[i].pTexelBufferView = &vk_uav_counter_views[uav_counter->counter_index];
}
VK_CALL(vkUpdateDescriptorSets(vk_device, uav_counter_count, vk_descriptor_writes, 0, NULL));
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index a321fa4..1a18e8a 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -308,12 +308,6 @@ static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutB
= vk_descriptor_type_from_d3d12_range_type(descriptor_range->RangeType, is_buffer);
binding_desc->descriptorCount = 1;
- if (descriptor_range->RegisterSpace)
- {
- FIXME("Unhandled register space %u.\n", descriptor_range->RegisterSpace);
- return false;
- }
-
binding_desc->stageFlags = stage_flags_from_visibility(shader_visibility);
binding_desc->pImmutableSamplers = NULL;
@@ -509,6 +503,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
? push_constants[0].stageFlags : stage_flags_from_visibility(p->ShaderVisibility);
root_constant->offset = offset;
+ root_signature->root_constants[j].register_space = p->u.Constants.RegisterSpace;
root_signature->root_constants[j].register_index = p->u.Constants.ShaderRegister;
root_signature->root_constants[j].shader_visibility
= vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility);
@@ -532,7 +527,7 @@ struct vkd3d_descriptor_set_context
};
static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature,
- enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_idx,
+ enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int register_idx,
bool buffer_descriptor, enum vkd3d_shader_visibility shader_visibility,
struct vkd3d_descriptor_set_context *context)
{
@@ -540,6 +535,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
= &root_signature->descriptor_mapping[context->descriptor_index++];
mapping->type = descriptor_type;
+ mapping->register_space = register_space;
mapping->register_index = register_idx;
mapping->shader_visibility = shader_visibility;
mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
@@ -548,7 +544,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
}
static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature,
- enum vkd3d_shader_descriptor_type descriptor_type, unsigned int base_register_idx,
+ enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int base_register_idx,
unsigned int binding_count, bool is_buffer_descriptor, bool duplicate_descriptors,
enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context)
{
@@ -565,10 +561,10 @@ static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signat
{
if (duplicate_descriptors)
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type,
- base_register_idx + i, true, shader_visibility, context);
+ register_space, base_register_idx + i, true, shader_visibility, context);
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type,
- base_register_idx + i, is_buffer_descriptor, shader_visibility, context);
+ register_space, base_register_idx + i, is_buffer_descriptor, shader_visibility, context);
}
return first_binding;
}
@@ -624,7 +620,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
vk_binding = d3d12_root_signature_assign_vk_bindings(root_signature,
vkd3d_descriptor_type_from_d3d12_range_type(range->RangeType),
- range->BaseShaderRegister, range->NumDescriptors, false, true,
+ range->RegisterSpace, range->BaseShaderRegister, range->NumDescriptors, false, true,
vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context);
/* Unroll descriptor range. */
@@ -657,6 +653,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
table->ranges[j].binding = vk_binding;
table->ranges[j].descriptor_magic = vkd3d_descriptor_magic_from_d3d12(range->RangeType);
table->ranges[j].base_register_idx = range->BaseShaderRegister;
+ table->ranges[j].register_space = range->RegisterSpace;
}
}
@@ -690,7 +687,7 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature,
vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType),
- p->u.Descriptor.ShaderRegister, 1, true, false,
+ p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1, true, false,
vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context);
cur_binding->descriptorType = vk_descriptor_type_from_d3d12_root_parameter(p->ParameterType);
cur_binding->descriptorCount = 1;
@@ -727,7 +724,7 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa
return hr;
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature,
- VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->ShaderRegister, 1, false, false,
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->RegisterSpace, s->ShaderRegister, 1, false, false,
vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), context);
cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
cur_binding->descriptorCount = 1;
@@ -1419,7 +1416,14 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel
if (!(shader_info->uav_counter_mask & (1u << i)))
continue;
+ /* UAV counters will lookup Vulkan bindings based on the mask index directly.
+ * We currently don't know the actual space/binding for this UAV,
+ * but register_space/register_index are fixed up later after compilation is finished. */
+ state->uav_counters[j].register_space = 0;
state->uav_counters[j].register_index = i;
+
+ state->uav_counters[j].counter_index = i;
+
state->uav_counters[j].shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE;
state->uav_counters[j].binding.set = context.set_index;
state->uav_counters[j].binding.binding = context.descriptor_binding;
@@ -1476,6 +1480,10 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
VkResult vr;
HRESULT hr;
int ret;
+ unsigned int i, j;
+ unsigned int uav_counter_spaces[VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS] = { 0 };
+ unsigned int uav_counter_bindings[VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS] = { 0 };
+ struct vkd3d_shader_effective_uav_counter_binding_info uav_binding_info = { VKD3D_SHADER_STRUCTURE_TYPE_EFFECTIVE_UAV_COUNTER_BINDING_INFO };
state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl;
state->refcount = 1;
@@ -1519,6 +1527,11 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
shader_interface.uav_counters = state->uav_counters;
shader_interface.uav_counter_count = vkd3d_popcount(state->uav_counter_mask);
+ shader_interface.next = &uav_binding_info;
+ uav_binding_info.uav_register_spaces = uav_counter_spaces;
+ uav_binding_info.uav_register_bindings = uav_counter_bindings;
+ uav_binding_info.uav_counter_count = VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS;
+
pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
pipeline_info.pNext = NULL;
pipeline_info.flags = 0;
@@ -1562,6 +1575,17 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
return hr;
}
+ /* Map back to actual space/bindings for the UAV counter now that we know. */
+ for (i = 0, j = 0; i < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; i++)
+ {
+ if (state->uav_counter_mask & (1u << i))
+ {
+ state->uav_counters[j].register_space = uav_counter_spaces[i];
+ state->uav_counters[j].register_index = uav_counter_bindings[i];
+ j++;
+ }
+ }
+
state->vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
d3d12_device_add_ref(state->device = device);
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 76ce709..56d130e 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -642,6 +642,7 @@ struct d3d12_root_descriptor_table_range
uint32_t descriptor_magic;
unsigned int base_register_idx;
+ unsigned int register_space;
};
struct d3d12_root_descriptor_table
--
2.24.0
2
3
[PATCH] comctl32: allocate the right wstr size for the TVN_GETDISPINFOW reply
by Damjan Jovanovic 26 Nov '19
by Damjan Jovanovic 26 Nov '19
26 Nov '19
The code doesn't multiply the strlenW() by sizeof(WCHAR),
allocating a buffer that is half the needed size, and
resulting in a guaranteed buffer overflow and heap corruption
when lstrcpyW() later copies the string.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=25264
Signed-off-by: Damjan Jovanovic <damjan.jov(a)gmail.com>
---
dlls/comctl32/treeview.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
2
1
[PATCH 1/2] ddraw: Fix conversion of v1 viewport from v2 in d3d_viewport_GetViewport().
by Paul Gofman 26 Nov '19
by Paul Gofman 26 Nov '19
26 Nov '19
Spotted in https://bugs.winehq.org/show_bug.cgi?id=19471.
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
dlls/ddraw/tests/ddraw4.c | 84 +++++++++++++++++++++++++++++----------
dlls/ddraw/viewport.c | 13 +++---
2 files changed, 70 insertions(+), 27 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index e61d67d723..ffa510a8b3 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -1619,13 +1619,13 @@ static void test_viewport_object(void)
return;
}
hr = IDirect3DDevice3_GetDirect3D(device, &d3d);
- ok(SUCCEEDED(hr), "Failed to get Direct3D3 interface, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
hr = IDirect3D3_QueryInterface(d3d, &IID_IDirectDraw4, (void **)&ddraw);
- ok(SUCCEEDED(hr), "Failed to get DirectDraw4 interface, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
old_d3d_ref = get_refcount((IUnknown *) d3d);
hr = IDirect3D3_CreateViewport(d3d, &viewport3, NULL);
- ok(SUCCEEDED(hr), "Failed to create viewport, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *)viewport3);
ok(ref == 1, "Got unexpected refcount %u.\n", ref);
ref = get_refcount((IUnknown *)d3d);
@@ -1654,11 +1654,11 @@ static void test_viewport_object(void)
gamma = (IDirectDrawGammaControl *)0xdeadbeef;
hr = IDirect3DViewport2_QueryInterface(viewport3, &IID_IDirectDrawGammaControl, (void **)&gamma);
ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
- ok(!gamma, "Interface not set to NULL by failed QI call: %p\n", gamma);
+ ok(!gamma, "Interface not set to NULL by failed QI call: %p.\n", gamma);
/* NULL iid: Segfaults */
hr = IDirect3DViewport3_QueryInterface(viewport3, &IID_IDirect3DViewport, (void **)&viewport);
- ok(SUCCEEDED(hr), "Failed to QI IDirect3DViewport, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *)viewport);
ok(ref == 2, "Got unexpected refcount %u.\n", ref);
ref = get_refcount((IUnknown *)viewport3);
@@ -1667,7 +1667,7 @@ static void test_viewport_object(void)
viewport = NULL;
hr = IDirect3DViewport3_QueryInterface(viewport3, &IID_IDirect3DViewport3, (void **)&viewport2);
- ok(SUCCEEDED(hr), "Failed to QI IDirect3DViewport3, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *)viewport2);
ok(ref == 2, "Got unexpected refcount %u.\n", ref);
ref = get_refcount((IUnknown *)viewport3);
@@ -1675,7 +1675,7 @@ static void test_viewport_object(void)
IDirect3DViewport3_Release(viewport2);
hr = IDirect3DViewport3_QueryInterface(viewport3, &IID_IUnknown, (void **)&unknown);
- ok(SUCCEEDED(hr), "Failed to QI IUnknown, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *)viewport3);
ok(ref == 2, "Got unexpected refcount %u.\n", ref);
ref = get_refcount(unknown);
@@ -1688,7 +1688,7 @@ static void test_viewport_object(void)
ok(hr == D3DERR_NOCURRENTVIEWPORT, "Got unexpected hr %#x.\n", hr);
hr = IDirect3D3_CreateViewport(d3d, &another_vp, NULL);
- ok(SUCCEEDED(hr), "Failed to create viewport, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
/* Setting a viewport not in the viewport list fails */
hr = IDirect3DDevice3_SetCurrentViewport(device, another_vp);
@@ -1696,21 +1696,21 @@ static void test_viewport_object(void)
/* AddViewport(NULL): Segfault */
hr = IDirect3DDevice3_AddViewport(device, viewport3);
- ok(SUCCEEDED(hr), "Failed to add viewport to device, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *) viewport3);
ok(ref == 2, "Got unexpected refcount %u.\n", ref);
hr = IDirect3DDevice3_AddViewport(device, another_vp);
- ok(SUCCEEDED(hr), "Failed to add viewport to device, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *) another_vp);
ok(ref == 2, "Got unexpected refcount %u.\n", ref);
test_vp = (IDirect3DViewport3 *) 0xbaadc0de;
hr = IDirect3DDevice3_GetCurrentViewport(device, &test_vp);
ok(hr == D3DERR_NOCURRENTVIEWPORT, "Got unexpected hr %#x.\n", hr);
- ok(test_vp == (IDirect3DViewport3 *) 0xbaadc0de, "Got unexpected pointer %p\n", test_vp);
+ ok(test_vp == (IDirect3DViewport3 *) 0xbaadc0de, "Got unexpected pointer %p.\n", test_vp);
hr = IDirect3DDevice3_SetCurrentViewport(device, viewport3);
- ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *) viewport3);
ok(ref == 3, "Got unexpected refcount %u.\n", ref);
ref = get_refcount((IUnknown *) device);
@@ -1719,7 +1719,7 @@ static void test_viewport_object(void)
test_vp = NULL;
hr = IDirect3DDevice3_GetCurrentViewport(device, &test_vp);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- ok(test_vp == viewport3, "Got unexpected viewport %p\n", test_vp);
+ ok(test_vp == viewport3, "Got unexpected viewport %p.\n", test_vp);
ref = get_refcount((IUnknown *) viewport3);
ok(ref == 4, "Got unexpected refcount %u.\n", ref);
if (test_vp)
@@ -1729,17 +1729,17 @@ static void test_viewport_object(void)
/* Cannot set the viewport to NULL */
hr = IDirect3DDevice3_SetCurrentViewport(device, NULL);
- ok(hr == DDERR_INVALIDPARAMS, "Failed to set viewport to NULL, hr %#x.\n", hr);
+ ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
test_vp = NULL;
hr = IDirect3DDevice3_GetCurrentViewport(device, &test_vp);
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
- ok(test_vp == viewport3, "Got unexpected viewport %p\n", test_vp);
+ ok(test_vp == viewport3, "Got unexpected viewport %p.\n", test_vp);
if (test_vp)
IDirect3DViewport3_Release(test_vp);
/* SetCurrentViewport properly releases the old viewport's reference */
hr = IDirect3DDevice3_SetCurrentViewport(device, another_vp);
- ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *) viewport3);
ok(ref == 2, "Got unexpected refcount %u.\n", ref);
ref = get_refcount((IUnknown *) another_vp);
@@ -1748,7 +1748,7 @@ static void test_viewport_object(void)
/* Unlike device2::DeleteViewport, device3::DeleteViewport releases the
* reference held by SetCurrentViewport */
hr = IDirect3DDevice3_DeleteViewport(device, another_vp);
- ok(SUCCEEDED(hr), "Failed to delete viewport from device, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *) another_vp);
ok(ref == 1, "Got unexpected refcount %u.\n", ref);
@@ -1756,11 +1756,11 @@ static void test_viewport_object(void)
test_vp = NULL;
hr = IDirect3DDevice3_GetCurrentViewport(device, &test_vp);
ok(hr == D3DERR_NOCURRENTVIEWPORT, "Got unexpected hr %#x.\n", hr);
- ok(!test_vp, "Got unexpected viewport %p\n", test_vp);
+ ok(!test_vp, "Got unexpected viewport %p.\n", test_vp);
/* Setting a different viewport doesn't have any surprises now */
hr = IDirect3DDevice3_SetCurrentViewport(device, viewport3);
- ok(SUCCEEDED(hr), "Failed to set current viewport, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
ref = get_refcount((IUnknown *) viewport3);
ok(ref == 3, "Got unexpected refcount %u.\n", ref);
ref = get_refcount((IUnknown *) another_vp);
@@ -1790,10 +1790,52 @@ static void test_viewport_object(void)
vp.dwSize = sizeof(vp);
hr = IDirect3DViewport3_SetViewport(viewport3, &vp);
- ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
vp2.dwSize = sizeof(vp2);
hr = IDirect3DViewport3_SetViewport2(viewport3, &vp2);
- ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x.\n", hr);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+ vp2.dwSize = sizeof(vp2);
+ vp2.dwX = 160;
+ vp2.dwY = 120;
+ vp2.dwWidth = 640 - vp2.dwX;
+ vp2.dwHeight = 480 - vp2.dwY;
+ vp2.dvClipX = 2.0f;
+ vp2.dvClipY = -1.75f;
+ vp2.dvClipWidth = 2.5f;
+ vp2.dvClipHeight = -1.5f;
+ vp2.dvMinZ = 0.5f;
+ vp2.dvMaxZ = 2.0f;
+ hr = IDirect3DViewport3_SetViewport2(viewport3, &vp2);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+ memset(&vp, 0xff, sizeof(vp));
+ vp.dwSize = sizeof(vp);
+ hr = IDirect3DViewport3_GetViewport(viewport3, &vp);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+ ok(vp.dvMaxX == 4.5f && vp.dvMaxY == -1.75f && vp.dvScaleX == 192.0f
+ && vp.dvScaleY == -240.0f && vp.dvMinZ == 0.0f && vp.dvMaxZ == 1.0f,
+ "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
+ vp.dvMaxX, vp.dvMaxY, vp.dvScaleX, vp.dvScaleY, vp.dvMinZ, vp.dvMaxZ);
+
+ vp2.dvClipX = -1.5f;
+ vp2.dvClipY = 1.75f;
+ vp2.dvClipWidth = -1.5f;
+ vp2.dvClipHeight = 2.0f;
+ vp2.dvMinZ = 2.0f;
+ vp2.dvMaxZ = 0.5f;
+
+ hr = IDirect3DViewport3_SetViewport2(viewport3, &vp2);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+ memset(&vp, 0xff, sizeof(vp));
+ vp.dwSize = sizeof(vp);
+ hr = IDirect3DViewport3_GetViewport(viewport3, &vp);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+ ok(vp.dvMaxX == -3.0f && vp.dvMaxY == 1.75f && vp.dvScaleX == -320.0f
+ && vp.dvScaleY == 180.0f && vp.dvMinZ == 0.0f && vp.dvMaxZ == 1.0f,
+ "Got unexpected values %g, %g, %g, %g, %g, %g.\n",
+ vp.dvMaxX, vp.dvMaxY, vp.dvScaleX, vp.dvScaleY, vp.dvMinZ, vp.dvMaxZ);
/* Destroying the device removes the viewport and releases the reference */
IDirect3DDevice3_Release(device);
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c
index 5fc7a4b2be..ceb5582524 100644
--- a/dlls/ddraw/viewport.c
+++ b/dlls/ddraw/viewport.c
@@ -350,12 +350,13 @@ static HRESULT WINAPI d3d_viewport_GetViewport(IDirect3DViewport3 *iface, D3DVIE
vp1.dwY = viewport->viewports.vp2.dwY;
vp1.dwWidth = viewport->viewports.vp2.dwWidth;
vp1.dwHeight = viewport->viewports.vp2.dwHeight;
- vp1.dvMaxX = 0.0f;
- vp1.dvMaxY = 0.0f;
- vp1.dvScaleX = 0.0f;
- vp1.dvScaleY = 0.0f;
- vp1.dvMinZ = viewport->viewports.vp2.dvMinZ;
- vp1.dvMaxZ = viewport->viewports.vp2.dvMaxZ;
+
+ vp1.dvScaleX = vp1.dwWidth / viewport->viewports.vp2.dvClipWidth;
+ vp1.dvScaleY = vp1.dwHeight / viewport->viewports.vp2.dvClipHeight;
+ vp1.dvMaxX = viewport->viewports.vp2.dvClipWidth + viewport->viewports.vp2.dvClipX;
+ vp1.dvMaxY = viewport->viewports.vp2.dvClipY;
+ vp1.dvMinZ = 0.0f;
+ vp1.dvMaxZ = 1.0f;
memcpy(vp, &vp1, size);
}
--
2.23.0
2
3
Signed-off-by: Chip Davis <cdavis(a)codeweavers.com>
---
dlls/ntdll/nt.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index b684d7683b4..610bf4ccaaa 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -37,6 +37,7 @@
# include <mach/machine.h>
#endif
#ifdef HAVE_IOKIT_IOKITLIB_H
+# include <CoreFoundation/CoreFoundation.h>
# include <IOKit/IOKitLib.h>
# include <IOKit/pwr_mgt/IOPM.h>
# include <IOKit/pwr_mgt/IOPMLib.h>
--
2.21.0
1
0
[PATCH 1/5] wined3d: Export wined3d_stateblock_init_contained_states().
by Zebediah Figura 26 Nov '19
by Zebediah Figura 26 Nov '19
26 Nov '19
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/wined3d/device.c | 2 +-
dlls/wined3d/stateblock.c | 4 ++--
dlls/wined3d/wined3d.spec | 1 +
dlls/wined3d/wined3d_private.h | 2 --
include/wine/wined3d.h | 1 +
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 87db701d157..5983281f932 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4131,7 +4131,7 @@ HRESULT CDECL wined3d_device_end_stateblock(struct wined3d_device *device)
return WINED3DERR_INVALIDCALL;
}
- stateblock_init_contained_states(stateblock);
+ wined3d_stateblock_init_contained_states(stateblock);
wined3d_stateblock_decref(device->recording);
device->recording = NULL;
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 898a4bc93d4..dc714914ec3 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -283,7 +283,7 @@ static void stateblock_savedstates_set_vertex(struct wined3d_saved_states *state
memset(states->vs_consts_f, TRUE, sizeof(BOOL) * num_constants);
}
-void stateblock_init_contained_states(struct wined3d_stateblock *stateblock)
+void CDECL wined3d_stateblock_init_contained_states(struct wined3d_stateblock *stateblock)
{
const struct wined3d_d3d_info *d3d_info = &stateblock->device->adapter->d3d_info;
unsigned int i, j;
@@ -2032,7 +2032,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock,
break;
}
- stateblock_init_contained_states(stateblock);
+ wined3d_stateblock_init_contained_states(stateblock);
wined3d_stateblock_capture(stateblock);
/* According to the tests, stream offset is not updated in the captured state if
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index ea04c85d385..29bcd759264 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -262,6 +262,7 @@
@ cdecl wined3d_stateblock_create(ptr long ptr)
@ cdecl wined3d_stateblock_decref(ptr)
@ cdecl wined3d_stateblock_incref(ptr)
+@ cdecl wined3d_stateblock_init_contained_states(ptr)
@ cdecl wined3d_stateblock_reset(ptr)
@ cdecl wined3d_stateblock_set_base_vertex_index(ptr long)
@ cdecl wined3d_stateblock_set_blend_factor(ptr ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f6d25aa6d88..8ebf377b114 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3974,8 +3974,6 @@ struct wined3d_stateblock
unsigned int num_contained_sampler_states;
};
-void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
-
void wined3d_stateblock_state_init(struct wined3d_stateblock_state *state,
const struct wined3d_device *device, DWORD flags) DECLSPEC_HIDDEN;
void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) DECLSPEC_HIDDEN;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index fac9eef5be2..37e012b979d 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2667,6 +2667,7 @@ HRESULT __cdecl wined3d_stateblock_create(struct wined3d_device *device,
enum wined3d_stateblock_type type, struct wined3d_stateblock **stateblock);
ULONG __cdecl wined3d_stateblock_decref(struct wined3d_stateblock *stateblock);
ULONG __cdecl wined3d_stateblock_incref(struct wined3d_stateblock *stateblock);
+void __cdecl wined3d_stateblock_init_contained_states(struct wined3d_stateblock *stateblock);
void __cdecl wined3d_stateblock_reset(struct wined3d_stateblock *stateblock);
void __cdecl wined3d_stateblock_set_base_vertex_index(struct wined3d_stateblock *stateblock, INT base_index);
void __cdecl wined3d_stateblock_set_blend_factor(struct wined3d_stateblock *stateblock,
--
2.23.0
3
7
26 Nov '19
Some games, e.g. Hitman 2, do not check for success, and if the feature
check is unimplemented they will use uninitialised data as the result.
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
include/vkd3d_d3d12.idl | 141 ++++++++++++++++++
libs/vkd3d/device.c | 276 +++++++++++++++++++++++++++++++++++++
libs/vkd3d/vkd3d_private.h | 5 +
3 files changed, 422 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl
index 8246424..3747c8e 100644
--- a/include/vkd3d_d3d12.idl
+++ b/include/vkd3d_d3d12.idl
@@ -1608,6 +1608,141 @@ typedef struct D3D12_FEATURE_DATA_SHADER_MODEL
D3D_SHADER_MODEL HighestShaderModel;
} D3D12_FEATURE_DATA_SHADER_MODEL;
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS1
+{
+ BOOL WaveOps;
+ UINT WaveLaneCountMin;
+ UINT WaveLaneCountMax;
+ UINT TotalLaneCount;
+ BOOL ExpandedComputeResourceStates;
+ BOOL Int64ShaderOps;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS1;
+
+typedef enum D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER
+{
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED = 0,
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_1 = 1,
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2 = 2,
+} D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER;
+
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS2
+{
+ BOOL DepthBoundsTestSupported;
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER ProgrammableSamplePositionsTier;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS2;
+
+typedef enum D3D12_SHADER_CACHE_SUPPORT_FLAGS
+{
+ D3D12_SHADER_CACHE_SUPPORT_NONE = 0x0,
+ D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO = 0x1,
+ D3D12_SHADER_CACHE_SUPPORT_LIBRARY = 0x2,
+ D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE = 0x4,
+ D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE = 0x8,
+} D3D12_SHADER_CACHE_SUPPORT_FLAGS;
+
+typedef struct D3D12_FEATURE_DATA_SHADER_CACHE
+{
+ D3D12_SHADER_CACHE_SUPPORT_FLAGS SupportFlags;
+} D3D12_FEATURE_DATA_SHADER_CACHE;
+
+typedef struct D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY
+{
+ D3D12_COMMAND_LIST_TYPE CommandListType;
+ UINT Priority;
+ BOOL PriorityForTypeIsSupported;
+} D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY;
+
+typedef struct D3D12_FEATURE_DATA_ARCHITECTURE1
+{
+ UINT NodeIndex;
+ BOOL TileBasedRenderer;
+ BOOL UMA;
+ BOOL CacheCoherentUMA;
+ BOOL IsolatedMMU;
+} D3D12_FEATURE_DATA_ARCHITECTURE1;
+
+typedef enum D3D12_COMMAND_LIST_SUPPORT_FLAGS
+{
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE = 0x0,
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT = 0x1,
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_BUNDLE = 0x2,
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE = 0x4,
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_COPY = 0x8,
+} D3D12_COMMAND_LIST_SUPPORT_FLAGS;
+
+typedef enum D3D12_VIEW_INSTANCING_TIER
+{
+ D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED = 0,
+ D3D12_VIEW_INSTANCING_TIER_1 = 1,
+ D3D12_VIEW_INSTANCING_TIER_2 = 2,
+ D3D12_VIEW_INSTANCING_TIER_3 = 3,
+} D3D12_VIEW_INSTANCING_TIER;
+
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS3
+{
+ BOOL CopyQueueTimestampQueriesSupported;
+ BOOL CastingFullyTypedFormatSupported;
+ D3D12_COMMAND_LIST_SUPPORT_FLAGS WriteBufferImmediateSupportFlags;
+ D3D12_VIEW_INSTANCING_TIER ViewInstancingTier;
+ BOOL BarycentricsSupported;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS3;
+
+typedef struct D3D12_FEATURE_DATA_EXISTING_HEAPS
+{
+ BOOL Supported;
+} D3D12_FEATURE_DATA_EXISTING_HEAPS;
+
+typedef enum D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER
+{
+ D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0 = 0,
+ D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_1 = 1,
+} D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER;
+
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS4
+{
+ BOOL MSAA64KBAlignedTextureSupported;
+ D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER SharedResourceCompatibilityTier;
+ BOOL Native16BitShaderOpsSupported;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS4;
+
+typedef enum D3D12_HEAP_SERIALIZATION_TIER
+{
+ D3D12_HEAP_SERIALIZATION_TIER_0 = 0,
+ D3D12_HEAP_SERIALIZATION_TIER_10 = 10,
+} D3D12_HEAP_SERIALIZATION_TIER;
+
+typedef struct D3D12_FEATURE_DATA_SERIALIZATION
+{
+ UINT NodeIndex;
+ D3D12_HEAP_SERIALIZATION_TIER HeapSerializationTier;
+} D3D12_FEATURE_DATA_SERIALIZATION;
+
+typedef struct D3D12_FEATURE_DATA_CROSS_NODE
+{
+ D3D12_CROSS_NODE_SHARING_TIER SharingTier;
+ BOOL AtomicShaderInstructions;
+} D3D12_FEATURE_DATA_CROSS_NODE;
+
+typedef enum D3D12_RENDER_PASS_TIER
+{
+ D3D12_RENDER_PASS_TIER_0 = 0,
+ D3D12_RENDER_PASS_TIER_1 = 1,
+ D3D12_RENDER_PASS_TIER_2 = 2,
+} D3D12_RENDER_PASS_TIER;
+
+typedef enum D3D12_RAYTRACING_TIER
+{
+ D3D12_RAYTRACING_TIER_NOT_SUPPORTED = 0,
+ D3D12_RAYTRACING_TIER_1_0 = 10,
+} D3D12_RAYTRACING_TIER;
+
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS5
+{
+ BOOL SRVOnlyTiledResourceTier3;
+ D3D12_RENDER_PASS_TIER RenderPassesTier;
+ D3D12_RAYTRACING_TIER RaytracingTier;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS5;
+
typedef enum D3D12_FEATURE
{
D3D12_FEATURE_D3D12_OPTIONS = 0,
@@ -1624,6 +1759,12 @@ typedef enum D3D12_FEATURE
D3D12_FEATURE_D3D12_OPTIONS2 = 18,
D3D12_FEATURE_SHADER_CACHE = 19,
D3D12_FEATURE_COMMAND_QUEUE_PRIORITY = 20,
+ D3D12_FEATURE_D3D12_OPTIONS3 = 21,
+ D3D12_FEATURE_EXISTING_HEAPS = 22,
+ D3D12_FEATURE_D3D12_OPTIONS4 = 23,
+ D3D12_FEATURE_SERIALIZATION = 24,
+ D3D12_FEATURE_CROSS_NODE = 25,
+ D3D12_FEATURE_D3D12_OPTIONS5 = 27,
} D3D12_FEATURE;
typedef struct D3D12_MEMCPY_DEST
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 7ff567d..0404b76 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1336,6 +1336,33 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
device->feature_options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation = FALSE;
device->feature_options.ResourceHeapTier = D3D12_RESOURCE_HEAP_TIER_2;
+ device->feature_options1.WaveOps = FALSE;
+ device->feature_options1.WaveLaneCountMin = 0;
+ device->feature_options1.WaveLaneCountMax = 0;
+ device->feature_options1.TotalLaneCount = 0;
+ device->feature_options1.ExpandedComputeResourceStates = TRUE;
+ device->feature_options1.Int64ShaderOps = features->shaderInt64;
+
+ /* Depth bounds test is enabled in D3D12_DEPTH_STENCIL_DESC1, which is not supported. */
+ device->feature_options2.DepthBoundsTestSupported = FALSE;
+ /* d3d12_command_list_SetSamplePositions() is not implemented. */
+ device->feature_options2.ProgrammableSamplePositionsTier = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED;
+
+ device->feature_options3.CopyQueueTimestampQueriesSupported = FALSE;
+ device->feature_options3.CastingFullyTypedFormatSupported = FALSE;
+ device->feature_options3.WriteBufferImmediateSupportFlags = D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE;
+ device->feature_options3.ViewInstancingTier = D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED;
+ device->feature_options3.BarycentricsSupported = FALSE;
+
+ /* Alignment support can be tested later. */
+ device->feature_options4.MSAA64KBAlignedTextureSupported = FALSE;
+ device->feature_options4.SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0;
+ device->feature_options4.Native16BitShaderOpsSupported = features->shaderInt16;
+
+ device->feature_options5.SRVOnlyTiledResourceTier3 = FALSE;
+ device->feature_options5.RenderPassesTier = D3D12_RENDER_PASS_TIER_0;
+ device->feature_options5.RaytracingTier = D3D12_RAYTRACING_TIER_NOT_SUPPORTED;
+
if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0)
{
ERR("Failed to enumerate device extensions, vr %d.\n", vr);
@@ -1590,6 +1617,8 @@ static HRESULT d3d12_device_create_vkd3d_queues(struct d3d12_device *device,
else
goto out_destroy_queues;
+ device->feature_options3.CopyQueueTimestampQueriesSupported = !!device->copy_queue->timestamp_bits;
+
return S_OK;
out_destroy_queues:
@@ -2433,6 +2462,27 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent)
return true;
}
+static bool d3d12_is_64k_msaa_supported(struct d3d12_device *device)
+{
+ D3D12_RESOURCE_ALLOCATION_INFO info;
+ D3D12_RESOURCE_DESC resource_desc;
+
+ memset(&resource_desc, 0, sizeof(resource_desc));
+ resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ resource_desc.Width = 1024;
+ resource_desc.Height = 1024;
+ resource_desc.DepthOrArraySize = 1;
+ resource_desc.MipLevels = 1;
+ resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ resource_desc.SampleDesc.Count = 4;
+ resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
+
+ /* FIXME: in some cases Vulkan requires 0x20000 or more for non-MSAA resources which must have
+ * 0x10000 in their description, so we might resonably return true here for 0x20000 or 0x40000. */
+ return SUCCEEDED(vkd3d_get_image_allocation_info(device, &resource_desc, &info))
+ && info.Alignment <= 0x10000;
+}
+
static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *iface,
D3D12_FEATURE feature, void *feature_data, UINT feature_data_size)
{
@@ -2683,6 +2733,27 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *
return S_OK;
}
+ case D3D12_FEATURE_D3D12_OPTIONS1:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS1 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options1;
+
+ TRACE("Wave ops %#x.\n", data->WaveOps);
+ TRACE("Min wave lane count %#x.\n", data->WaveLaneCountMin);
+ TRACE("Max wave lane count %#x.\n", data->WaveLaneCountMax);
+ TRACE("Total lane count %#x.\n", data->TotalLaneCount);
+ TRACE("Expanded compute resource states %#x.\n", data->ExpandedComputeResourceStates);
+ TRACE("Int64 shader ops %#x.\n", data->Int64ShaderOps);
+ return S_OK;
+ }
+
case D3D12_FEATURE_ROOT_SIGNATURE:
{
D3D12_FEATURE_DATA_ROOT_SIGNATURE *data = feature_data;
@@ -2700,6 +2771,219 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *
return S_OK;
}
+ case D3D12_FEATURE_ARCHITECTURE1:
+ {
+ D3D12_FEATURE_DATA_ARCHITECTURE1 *data = feature_data;
+ bool coherent;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ if (data->NodeIndex)
+ {
+ FIXME("Multi-adapter not supported.\n");
+ return E_INVALIDARG;
+ }
+
+ WARN("Assuming device does not support tile based rendering.\n");
+ data->TileBasedRenderer = FALSE;
+
+ data->UMA = d3d12_device_is_uma(device, &coherent);
+ data->CacheCoherentUMA = data->UMA ? coherent : FALSE;
+
+ WARN("Assuming device does not have an isolated memory management unit.\n");
+ data->IsolatedMMU = FALSE;
+
+ TRACE("Tile based renderer %#x, UMA %#x, cache coherent UMA %#x, isolated MMU %#x.\n",
+ data->TileBasedRenderer, data->UMA, data->CacheCoherentUMA, data->IsolatedMMU);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS2:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS2 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options2;
+
+ TRACE("Depth bounds test %#x.\n", data->DepthBoundsTestSupported);
+ TRACE("Programmable sample positions tier %#x.\n", data->ProgrammableSamplePositionsTier);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_SHADER_CACHE:
+ {
+ D3D12_FEATURE_DATA_SHADER_CACHE *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ /* FIXME: The D3D12 documentation states that D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO is
+ * always supported, but the CachedPSO field of D3D12_GRAPHICS_PIPELINE_STATE_DESC is
+ * ignored and GetCachedBlob() is a stub. */
+ data->SupportFlags = D3D12_SHADER_CACHE_SUPPORT_NONE;
+
+ TRACE("Shader cache support %#x.\n", data->SupportFlags);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_COMMAND_QUEUE_PRIORITY:
+ {
+ D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ switch (data->CommandListType)
+ {
+ case D3D12_COMMAND_LIST_TYPE_DIRECT:
+ case D3D12_COMMAND_LIST_TYPE_COMPUTE:
+ case D3D12_COMMAND_LIST_TYPE_COPY:
+ data->PriorityForTypeIsSupported = FALSE;
+ TRACE("Command list type %#x, priority %u, supported %#x.\n",
+ data->CommandListType, data->Priority, data->PriorityForTypeIsSupported);
+ return S_OK;
+
+ default:
+ FIXME("Unhandled command list type %#x.\n", data->CommandListType);
+ return E_INVALIDARG;
+ }
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS3:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS3 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options3;
+
+ TRACE("Copy queue timestamp queries %#x.\n", data->CopyQueueTimestampQueriesSupported);
+ TRACE("Casting fully typed format %#x.\n", data->CastingFullyTypedFormatSupported);
+ TRACE("Write buffer immediate %#x.\n", data->WriteBufferImmediateSupportFlags);
+ TRACE("View instancing tier %#x.\n", data->ViewInstancingTier);
+ TRACE("Barycentrics %#x.\n", data->BarycentricsSupported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_EXISTING_HEAPS:
+ {
+ D3D12_FEATURE_DATA_EXISTING_HEAPS *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ data->Supported = FALSE;
+
+ TRACE("Existing heaps %#x.\n", data->Supported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS4:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS4 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options4;
+ data->MSAA64KBAlignedTextureSupported = d3d12_is_64k_msaa_supported(device);
+
+ TRACE("64KB aligned MSAA textures %#x.\n", data->MSAA64KBAlignedTextureSupported);
+ TRACE("Shared resource compatibility tier %#x.\n", data->SharedResourceCompatibilityTier);
+ TRACE("Native 16-bit shader ops %#x.\n", data->Native16BitShaderOpsSupported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_SERIALIZATION:
+ {
+ D3D12_FEATURE_DATA_SERIALIZATION *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+ if (data->NodeIndex)
+ {
+ FIXME("Multi-adapter not supported.\n");
+ return E_INVALIDARG;
+ }
+
+ data->HeapSerializationTier = D3D12_HEAP_SERIALIZATION_TIER_0;
+
+ TRACE("Heap serialization tier %#x.\n", data->HeapSerializationTier);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_CROSS_NODE:
+ {
+ D3D12_FEATURE_DATA_CROSS_NODE *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ data->SharingTier = D3D12_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED;
+ data->AtomicShaderInstructions = FALSE;
+
+ TRACE("Cross node sharing tier %#x.\n", data->SharingTier);
+ TRACE("Cross node shader atomics %#x.\n", data->AtomicShaderInstructions);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS5:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS5 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options5;
+
+ TRACE("SRV tiled resource tier 3 only %#x.\n", data->SRVOnlyTiledResourceTier3);
+ TRACE("Render pass tier %#x.\n", data->RenderPassesTier);
+ TRACE("Ray tracing tier %#x.\n", data->RaytracingTier);
+ return S_OK;
+ }
+
default:
FIXME("Unhandled feature %#x.\n", feature);
return E_NOTIMPL;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 9edf96e..7ba1db4 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -1086,6 +1086,11 @@ struct d3d12_device
PFN_vkd3d_memory_usage_callback pfn_memory_usage_callback;
D3D12_FEATURE_DATA_D3D12_OPTIONS feature_options;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS1 feature_options1;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS2 feature_options2;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS3 feature_options3;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS4 feature_options4;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS5 feature_options5;
struct vkd3d_vulkan_info vk_info;
--
2.24.0
2
3
[PATCH vkd3d v2 1/2] vkd3d: Return success for all valid D3D12 alignments.
by Conor McCarthy 26 Nov '19
by Conor McCarthy 26 Nov '19
26 Nov '19
Windows checks for one of its valid default alignment sizes. The size test
should not include DepthOrArraySize, should use the correct size for
compressed textures, and the returned alignment should not be tested
against the requested one. The current implementation returns ~0 in
SizeInBytes for standard D3D12 alignments on some hardware and driver
combinations, e.g. AMD RX 580 / RADV. Some games use this value unchecked;
for example Hitman 2 will allocate heaps of size 0xffffffff and run out of
vram. This patch also fixes RX 580 alignment test failures.
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
Supersedes 173581.
---
libs/vkd3d/device.c | 50 ++++++++++++++++++++++++++++++---------------
1 file changed, 33 insertions(+), 17 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index a025e68..7ff567d 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -2938,7 +2938,7 @@ static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResour
if (FAILED(d3d12_resource_validate_desc(desc)))
{
WARN("Invalid resource desc.\n");
- goto invalid;
+ goto fail;
}
requested_alignment = desc->Alignment
@@ -2946,6 +2946,8 @@ static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResour
if (desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
+ if (requested_alignment != D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT)
+ goto invalid;
info->SizeInBytes = desc->Width;
info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
}
@@ -2954,32 +2956,43 @@ static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResour
if (FAILED(vkd3d_get_image_allocation_info(device, desc, info)))
{
WARN("Failed to get allocation info for texture.\n");
- goto invalid;
+ goto fail;
}
+ /* Validate the alignment in the resource description. Also allow the Vulkan alignment in case the caller
+ * specifies it in future calls. We *could* enforce D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT,
+ * but it may prove better to allow 64KB (which D3D12 accepts on newer hardware anyway), and return
+ * whatever Vulkan requires. */
+ if (requested_alignment != info->Alignment
+ && requested_alignment != D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT
+ && requested_alignment != D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT
+ && (desc->SampleDesc.Count == 1 || requested_alignment != D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT))
+ goto invalid;
+
info->Alignment = max(info->Alignment, requested_alignment);
- if (info->Alignment < D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT)
+ if (info->Alignment < D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT
+ || requested_alignment < D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT)
{
if (!(format = vkd3d_format_from_d3d12_resource_desc(device, desc, 0)))
{
WARN("Invalid format %#x.\n", desc->Format);
- goto invalid;
+ goto fail;
}
- estimated_size = desc->Width * desc->Height * desc->DepthOrArraySize * format->byte_count;
+ /* Windows uses the slice size to determine small alignment eligibility. DepthOrArraySize is ignored. */
+ estimated_size = vkd3d_format_is_compressed(format)
+ ? desc->Width * desc->Height * format->block_byte_count / (format->block_width * format->block_height)
+ : desc->Width * desc->Height * format->byte_count;
if (estimated_size > D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT)
+ {
+ if (requested_alignment == D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT)
+ goto invalid;
info->Alignment = max(info->Alignment, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT);
+ }
}
}
- if (desc->Alignment % info->Alignment)
- {
- WARN("Invalid resource alignment %#"PRIx64" (required %#"PRIx64").\n",
- desc->Alignment, info->Alignment);
- goto invalid;
- }
-
info->SizeInBytes = align(info->SizeInBytes, info->Alignment);
TRACE("Size %#"PRIx64", alignment %#"PRIx64".\n", info->SizeInBytes, info->Alignment);
@@ -2987,13 +3000,16 @@ static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResour
return info;
invalid:
+ WARN("Invalid resource alignment %#"PRIx64" (required %#x).\n",
+ requested_alignment, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT);
+
+fail:
info->SizeInBytes = ~(uint64_t)0;
- /* FIXME: Should we support D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT for small MSSA resources? */
- if (desc->SampleDesc.Count != 1)
- info->Alignment = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT;
- else
- info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
+ /* Theoretically we should return D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT if
+ * (desc->SampleDesc.Count != 1 && !device->feature_options4.MSAA64KBAlignedTextureSupported)
+ * but Vulkan has no such requirement and it may prove unnecessary. */
+ info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
TRACE("Alignment %#"PRIx64".\n", info->Alignment);
--
2.24.0
2
4
[PATCH 1/3] mfplat: Do not make a copy when returning GUID attributes (Valgrind).
by Nikolay Sivov 26 Nov '19
by Nikolay Sivov 26 Nov '19
26 Nov '19
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/mfplat/main.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 48e64adeef..6336b1b347 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -1349,14 +1349,23 @@ HRESULT attributes_GetDouble(struct attributes *attributes, REFGUID key, double
HRESULT attributes_GetGUID(struct attributes *attributes, REFGUID key, GUID *value)
{
- PROPVARIANT attrval;
- HRESULT hr;
+ struct attribute *attribute;
+ HRESULT hr = S_OK;
- PropVariantInit(&attrval);
- attrval.vt = VT_CLSID;
- hr = attributes_get_item(attributes, key, &attrval);
- if (SUCCEEDED(hr))
- *value = *attrval.u.puuid;
+ EnterCriticalSection(&attributes->cs);
+
+ attribute = attributes_find_item(attributes, key, NULL);
+ if (attribute)
+ {
+ if (attribute->value.vt == MF_ATTRIBUTE_GUID)
+ *value = *attribute->value.u.puuid;
+ else
+ hr = MF_E_INVALIDTYPE;
+ }
+ else
+ hr = MF_E_ATTRIBUTENOTFOUND;
+
+ LeaveCriticalSection(&attributes->cs);
return hr;
}
--
2.24.0
2
3
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/user32/combo.c | 163 +++++++++++++++-----------------------------
1 file changed, 55 insertions(+), 108 deletions(-)
diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c
index 4ddccd6c95..07d53f7341 100644
--- a/dlls/user32/combo.c
+++ b/dlls/user32/combo.c
@@ -319,111 +319,70 @@ static void CBForceDummyResize(
*
* Set up component coordinates given valid lphc->RectCombo.
*/
-static void CBCalcPlacement(
- HWND hwnd,
- LPHEADCOMBO lphc,
- LPRECT lprEdit,
- LPRECT lprButton,
- LPRECT lprLB)
+static void CBCalcPlacement(HEADCOMBO *combo)
{
- /*
- * Again, start with the client rectangle.
- */
- GetClientRect(hwnd, lprEdit);
+ /* Start with the client rectangle. */
+ GetClientRect(combo->self, &combo->textRect);
- /*
- * Remove the borders
- */
- InflateRect(lprEdit, -COMBO_XBORDERSIZE(), -COMBO_YBORDERSIZE());
+ /* Remove the borders */
+ InflateRect(&combo->textRect, -COMBO_XBORDERSIZE(), -COMBO_YBORDERSIZE());
- /*
- * Chop off the bottom part to fit with the height of the text area.
- */
- lprEdit->bottom = lprEdit->top + CBGetTextAreaHeight(hwnd, lphc);
-
- /*
- * The button starts the same vertical position as the text area.
- */
- CopyRect(lprButton, lprEdit);
+ /* Chop off the bottom part to fit with the height of the text area. */
+ combo->textRect.bottom = combo->textRect.top + CBGetTextAreaHeight(combo->self, combo);
- /*
- * If the combobox is "simple" there is no button.
- */
- if( CB_GETTYPE(lphc) == CBS_SIMPLE )
- lprButton->left = lprButton->right = lprButton->bottom = 0;
- else
- {
- /*
- * Let's assume the combobox button is the same width as the
- * scrollbar button.
- * size the button horizontally and cut-off the text area.
- */
- lprButton->left = lprButton->right - GetSystemMetrics(SM_CXVSCROLL);
- lprEdit->right = lprButton->left;
- }
+ /* The button starts the same vertical position as the text area. */
+ combo->buttonRect = combo->textRect;
- /*
- * In the case of a dropdown, there is an additional spacing between the
- * text area and the button.
- */
- if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
- {
- lprEdit->right -= COMBO_EDITBUTTONSPACE();
- }
+ /* If the combobox is "simple" there is no button. */
+ if (CB_GETTYPE(combo) == CBS_SIMPLE)
+ combo->buttonRect.left = combo->buttonRect.right = combo->buttonRect.bottom = 0;
+ else
+ {
+ /*
+ * Let's assume the combobox button is the same width as the
+ * scrollbar button.
+ * size the button horizontally and cut-off the text area.
+ */
+ combo->buttonRect.left = combo->buttonRect.right - GetSystemMetrics(SM_CXVSCROLL);
+ combo->textRect.right = combo->buttonRect.left;
+ }
- /*
- * If we have an edit control, we space it away from the borders slightly.
- */
- if (CB_GETTYPE(lphc) != CBS_DROPDOWNLIST)
- {
- InflateRect(lprEdit, -EDIT_CONTROL_PADDING(), -EDIT_CONTROL_PADDING());
- }
+ /* In the case of a dropdown, there is an additional spacing between the text area and the button. */
+ if (CB_GETTYPE(combo) == CBS_DROPDOWN)
+ combo->textRect.right -= COMBO_EDITBUTTONSPACE();
- /*
- * Adjust the size of the listbox popup.
- */
- if( CB_GETTYPE(lphc) == CBS_SIMPLE )
- {
- /*
- * Use the client rectangle to initialize the listbox rectangle
- */
- GetClientRect(hwnd, lprLB);
+ /* If we have an edit control, we space it away from the borders slightly. */
+ if (CB_GETTYPE(combo) != CBS_DROPDOWNLIST)
+ InflateRect(&combo->textRect, -EDIT_CONTROL_PADDING(), -EDIT_CONTROL_PADDING());
- /*
- * Then, chop-off the top part.
- */
- lprLB->top = lprEdit->bottom + COMBO_YBORDERSIZE();
- }
- else
- {
- /*
- * Make sure the dropped width is as large as the combobox itself.
- */
- if (lphc->droppedWidth < (lprButton->right + COMBO_XBORDERSIZE()))
+ /* Adjust the size of the listbox popup. */
+ if (CB_GETTYPE(combo) == CBS_SIMPLE)
{
- lprLB->right = lprLB->left + (lprButton->right + COMBO_XBORDERSIZE());
-
- /*
- * In the case of a dropdown, the popup listbox is offset to the right.
- * so, we want to make sure it's flush with the right side of the
- * combobox
- */
- if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
- lprLB->right -= COMBO_EDITBUTTONSPACE();
+ GetClientRect(combo->self, &combo->droppedRect);
+ combo->droppedRect.top = combo->textRect.bottom + COMBO_YBORDERSIZE();
}
else
- lprLB->right = lprLB->left + lphc->droppedWidth;
- }
-
- /* don't allow negative window width */
- if (lprEdit->right < lprEdit->left)
- lprEdit->right = lprEdit->left;
+ {
+ /* Make sure the dropped width is as large as the combobox itself. */
+ if (combo->droppedWidth < (combo->buttonRect.right + COMBO_XBORDERSIZE()))
+ {
+ combo->droppedRect.right = combo->droppedRect.left + (combo->buttonRect.right + COMBO_XBORDERSIZE());
- TRACE("\ttext\t= (%s)\n", wine_dbgstr_rect(lprEdit));
+ /* In the case of a dropdown, the popup listbox is offset to the right. We want to make sure it's flush
+ with the right side of the combobox. */
+ if (CB_GETTYPE(combo) == CBS_DROPDOWN)
+ combo->droppedRect.right -= COMBO_EDITBUTTONSPACE();
+ }
+ else
+ combo->droppedRect.right = combo->droppedRect.left + combo->droppedWidth;
+ }
- TRACE("\tbutton\t= (%s)\n", wine_dbgstr_rect(lprButton));
+ /* Disallow negative window width */
+ if (combo->textRect.right < combo->textRect.left)
+ combo->textRect.right = combo->textRect.left;
- TRACE("\tlbox\t= (%s)\n", wine_dbgstr_rect(lprLB));
+ TRACE("text %s, button %s, lbox %s.\n", wine_dbgstr_rect(&combo->textRect), wine_dbgstr_rect(&combo->buttonRect),
+ wine_dbgstr_rect(&combo->droppedRect));
}
/***********************************************************************
@@ -479,7 +438,7 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG
* recalculated.
*/
GetClientRect( hwnd, &lphc->droppedRect );
- CBCalcPlacement(hwnd, lphc, &lphc->textRect, &lphc->buttonRect, &lphc->droppedRect );
+ CBCalcPlacement(lphc);
/*
* Adjust the position of the popup listbox if it's necessary
@@ -1530,11 +1489,7 @@ static void COMBO_Size( LPHEADCOMBO lphc )
SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOREDRAW);
}
- CBCalcPlacement(lphc->self,
- lphc,
- &lphc->textRect,
- &lphc->buttonRect,
- &lphc->droppedRect);
+ CBCalcPlacement(lphc);
CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, FALSE );
}
@@ -1562,11 +1517,7 @@ static void COMBO_Font( LPHEADCOMBO lphc, HFONT hFont, BOOL bRedraw )
*/
if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
{
- CBCalcPlacement(lphc->self,
- lphc,
- &lphc->textRect,
- &lphc->buttonRect,
- &lphc->droppedRect);
+ CBCalcPlacement(lphc);
CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
}
@@ -1595,11 +1546,7 @@ static LRESULT COMBO_SetItemHeight( LPHEADCOMBO lphc, INT index, INT height )
*/
if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
{
- CBCalcPlacement(lphc->self,
- lphc,
- &lphc->textRect,
- &lphc->buttonRect,
- &lphc->droppedRect);
+ CBCalcPlacement(lphc);
CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
}
@@ -2100,7 +2047,7 @@ LRESULT ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar
lphc->droppedWidth = 0;
/* recalculate the combobox area */
- CBCalcPlacement(hwnd, lphc, &lphc->textRect, &lphc->buttonRect, &lphc->droppedRect );
+ CBCalcPlacement(lphc);
/* fall through */
case CB_GETDROPPEDWIDTH:
--
2.24.0
2
3
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48054
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/gdi32/tests/bitmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index 8fe160546c..8f0f6601b3 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -913,7 +913,7 @@ static void test_dibsections(void)
static void test_dib_formats(void)
{
BITMAPINFO *bi;
- char data[256];
+ char data[2048]; /* 2 x 2 pixels, max 64 bits-per-pixel, max 64 planes */
void *bits;
int planes, bpp, compr, format;
HBITMAP hdib, hbmp;
--
2.23.0
3
3