On Tue, Nov 9, 2021 at 12:40 PM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3d10/effect.c | 595 +++++++++++++++++++++++++++++++++++++- dlls/d3d10/tests/effect.c | 147 ++++++++++ 2 files changed, 734 insertions(+), 8 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 78a3d0c386a..3f35e9cc28a 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c
+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->v->buffer_offset,
v->length * sizeof(*dst));
- }
- instr_count = *ip++;
- for (i = 0; i < instr_count; ++i)
- {
*(DWORD *)&ins = *ip++;
input_count = *ip++;
if (input_count > ARRAY_SIZE(args))
{
FIXME("Unexpected argument count %u.\n", input_count);
return E_FAIL;
}
/* Arguments */
for (j = 0; j < input_count; ++j)
{
ip++; /* TODO: argument register flags are currently ignored */
regt = *ip++;
offset = *ip++;
args[j] = d3d10_effect_preshader_get_reg_ptr(p, regt, offset);
}
ip++; /* TODO: result register flags are currently ignored */
regt = *ip++;
offset = *ip++;
retval = d3d10_effect_preshader_get_reg_ptr(p, regt, offset);
*retval = d3d10_effect_get_op_info(ins.opcode)->func(args, input_count);
Making sure I get this right: in d3d10 FXLVM all instructions / operands are scalar, correct?
@@ -528,24 +727,58 @@ static void d3d10_effect_update_dependent_props(struct d3d10_effect_prop_depende property_info = &property_infos[d->id];
dst = (char *)container + property_info->offset;
dst_index = (unsigned int *)((char *)container + property_info->index_offset); switch (d->operation) { case D3D10_EOO_VAR: case D3D10_EOO_CONST_INDEX:
v = d->u.var.v;
v = d->var.v; count = v->type->type_class == D3D10_SVC_VECTOR ? 4 : 1; for (j = 0; j < count; ++j) {
d3d10_effect_variable_get_raw_value(v, &value, d->u.var.offset + j * sizeof(value), sizeof(value));
d3d10_effect_variable_get_raw_value(v, &value, d->var.offset + j * sizeof(value), sizeof(value)); d3d10_effect_read_numeric_value(value, v->type->basetype, property_info->type, dst, j); } break;
case D3D10_EOO_INDEX_EXPRESSION:
v = d->index_expr.v;
if (FAILED(hr = d3d10_effect_preshader_eval(&d->index_expr.index)))
{
WARN("Failed to evaluate index expression, hr %#x.\n", hr);
return;
}
variable_idx = *d->index_expr.index.reg_tables[D3D10_REG_TABLE_RESULT].dword;
if (variable_idx >= v->type->element_count)
{
WARN("Expression evaluated to invalid index value %u, array %s of size %u.\n",
variable_idx, debugstr_a(v->name), v->type->element_count);
return;
}
/* Ignoring destination index here, there are no object typed array properties. */
switch (property_info->type)
{
case D3D10_SVT_VERTEXSHADER:
case D3D10_SVT_PIXELSHADER:
case D3D10_SVT_GEOMETRYSHADER:
*(void **)dst = v;
*dst_index = variable_idx;
break;
default:
*(void **)dst = &v->elements[variable_idx];
I guess we could have explicit D3D10_SVT_BLEND and such cases in the switch and print a WARN for those, to be super safe.