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
November 2021
- 83 participants
- 2620 messages
[PATCH vkd3d 3/5] vkd3d-shader/hlsl: Handle conditionals in copy propagation.
by Giovanni Mascellani
Signed-off-by: Giovanni Mascellani <gmascellani(a)codeweavers.com>
---
libs/vkd3d-shader/hlsl_codegen.c | 138 +++++++++++++++++++++++++++----
1 file changed, 123 insertions(+), 15 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 8db8bfc9..78bcd079 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -239,15 +239,17 @@ static void replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new)
/* struct copy_propagation_state represents the accumulated knowledge
* of the copy propagation pass while it scans through the code. Field
- * "variables" is a tree whose elements have type struct
- * copy_propagation_varible, and represent each of the variables the
- * pass has already encountered (except those with special semantics,
- * which are ignored). For each variable, the array "values" (whose
- * length is the register size of the variable) represent which node
- * and which index inside that node (i.e., which of the at most four
- * entries of a vector) provided that value last time. Field "node"
- * can be NULL, meaning that the pass was not able to statically
- * determine the node.
+ * "variables" is an stack of trees: each stack entry represents an
+ * embedded block (of type either HLSL_IR_IF or HLSL_IR_TREE); the
+ * elements of the tree have type struct copy_propagation_variable,
+ * and represent each of the variables the pass has already
+ * encountered (except those with special semantics, which are
+ * ignored). For each variable, the array "values" (whose length is
+ * the register size of the variable) represent which node and which
+ * index inside that node (i.e., which of the at most four entries of
+ * a vector) provided that value last time. Field "node" can be NULL,
+ * meaning that the pass was not able to statically determine the
+ * node.
*/
struct copy_propagation_value
@@ -265,7 +267,9 @@ struct copy_propagation_variable
struct copy_propagation_state
{
- struct rb_tree variables;
+ struct rb_tree *variables;
+ unsigned int depth;
+ unsigned int capacity;
};
static int copy_propagation_variable_compare(const void *key, const struct rb_entry *entry)
@@ -291,7 +295,7 @@ static void copy_propagation_variable_destroy(struct rb_entry *entry, void *cont
static struct copy_propagation_variable *copy_propagation_get_variable(struct hlsl_ctx *ctx,
struct copy_propagation_state *state, struct hlsl_ir_var *var)
{
- struct rb_entry *entry = rb_get(&state->variables, var);
+ struct rb_entry *entry = rb_get(&state->variables[state->depth], var);
struct copy_propagation_variable *variable;
int res;
@@ -310,7 +314,7 @@ static struct copy_propagation_variable *copy_propagation_get_variable(struct hl
return NULL;
}
- res = rb_put(&state->variables, var, &variable->entry);
+ res = rb_put(&state->variables[state->depth], var, &variable->entry);
assert(!res);
return variable;
@@ -342,6 +346,71 @@ static void copy_propagation_set_value(struct copy_propagation_variable *variabl
}
}
+static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct copy_propagation_state *state,
+ struct hlsl_block *block)
+{
+ struct hlsl_ir_node *instr;
+
+ LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry)
+ {
+ if (instr->type == HLSL_IR_STORE)
+ {
+ struct hlsl_ir_store *store = hlsl_ir_store(instr);
+ struct copy_propagation_variable *variable;
+ struct hlsl_deref *lhs = &store->lhs;
+ struct hlsl_ir_var *var = lhs->var;
+
+ if (var->is_input_semantic || var->is_output_semantic || var->is_uniform)
+ continue;
+
+ variable = copy_propagation_get_variable(ctx, state, var);
+ if (!variable)
+ continue;
+
+ copy_propagation_set_value(variable, hlsl_offset_from_deref(lhs), store->writemask, NULL);
+ }
+ }
+}
+
+static void copy_propagation_pop(struct copy_propagation_state *state)
+{
+ assert(state->depth > 0);
+ rb_destroy(&state->variables[state->depth], copy_propagation_variable_destroy, NULL);
+ --state->depth;
+}
+
+static bool copy_propagation_duplicate(struct hlsl_ctx *ctx, struct copy_propagation_state *state)
+{
+ struct copy_propagation_variable *var;
+
+ if (state->depth + 1 == state->capacity)
+ {
+ unsigned int new_capacity = 2 * state->capacity;
+ struct rb_tree *new_vars;
+
+ new_vars = hlsl_realloc(ctx, state->variables, sizeof(*state->variables) * new_capacity);
+ if (!new_vars)
+ return false;
+ state->capacity = new_capacity;
+ state->variables = new_vars;
+ }
+ ++state->depth;
+
+ rb_init(&state->variables[state->depth], copy_propagation_variable_compare);
+
+ RB_FOR_EACH_ENTRY(var, &state->variables[state->depth - 1], struct copy_propagation_variable, entry)
+ {
+ struct copy_propagation_variable *new_var = copy_propagation_get_variable(ctx, state, var->var);
+
+ if (!new_var)
+ continue;
+
+ memcpy(new_var->values, var->values, sizeof(*var->values) * var->var->data_type->reg_size);
+ }
+
+ return true;
+}
+
/* Check if locations [offset, offset+count) in variable were all
* written from the same node. If so return the node the corresponding
* indices, otherwise return NULL (and undefined indices). */
@@ -436,6 +505,38 @@ static bool copy_propagation_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *s
return false;
}
+static bool copy_propagation_recursive(struct hlsl_ctx *ctx, struct hlsl_block *block,
+ struct copy_propagation_state *state);
+
+/* Both branches can inherit the variable state available when
+ * entering the "if". After the "if", all variables that might have
+ * been written in either branch must be invalidated, because we don't
+ * know which branch has executed. */
+static bool copy_propagation_if(struct hlsl_ctx *ctx, struct hlsl_ir_if *iff,
+ struct copy_propagation_state *state)
+{
+ bool progress = false;
+
+ if (!copy_propagation_duplicate(ctx, state))
+ goto end;
+
+ progress |= copy_propagation_recursive(ctx, &iff->then_instrs, state);
+
+ copy_propagation_pop(state);
+ if (!copy_propagation_duplicate(ctx, state))
+ goto end;
+
+ progress |= copy_propagation_recursive(ctx, &iff->else_instrs, state);
+
+ copy_propagation_pop(state);
+
+end:
+ copy_propagation_invalidate_from_block(ctx, state, &iff->then_instrs);
+ copy_propagation_invalidate_from_block(ctx, state, &iff->else_instrs);
+
+ return progress;
+}
+
static bool copy_propagation_recursive(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct copy_propagation_state *state)
{
@@ -455,7 +556,7 @@ static bool copy_propagation_recursive(struct hlsl_ctx *ctx, struct hlsl_block *
break;
case HLSL_IR_IF:
- FIXME("Copy propagation doesn't support conditionals yet, leaving.\n");
+ progress |= copy_propagation_if(ctx, hlsl_ir_if(instr), state);
return progress;
case HLSL_IR_LOOP:
@@ -475,11 +576,18 @@ static bool copy_propagation_pass(struct hlsl_ctx *ctx, struct hlsl_block *block
struct copy_propagation_state state;
bool progress;
- rb_init(&state.variables, copy_propagation_variable_compare);
+ state.depth = 0;
+ state.capacity = 1;
+ state.variables = hlsl_alloc(ctx, sizeof(*state.variables) * state.capacity);
+ if (!state.variables)
+ return false;
+ rb_init(&state.variables[state.depth], copy_propagation_variable_compare);
progress = copy_propagation_recursive(ctx, block, &state);
- rb_destroy(&state.variables, copy_propagation_variable_destroy, NULL);
+ assert(state.depth == 0);
+ rb_destroy(&state.variables[state.depth], copy_propagation_variable_destroy, NULL);
+ vkd3d_free(state.variables);
return progress;
}
--
2.33.1
Nov. 9, 2021
[PATCH vkd3d 2/5] vkd3d-shader/hlsl: Perform a copy propagation pass.
by Giovanni Mascellani
Signed-off-by: Giovanni Mascellani <gmascellani(a)codeweavers.com>
---
Pretty sure this (and the following ones) will require some more
tweaking before being accepted! :-)
libs/vkd3d-shader/hlsl_codegen.c | 254 ++++++++++++++++++++++++++++++-
1 file changed, 253 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 0ee8ab55..8db8bfc9 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -237,6 +237,253 @@ static void replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new)
hlsl_free_instr(old);
}
+/* struct copy_propagation_state represents the accumulated knowledge
+ * of the copy propagation pass while it scans through the code. Field
+ * "variables" is a tree whose elements have type struct
+ * copy_propagation_varible, and represent each of the variables the
+ * pass has already encountered (except those with special semantics,
+ * which are ignored). For each variable, the array "values" (whose
+ * length is the register size of the variable) represent which node
+ * and which index inside that node (i.e., which of the at most four
+ * entries of a vector) provided that value last time. Field "node"
+ * can be NULL, meaning that the pass was not able to statically
+ * determine the node.
+ */
+
+struct copy_propagation_value
+{
+ struct hlsl_ir_node *node;
+ unsigned int index;
+};
+
+struct copy_propagation_variable
+{
+ struct rb_entry entry;
+ struct hlsl_ir_var *var;
+ struct copy_propagation_value *values;
+};
+
+struct copy_propagation_state
+{
+ struct rb_tree variables;
+};
+
+static int copy_propagation_variable_compare(const void *key, const struct rb_entry *entry)
+{
+ struct copy_propagation_variable *variable = RB_ENTRY_VALUE(entry, struct copy_propagation_variable, entry);
+ uintptr_t key_int = (uintptr_t)key, entry_int = (uintptr_t)variable->var;
+
+ if (key_int < entry_int)
+ return -1;
+ else if (key_int > entry_int)
+ return 1;
+ else
+ return 0;
+}
+
+static void copy_propagation_variable_destroy(struct rb_entry *entry, void *context)
+{
+ struct copy_propagation_variable *variable = RB_ENTRY_VALUE(entry, struct copy_propagation_variable, entry);
+
+ vkd3d_free(variable);
+}
+
+static struct copy_propagation_variable *copy_propagation_get_variable(struct hlsl_ctx *ctx,
+ struct copy_propagation_state *state, struct hlsl_ir_var *var)
+{
+ struct rb_entry *entry = rb_get(&state->variables, var);
+ struct copy_propagation_variable *variable;
+ int res;
+
+ if (entry)
+ return RB_ENTRY_VALUE(entry, struct copy_propagation_variable, entry);
+
+ variable = hlsl_alloc(ctx, sizeof(*variable));
+ if (!variable)
+ return NULL;
+
+ variable->var = var;
+ variable->values = hlsl_alloc(ctx, sizeof(*variable->values) * var->data_type->reg_size);
+ if (!variable->values)
+ {
+ vkd3d_free(variable);
+ return NULL;
+ }
+
+ res = rb_put(&state->variables, var, &variable->entry);
+ assert(!res);
+
+ return variable;
+}
+
+static void copy_propagation_set_value(struct copy_propagation_variable *variable, unsigned int offset,
+ unsigned char writemask, struct hlsl_ir_node *node)
+{
+ unsigned int index;
+
+ for (index = 0; index < 4; ++index)
+ {
+ if (writemask & (1u << index))
+ {
+ if (TRACE_ON())
+ {
+ char buf[32];
+ if (!node)
+ sprintf(buf, "(nil)");
+ else if (node->index)
+ sprintf(buf, "@%u", node->index);
+ else
+ sprintf(buf, "%p", node);
+ TRACE("variable %s[%d] is written by %p[%d]\n", variable->var->name, offset + index, buf, index);
+ }
+ variable->values[offset + index].node = node;
+ variable->values[offset + index].index = index;
+ }
+ }
+}
+
+/* Check if locations [offset, offset+count) in variable were all
+ * written from the same node. If so return the node the corresponding
+ * indices, otherwise return NULL (and undefined indices). */
+static struct hlsl_ir_node *copy_propagation_reconstruct_node(struct copy_propagation_variable *variable,
+ unsigned int offset, unsigned int count, unsigned int indices[4])
+{
+ struct hlsl_ir_node *node = NULL;
+ unsigned int i;
+
+ assert(offset + count <= variable->var->data_type->reg_size);
+
+ for (i = 0; i < count; ++i)
+ {
+ if (!node)
+ node = variable->values[offset + i].node;
+ else if (node != variable->values[offset + i].node)
+ return NULL;
+ indices[i] = variable->values[offset + i].index;
+ }
+
+ return node;
+}
+
+static bool copy_propagation_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load,
+ struct copy_propagation_state *state)
+{
+ struct hlsl_ir_node *node = &load->node, *new_node;
+ struct copy_propagation_variable *variable;
+ struct hlsl_type *type = node->data_type;
+ unsigned int offset, indices[4] = {};
+ struct hlsl_deref *src = &load->src;
+ struct hlsl_ir_var *var = src->var;
+ struct hlsl_ir_swizzle *swizzle;
+ DWORD s;
+
+ if (var->is_input_semantic || var->is_output_semantic || var->is_uniform)
+ return false;
+
+ if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR)
+ return false;
+
+ offset = hlsl_offset_from_deref(src);
+
+ variable = copy_propagation_get_variable(ctx, state, var);
+ if (!variable)
+ return false;
+
+ new_node = copy_propagation_reconstruct_node(variable, offset, type->dimx, indices);
+
+ if (TRACE_ON())
+ {
+ char buf[32];
+ if (!new_node)
+ sprintf(buf, "(nil)");
+ else if (new_node->index)
+ sprintf(buf, "@%u", new_node->index);
+ else
+ sprintf(buf, "%p", new_node);
+ TRACE("load from %s[%d-%d] reconstructed to %s[%d %d %d %d]\n", var->name, offset,
+ offset + type->dimx, buf, indices[0], indices[1], indices[2], indices[3]);
+ }
+
+ if (!new_node)
+ return false;
+
+ s = indices[0] | indices[1] << 2 | indices[2] << 4 | indices[3] << 6;
+ if (!(swizzle = hlsl_new_swizzle(ctx, s, type->dimx, new_node, &node->loc)))
+ return false;
+ list_add_before(&node->entry, &swizzle->node.entry);
+
+ replace_node(node, &swizzle->node);
+
+ return true;
+}
+
+static bool copy_propagation_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store,
+ struct copy_propagation_state *state)
+{
+ struct copy_propagation_variable *variable;
+ struct hlsl_deref *lhs = &store->lhs;
+ struct hlsl_ir_var *var = lhs->var;
+
+ if (var->is_input_semantic || var->is_output_semantic || var->is_uniform)
+ return false;
+
+ variable = copy_propagation_get_variable(ctx, state, var);
+ if (!variable)
+ return false;
+
+ copy_propagation_set_value(variable, hlsl_offset_from_deref(lhs), store->writemask, store->rhs.node);
+
+ return false;
+}
+
+static bool copy_propagation_recursive(struct hlsl_ctx *ctx, struct hlsl_block *block,
+ struct copy_propagation_state *state)
+{
+ struct hlsl_ir_node *instr, *next;
+ bool progress = false;
+
+ LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry)
+ {
+ switch (instr->type)
+ {
+ case HLSL_IR_LOAD:
+ progress |= copy_propagation_load(ctx, hlsl_ir_load(instr), state);
+ break;
+
+ case HLSL_IR_STORE:
+ progress |= copy_propagation_store(ctx, hlsl_ir_store(instr), state);
+ break;
+
+ case HLSL_IR_IF:
+ FIXME("Copy propagation doesn't support conditionals yet, leaving.\n");
+ return progress;
+
+ case HLSL_IR_LOOP:
+ FIXME("Copy propagation doesn't support loops yet, leaving.\n");
+ return progress;
+
+ default:
+ break;
+ }
+ }
+
+ return progress;
+}
+
+static bool copy_propagation_pass(struct hlsl_ctx *ctx, struct hlsl_block *block)
+{
+ struct copy_propagation_state state;
+ bool progress;
+
+ rb_init(&state.variables, copy_propagation_variable_compare);
+
+ progress = copy_propagation_recursive(ctx, block, &state);
+
+ rb_destroy(&state.variables, copy_propagation_variable_destroy, NULL);
+
+ return progress;
+}
+
static bool is_vec1(const struct hlsl_type *type)
{
return (type->type == HLSL_CLASS_SCALAR) || (type->type == HLSL_CLASS_VECTOR && type->dimx == 1);
@@ -1354,7 +1601,12 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
progress |= transform_ir(ctx, split_struct_copies, body, NULL);
}
while (progress);
- while (transform_ir(ctx, fold_constants, body, NULL));
+ do
+ {
+ progress = transform_ir(ctx, fold_constants, body, NULL);
+ progress |= copy_propagation_pass(ctx, body);
+ }
+ while (progress);
if (ctx->profile->major_version < 4)
transform_ir(ctx, lower_division, body, NULL);
--
2.33.1
Nov. 9, 2021
[PATCH vkd3d 1/5] vkd3d-shader/hlsl: Use "false" instead of "0" as a bool immediate.
by Giovanni Mascellani
Signed-off-by: Giovanni Mascellani <gmascellani(a)codeweavers.com>
---
libs/vkd3d-shader/hlsl_codegen.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 24b8205c..0ee8ab55 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -204,7 +204,7 @@ static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx
struct hlsl_block *block, void *context)
{
struct hlsl_ir_node *instr, *next;
- bool progress = 0;
+ bool progress = false;
LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry)
{
--
2.33.1
Nov. 9, 2021
Re: [v3 PATCH] d3d10/effect: Add initial support for indexing expressions.
by Matteo Bruni
On Mon, Nov 8, 2021 at 1:30 PM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>
> Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
> ---
>
> v3: some rework based on received feedback
>
> For now for simplicity I removed destination index from property update, with additional
> test for property type when parsing.
I like the changes. Unfortunately I keep finding stuff...
Only one important comment, see below.
> dlls/d3d10/effect.c | 577 +++++++++++++++++++++++++++++++++++++-
> dlls/d3d10/tests/effect.c | 114 ++++++++
> 2 files changed, 683 insertions(+), 8 deletions(-)
>
> diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
> index 78a3d0c386a..1be16771921 100644
> --- a/dlls/d3d10/effect.c
> +++ b/dlls/d3d10/effect.c
> +static float * d3d10_effect_preshader_get_reg_ptr(const struct d3d10_effect_preshader *p,
> + enum d3d10_reg_table_type regt, unsigned int offset)
> +{
> + switch (regt)
> + {
> + case D3D10_REG_TABLE_CONSTANTS:
> + case D3D10_REG_TABLE_CB:
> + case D3D10_REG_TABLE_RESULT:
> + case D3D10_REG_TABLE_TEMP:
> + return p->reg_tables[regt].f + offset;
> + default:
> + return NULL;
> + }
> +}
I think we want to validate the offset (for the _CONSTANTS table in
particular, since the other 3 are sized to fit all the accesses). Not
sure this is the best place for that but, if so, it might look
something like:
case D3D10_REG_TABLE_CB:
case D3D10_REG_TABLE_RESULT:
case D3D10_REG_TABLE_TEMP:
+ if (offset / sizeof(*p->reg_tables[regt].f) >=
p->reg_tables[regt].count
+ || (offset + sizeof(*p->reg_tables[regt].f)) /
sizeof(*p->reg_tables[regt].f)
+ > p->reg_tables[regt].count)
+ {
+ WARN("Invalid table offset %u.\n", offset);
+ offset = 0;
+ }
return p->reg_tables[regt].f + offset;
default:
+ WARN("Unexpected register type %#x.\n", regt);
return NULL;
}
}
(I expect it to get wrapped badly but hopefully it'll still be readable)
> +
> +static HRESULT d3d10_effect_preshader_eval(struct d3d10_effect_preshader *p)
> +{
> + unsigned int i, j, regt, offset, instr_count, input_count;
> + const DWORD *ip = ID3D10Blob_GetBufferPointer(p->code);
> + float *dst, *args[4], *retval;
> + struct preshader_instr ins;
> +
> + dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_RESULT, 0);
> + memset(dst, 0, sizeof(float) * p->reg_tables[D3D10_REG_TABLE_RESULT].count);
> +
> + /* Update constant buffer */
> + dst = d3d10_effect_preshader_get_reg_ptr(p, D3D10_REG_TABLE_CB, 0);
> + for (i = 0; i < p->vars_count; ++i)
> + {
> + struct d3d10_ctab_var *v = &p->vars[i];
> + memcpy(dst + v->offset, v->v->buffer->u.buffer.local_buffer, v->length * sizeof(*dst));
This is the one I mentioned at the top. Does this need to take
v->v->buffer_offset into account for the memcpy() source argument?
> +static HRESULT parse_fx10_fxlc(void *ctx, const char *data, unsigned int data_size)
> +{
> + struct d3d10_preshader_parse_context *context = ctx;
> + struct d3d10_effect_preshader *p = context->preshader;
> + unsigned int i, offset = 4;
> + uint32_t ins_count;
> + const char *ptr;
> + HRESULT hr;
> +
> + if (data_size % sizeof(uint32_t))
> + {
> + WARN("FXLC size misaligned %u.\n", data_size);
> + return E_FAIL;
> + }
> +
> + /* Parse through bytecode copy, so we can patch opcodes. */
This comment is not actual anymore. I think we can just get rid of it.
> +static HRESULT parse_fx10_ctab(void *ctx, const char *data, unsigned int data_size)
> +{
> + struct d3d10_preshader_parse_context *context = ctx;
> + struct d3d10_effect_preshader *p = context->preshader;
> + struct ctab_header
> + {
> + DWORD size;
> + DWORD creator;
> + DWORD version;
> + DWORD constants;
> + DWORD constantinfo;
> + DWORD flags;
> + DWORD target;
> + } header;
> + struct ctab_const_info
> + {
> + DWORD name;
> + WORD register_set;
> + WORD register_index;
> + WORD register_count;
> + WORD reserved;
> + DWORD typeinfo;
> + DWORD default_value;
> + } *info;
> + unsigned int i, cb_reg_count = 0;
> + const char *ptr = data;
> + const char *name;
> + size_t name_len;
> + HRESULT hr;
> +
> + if (data_size < sizeof(header))
> + {
> + WARN("Invalid constant table size %u.\n", data_size);
> + return E_FAIL;
> + }
> +
> + read_dword(&ptr, &header.size);
> + read_dword(&ptr, &header.creator);
> + read_dword(&ptr, &header.version);
> + read_dword(&ptr, &header.constants);
> + read_dword(&ptr, &header.constantinfo);
> + read_dword(&ptr, &header.flags);
> + read_dword(&ptr, &header.target);
> +
> + if (!require_space(header.constantinfo, header.constants, sizeof(*info), data_size))
> + {
> + WARN("Invalid constant info section offset %#x.\n", header.constantinfo);
> + return E_FAIL;
> + }
> +
> + p->vars_count = header.constants;
> +
> + TRACE("Variable count %u.\n", p->vars_count);
> +
> + if (!(p->vars = heap_calloc(p->vars_count, sizeof(*p->vars))))
> + return E_OUTOFMEMORY;
> +
> + /* Collect variables used in expression. */
That's somewhat specific to INDEX_EXPRESSION preshaders. I'd just
leave out the comment, the code is pretty self-explanatory anyway.
> + info = (struct ctab_const_info *)(data + header.constantinfo);
> + for (i = 0; i < p->vars_count; ++i, ++info)
> + {
> + if (!fx10_get_string(data, data_size, info->name, &name, &name_len))
> + return E_FAIL;
> +
> + if (!(p->vars[i].v = d3d10_effect_get_variable_by_name(context->effect, name)))
> + {
> + WARN("Couldn't find variable %s.\n", debugstr_a(name));
> + return E_FAIL;
> + }
> +
> + /* 4 components per register */
> + p->vars[i].offset = info->register_index * 4;
> + p->vars[i].length = info->register_count * 4;
> +
> + cb_reg_count = max(cb_reg_count, info->register_index + info->register_count);
> + }
> +
> + /* Allocate contiguous "constant buffer" for all referenced variables. */
> + if (FAILED(hr = d3d10_reg_table_allocate(&p->reg_tables[D3D10_REG_TABLE_CB], cb_reg_count * 4)))
> + {
> + WARN("Failed to allocate variables buffer.\n");
> + return hr;
> + }
> +
> + return S_OK;
> +}
> @@ -2051,14 +2545,75 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size
> dep.id = id;
> dep.idx = idx;
> dep.operation = operation;
> - dep.u.var.v = variable;
> - dep.u.var.offset = offset;
> + dep.var.v = variable;
> + dep.var.offset = offset;
>
> return d3d10_effect_add_prop_dependency(d, &dep);
> }
>
> break;
>
> + case D3D10_EOO_INDEX_EXPRESSION:
> +
> + /* Variable, and an expression for its index. */
> + if (value_offset >= data_size || !require_space(value_offset, 2, sizeof(DWORD), data_size))
> + {
> + WARN("Invalid offset %#x (data size %#lx).\n", value_offset, (long)data_size);
> + return E_FAIL;
> + }
> +
> + data_ptr = data + value_offset;
> + read_dword(&data_ptr, &value_offset);
> + read_dword(&data_ptr, &code_offset);
> +
> + if (!fx10_get_string(data, data_size, value_offset, &name, &name_len))
> + {
> + WARN("Failed to get variable name.\n");
> + return E_FAIL;
> + }
> +
> + TRACE("Variable name %s[<expr>].\n", debugstr_a(name));
> +
> + if (!(variable = d3d10_effect_get_variable_by_name(effect, name)))
> + {
> + WARN("Couldn't find variable %s.\n", debugstr_a(name));
> + return E_FAIL;
> + }
> +
> + /* Has to be an array */
> + if (!variable->type->element_count)
> + {
> + WARN("Expected array variable.\n");
> + return E_FAIL;
> + }
This comment can also go IMO.
> +
> + if (!is_object_property(property_info))
> + {
> + WARN("Expected object type property used with indexed expression.\n");
> + return E_FAIL;
> + }
> +
> + if (code_offset >= data_size || !require_space(code_offset, 1, sizeof(DWORD), data_size))
> + {
> + WARN("Invalid offset %#x (data size %#lx).\n", value_offset, (long)data_size);
> + return E_FAIL;
> + }
> +
> + data_ptr = data + code_offset;
> + read_dword(&data_ptr, &blob_size);
> +
> + dep.id = id;
> + dep.idx = idx;
> + dep.operation = operation;
> + dep.index_expr.v = variable;
> + if (FAILED(hr = parse_fx10_preshader(data_ptr, blob_size, effect, &dep.index_expr.index)))
> + {
> + WARN("Failed to parse preshader, hr %#x.\n", hr);
> + return hr;
> + }
> +
> + return d3d10_effect_add_prop_dependency(d, &dep);
> +
> case D3D10_EOO_ANONYMOUS_SHADER:
>
> /* Anonymous shader */
Nov. 9, 2021
Re: [PATCH 2/2] d3dx10: Implement D3DX10CreateTextureFromResource{A, W}.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
We could think about introducing a couple of helpers for the
FindResourceA/W() + load_resource() hunk: it's not a lot but the
duplication with D3DX10GetImageInfoFromResourceA/W() is a bit ugly.
Nov. 9, 2021
Re: [PATCH 1/2] d3dx10: Implement D3DX10CreateTextureFromFile{A,W}.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
Nov. 9, 2021
Re: [PATCH 1/3] wined3d: Test if an offset is needed to get the correct filling convention (v3).
by Stefan Dösinger
Hi,
> Am 09.11.2021 um 02:04 schrieb Francois Gouget <fgouget(a)codeweavers.com>:
> https://test.winehq.org/data/patterns.html#d3drm:d3drm
>
> d3drm.c:7295: Test succeeded inside todo block: Got unexpected color 0x00bada55.
Strange indeed, but note that I already made a todo_wine conditional in the ddraw tests for a similar reason. I'll check the d3drm stuff.
Nov. 9, 2021
[PATCH 4/4] winexinput.sys: Use +xinput channel.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/winexinput.sys/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winexinput.sys/main.c b/dlls/winexinput.sys/main.c
index abc61e8754f..339db17817c 100644
--- a/dlls/winexinput.sys/main.c
+++ b/dlls/winexinput.sys/main.c
@@ -37,7 +37,7 @@
#include "wine/asm.h"
#include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(winexinput);
+WINE_DEFAULT_DEBUG_CHANNEL(xinput);
#ifdef __ASM_USE_FASTCALL_WRAPPER
extern void *WINAPI wrap_fastcall_func1(void *func, const void *a);
--
2.33.1
Nov. 9, 2021
[PATCH 3/4] hid: Use +hid debug channel instead of +hidp.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/hid/hidp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c
index 90dc3211e45..ed2fa3906bd 100644
--- a/dlls/hid/hidp.c
+++ b/dlls/hid/hidp.c
@@ -34,7 +34,7 @@
#include "wine/hid.h"
#include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(hidp);
+WINE_DEFAULT_DEBUG_CHANNEL(hid);
static NTSTATUS get_value_caps_range( struct hid_preparsed_data *preparsed, HIDP_REPORT_TYPE report_type, ULONG report_len,
const struct hid_value_caps **caps, const struct hid_value_caps **caps_end )
--
2.33.1
Nov. 9, 2021
[PATCH 2/4] hidparse.sys: Use +hid debug channel.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/hidparse.sys/main.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/hidparse.sys/main.c b/dlls/hidparse.sys/main.c
index d455049d9b1..c07389044fd 100644
--- a/dlls/hidparse.sys/main.c
+++ b/dlls/hidparse.sys/main.c
@@ -35,7 +35,7 @@
#include "wine/list.h"
#include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(hidp);
+WINE_DEFAULT_DEBUG_CHANNEL(hid);
/* Flags that are defined in the document
"Device Class Definition for Human Interface Devices" */
@@ -122,7 +122,7 @@ static void debug_print_preparsed( struct hid_preparsed_data *data )
{
unsigned int i, end;
- if (TRACE_ON( hidp ))
+ if (TRACE_ON(hid))
{
TRACE( "usage %02x:%02x input %u-(%u)-%u, report len %u output %u-(%u)-%u, report len %u "
"feature %u-(%u)-%u, report len %u collections %u\n", data->usage_page, data->usage,
@@ -498,7 +498,7 @@ struct hid_preparsed_data *parse_descriptor( BYTE *descriptor, unsigned int leng
BYTE *ptr, *end;
int i;
- if (TRACE_ON( hidp ))
+ if (TRACE_ON(hid))
{
TRACE( "descriptor %p, length %u:\n", descriptor, length );
for (i = 0; i < length;)
--
2.33.1
Nov. 9, 2021