[PATCH v2 1/2] wined3d: Support AMD alpha to coverage state.

Paul Gofman gofmanp at gmail.com
Tue Feb 11 11:18:38 CST 2020


On 2/11/20 19:32, Henri Verbeet wrote:
> On Mon, 10 Feb 2020 at 20:41, Paul Gofman <gofmanp at gmail.com> wrote:
>> -static void state_blend_object(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
>> +void state_atoc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
>>  {
> Why the rename? This is still the handler for blend state objects.
I thought the handler is already dealing just with ATOC state, other
parts of blend state are handled elsewhere. And now this is extended to
different ways of setting ATOC. Should I get the name back?
>> +    else
>> +    {
>> +        if (context->amd_atoc_enabled
>> +                && state->render_states[WINED3D_RS_POINTSIZE] != WINED3D_ALPHA_TO_COVERAGE_DISABLE)
>> +            return;
>> +
>> +        if (state->render_states[WINED3D_RS_POINTSIZE] == WINED3D_ALPHA_TO_COVERAGE_ENABLE)
>> +        {
>> +            alpha_to_coverage = TRUE;
>> +            context->amd_atoc_enabled = 1;
>> +        }
>> +        else
>> +        {
>> +            alpha_to_coverage = FALSE;
>> +            context->amd_atoc_enabled = 0;
>> +        }
>> +    }
> Does this imply that the current alpha to coverage state is supposed
> to stick as long as WINED3D_RS_POINTSIZE isn't set to either
> WINED3D_ALPHA_TO_COVERAGE_ENABLE or WINED3D_ALPHA_TO_COVERAGE_DISABLE?
> (And likewise that setting either of those shouldn't change the
> current point size?) If that's the case, you can't handle this here;
> d3d9 state is only flushed to wined3d on draws, so you'd miss
> intermediate states.

It is not consistent between the GPUs. I did some more testing lately,
Nvidia just considers the state to be enabled if D3DRS_ADAPTIVETESS_Y is
'ATOC' by the moment of the draw (and also requires alpha test to be
enabled), and ATOC is not in effect if there is any other value by the
moment of the draw. Intel, on the contrary, behaves like Nvidia docs
suggest, that is, ATOC state sticks until I set D3DFMT_UNKNOWN to
D3DRS_ADAPTIVETESS_Y. It gets reset even if I have something else set by
the moment of consequent draw (so yeah, this behaviour is currently not
reproduced exactly in these pacthes). I don't have AMD to test but if it
follows its own notes on this state and advertises the special value for
resetting ATOC state I guess it should behave like Intel (that is, ATOC
state is supposed to stick until reset with
WINED3D_ALPHA_TO_COVERAGE_DISABLE).

I've tested FC2 game with that 'return' removed, that is, enabling ATOC
strictly based on the states at the moment of the draw. It seems to work
fine this way both in 'Nvidia' and 'AMD' mode. So maybe it worth to
simplify the thing and just check for the currently present state here.

Otherwise I can maybe handle those states changes in
wined3d_cs_exec_set_render_state() and put a flag to wined3d_state which
will indicate if ATOC needs to be set or reset. STATE_BLEND can also be
invalidated there so the handler won't be called from the other places.

>
>> @@ -1532,6 +1549,8 @@ static void state_pscale(struct wined3d_context *context, const struct wined3d_s
>>
>>      gl_info->gl_ops.gl.p_glPointSize(max(pointsize, FLT_MIN));
>>      checkGLcall("glPointSize(...);");
>> +
>> +    state_atoc(context, state, state_id);
>>  }
> We'd typically guard that by "!isStateDirty(context, STATE_BLEND)",
> and perhaps a check on the value of WINED3D_RS_POINTSIZE.

I will add '!isStateDirty(context, STATE_BLEND)'. I am a bit unsure
about WINED3D_RS_POINTSIZE value, as that would probably mean I will
have to split (duplicate) the logic from state_blend() in some not very
straightforward way. Maybe I should rather introduce a separate handle
on WINED3D_RS_POINTSIZE instead (which will call state_pscale), so at
least the state_blend() would be called for the required state only?





More information about the wine-devel mailing list