[PATCH 2/2] d3dx9: Get rid of constants modification bitmasks.
Paul Gofman
gofmanp at gmail.com
Mon Aug 28 18:16:04 CDT 2017
On 08/29/2017 01:51 AM, Matteo Bruni wrote:
> 2017-08-28 23:32 GMT+02:00 Paul Gofman <gofmanp at gmail.com>:
>> On 08/28/2017 09:00 PM, Matteo Bruni wrote:
>>>
>>>> @@ -971,10 +946,30 @@ static HRESULT get_constants_desc(unsigned int
>>>> *byte_code, struct d3dx_const_tab
>>>> if (FAILED(hr = init_set_constants_param(out, ctab, hc,
>>>> inputs_param[index])))
>>>> goto cleanup;
>>>> }
>>>> + if (pres)
>>>> + append_pres_const_set(out, pres);
>>>> if (out->const_set_count)
>>>> {
>>>> struct d3dx_const_param_eval_output *new_alloc;
>>>>
>>>> + qsort(out->const_set, out->const_set_count,
>>>> sizeof(*out->const_set), compare_const_set);
>>>> + for (i = 0; i < out->const_set_count - 1; ++i)
>>>> + {
>>>> + if (out->const_set[i].constant_class == D3DXPC_FORCE_DWORD
>>>> + && out->const_set[i + 1].constant_class ==
>>>> D3DXPC_FORCE_DWORD
>>>> + && out->const_set[i].table == out->const_set[i +
>>>> 1].table
>>>> + && out->const_set[i].register_index +
>>>> out->const_set[i].register_count
>>>> + >= out->const_set[i + 1].register_index)
>>>> + {
>>>> + out->const_set[i].register_count = out->const_set[i +
>>>> 1].register_index
>>>> + + out->const_set[i + 1].register_count -
>>>> out->const_set[i].register_index;
>>> I think this might lose account of some registers. E.g. consider the
>>> case where const_set[i] has register_index == 0 and register_count ==
>>> 4 while const_set[i + 1] has register_index == 1 and register_count ==
>>> 1. This would seem to lose track of the last two components.
>>>
>>> I know that preshaders found in the wild seem not to overwrite already
>>> written output registers but I wouldn't feel safe with (silently)
>>> depending on it.
>> This 'if' selects just preshader output constants. The entries for const_set
>> handled (merged) in this 'if' are those provided preshader instructions
>> which output anything to shader constants. They can potentially overlap
>> (that's why '>=' in the last 'if' check). I am not sure what can be wrong
>> with that? We track preshader output as a single "commit", the same does
>> native implementation according to our tests.
> I don't have any issues with the if condition. It's the
> const_set[i].register_count assignment which looks troublesome since
> it doesn't consider the old count. In the (artificial, even forced if
> you want) example I gave const_set[i].register_count would go from 4
> to 2 which doesn't seem right.
>
Here is how this register_count is currently evaluated:
---- snip ----
const_set.register_count = max(get_reg_offset(reg->table,
pres_op_info[ins->op].func_all_comps ? 1 :
ins->component_count), 1);
---- snip ----
This expression is written for some generic case of component_count
and components per register, but unless I am missing something this
expression should not evaluate to anything but 1 for the real cases. We
do not check that component count in instruction does not exceed
component count per register during preshader parse though (just
checking if it is between 1 and 4).
So maybe I will add an assert for the overlapping registers in
this 'if' under discussion just in case?
More information about the wine-devel
mailing list