wined3d: Support AMD alpha to coverage state.
Signed-off-by: Paul Gofman <gofmanp@gmail.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
84cd082495
commit
c736321633
|
@ -26679,8 +26679,8 @@ static void test_alpha_to_coverage(void)
|
|||
get_rt_readback(rt, &rb);
|
||||
colour = get_readback_color(&rb, 64, 64);
|
||||
|
||||
/* Nvidia is probably using some proprietary algorithm for averaging sample colour values. */
|
||||
todo_wine ok(color_match(colour, 0x9f404080, 1) || color_match(colour, 0x9f485cbc, 1) /* Nvidia */,
|
||||
/* NVIDIA is probably using some proprietary algorithm for averaging sample colour values. */
|
||||
ok(color_match(colour, 0x9f404080, 1) || color_match(colour, 0x9f485cbc, 1) /* NVIDIA */,
|
||||
"Got unexpected colour %08x.\n", colour);
|
||||
release_surface_readback(&rb);
|
||||
|
||||
|
|
|
@ -529,6 +529,8 @@ void wined3d_device_cleanup(struct wined3d_device *device)
|
|||
if (device->swapchain_count)
|
||||
wined3d_device_uninit_3d(device);
|
||||
|
||||
wined3d_blend_state_decref(device->blend_state_atoc_enabled);
|
||||
|
||||
wined3d_cs_destroy(device->cs);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(device->multistate_funcs); ++i)
|
||||
|
@ -3837,6 +3839,8 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
|
|||
const struct wined3d_d3d_info *d3d_info = &stateblock->device->adapter->d3d_info;
|
||||
const struct wined3d_stateblock_state *state = &stateblock->stateblock_state;
|
||||
const struct wined3d_saved_states *changed = &stateblock->changed;
|
||||
struct wined3d_blend_state *blend_state;
|
||||
struct wined3d_color colour;
|
||||
unsigned int i, j, count;
|
||||
|
||||
TRACE("device %p, stateblock %p.\n", device, stateblock);
|
||||
|
@ -3941,18 +3945,32 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
|
|||
}
|
||||
}
|
||||
|
||||
if (changed->blend_state)
|
||||
{
|
||||
if (wined3d_bitmap_is_set(changed->renderState, WINED3D_RS_BLENDFACTOR))
|
||||
wined3d_color_from_d3dcolor(&colour, stateblock->stateblock_state.rs[WINED3D_RS_BLENDFACTOR]);
|
||||
else
|
||||
wined3d_device_get_blend_state(device, &colour);
|
||||
|
||||
wined3d_device_set_blend_state(device, state->blend_state, &colour);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(state->rs); ++i)
|
||||
{
|
||||
if (wined3d_bitmap_is_set(changed->renderState, i))
|
||||
if (!wined3d_bitmap_is_set(changed->renderState, i))
|
||||
continue;
|
||||
|
||||
if (i != WINED3D_RS_BLENDFACTOR)
|
||||
{
|
||||
if (i == WINED3D_RS_BLENDFACTOR)
|
||||
{
|
||||
struct wined3d_color color;
|
||||
wined3d_color_from_d3dcolor(&color, state->rs[i]);
|
||||
wined3d_device_set_blend_state(device, NULL, &color);
|
||||
}
|
||||
else
|
||||
wined3d_device_set_render_state(device, i, state->rs[i]);
|
||||
wined3d_device_set_render_state(device, i, state->rs[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!changed->blend_state)
|
||||
{
|
||||
blend_state = wined3d_device_get_blend_state(device, &colour);
|
||||
wined3d_color_from_d3dcolor(&colour, state->rs[i]);
|
||||
wined3d_device_set_blend_state(device, blend_state, &colour);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5760,6 +5778,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
|
|||
struct wined3d_adapter *adapter = wined3d->adapters[adapter_idx];
|
||||
const struct wined3d_fragment_pipe_ops *fragment_pipeline;
|
||||
const struct wined3d_vertex_pipe_ops *vertex_pipeline;
|
||||
struct wined3d_blend_state_desc blend_state_desc;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -5814,6 +5833,18 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
|
|||
goto err;
|
||||
}
|
||||
|
||||
memset(&blend_state_desc, 0, sizeof(blend_state_desc));
|
||||
blend_state_desc.alpha_to_coverage = TRUE;
|
||||
|
||||
if (FAILED(hr = wined3d_blend_state_create(device, &blend_state_desc,
|
||||
NULL, &wined3d_null_parent_ops, &device->blend_state_atoc_enabled)))
|
||||
{
|
||||
ERR("Failed to create blend state object, hr %#x.\n", hr);
|
||||
wined3d_cs_destroy(device->cs);
|
||||
state_cleanup(&device->state);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
|
||||
err:
|
||||
|
|
|
@ -209,6 +209,7 @@ static void stateblock_savedstates_set_all(struct wined3d_saved_states *states,
|
|||
states->pixelShader = 1;
|
||||
states->vertexShader = 1;
|
||||
states->scissorRect = 1;
|
||||
states->blend_state = 1;
|
||||
|
||||
/* Fixed size arrays */
|
||||
states->streamSource = 0xffff;
|
||||
|
@ -263,6 +264,7 @@ static void stateblock_savedstates_set_vertex(struct wined3d_saved_states *state
|
|||
|
||||
states->vertexDecl = 1;
|
||||
states->vertexShader = 1;
|
||||
states->blend_state = 1;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(vertex_states_render); ++i)
|
||||
{
|
||||
|
@ -426,6 +428,7 @@ void state_unbind_resources(struct wined3d_state *state)
|
|||
struct wined3d_unordered_access_view *uav;
|
||||
struct wined3d_shader_resource_view *srv;
|
||||
struct wined3d_vertex_declaration *decl;
|
||||
struct wined3d_blend_state *blend_state;
|
||||
struct wined3d_sampler *sampler;
|
||||
struct wined3d_texture *texture;
|
||||
struct wined3d_buffer *buffer;
|
||||
|
@ -519,12 +522,19 @@ void state_unbind_resources(struct wined3d_state *state)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((blend_state = state->blend_state))
|
||||
{
|
||||
state->blend_state = NULL;
|
||||
wined3d_blend_state_decref(blend_state);
|
||||
}
|
||||
}
|
||||
|
||||
void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state)
|
||||
{
|
||||
struct wined3d_light_info *light, *cursor;
|
||||
struct wined3d_vertex_declaration *decl;
|
||||
struct wined3d_blend_state *blend_state;
|
||||
struct wined3d_texture *texture;
|
||||
struct wined3d_buffer *buffer;
|
||||
struct wined3d_shader *shader;
|
||||
|
@ -580,6 +590,12 @@ void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state)
|
|||
heap_free(light);
|
||||
}
|
||||
}
|
||||
|
||||
if ((blend_state = state->blend_state))
|
||||
{
|
||||
state->blend_state = NULL;
|
||||
wined3d_blend_state_decref(blend_state);
|
||||
}
|
||||
}
|
||||
|
||||
void state_cleanup(struct wined3d_state *state)
|
||||
|
@ -1017,6 +1033,15 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock,
|
|||
|
||||
wined3d_state_record_lights(stateblock->stateblock_state.light_state, state->light_state);
|
||||
|
||||
if (stateblock->changed.blend_state && stateblock->stateblock_state.blend_state != state->blend_state)
|
||||
{
|
||||
if (state->blend_state)
|
||||
wined3d_blend_state_incref(state->blend_state);
|
||||
if (stateblock->stateblock_state.blend_state)
|
||||
wined3d_blend_state_decref(stateblock->stateblock_state.blend_state);
|
||||
stateblock->stateblock_state.blend_state = state->blend_state;
|
||||
}
|
||||
|
||||
TRACE("Capture done.\n");
|
||||
}
|
||||
|
||||
|
@ -1025,6 +1050,8 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock,
|
|||
{
|
||||
struct wined3d_stateblock_state *state = &device_state->stateblock_state;
|
||||
struct wined3d_device *device = stateblock->device;
|
||||
struct wined3d_blend_state *blend_state;
|
||||
struct wined3d_color colour;
|
||||
unsigned int i;
|
||||
DWORD map;
|
||||
|
||||
|
@ -1113,20 +1140,41 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock,
|
|||
wined3d_device_set_ps_consts_b(device, idx, 1, &stateblock->stateblock_state.ps_consts_b[idx]);
|
||||
}
|
||||
|
||||
if (stateblock->changed.blend_state)
|
||||
{
|
||||
if (stateblock->stateblock_state.blend_state)
|
||||
wined3d_blend_state_incref(stateblock->stateblock_state.blend_state);
|
||||
if (state->blend_state)
|
||||
wined3d_blend_state_decref(state->blend_state);
|
||||
|
||||
state->blend_state = stateblock->stateblock_state.blend_state;
|
||||
|
||||
if (wined3d_bitmap_is_set(stateblock->changed.renderState, WINED3D_RS_BLENDFACTOR))
|
||||
wined3d_color_from_d3dcolor(&colour, stateblock->stateblock_state.rs[WINED3D_RS_BLENDFACTOR]);
|
||||
else
|
||||
wined3d_device_get_blend_state(device, &colour);
|
||||
|
||||
wined3d_device_set_blend_state(device, stateblock->stateblock_state.blend_state, &colour);
|
||||
}
|
||||
|
||||
/* Render states. */
|
||||
for (i = 0; i < stateblock->num_contained_render_states; ++i)
|
||||
{
|
||||
enum wined3d_render_state rs = stateblock->contained_render_states[i];
|
||||
|
||||
state->rs[rs] = stateblock->stateblock_state.rs[rs];
|
||||
if (rs == WINED3D_RS_BLENDFACTOR)
|
||||
if (rs != WINED3D_RS_BLENDFACTOR)
|
||||
{
|
||||
struct wined3d_color color;
|
||||
wined3d_color_from_d3dcolor(&color, stateblock->stateblock_state.rs[rs]);
|
||||
wined3d_device_set_blend_state(device, NULL, &color);
|
||||
}
|
||||
else
|
||||
wined3d_device_set_render_state(device, rs, stateblock->stateblock_state.rs[rs]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!stateblock->changed.blend_state)
|
||||
{
|
||||
blend_state = wined3d_device_get_blend_state(device, &colour);
|
||||
wined3d_color_from_d3dcolor(&colour, stateblock->stateblock_state.rs[rs]);
|
||||
wined3d_device_set_blend_state(device, blend_state, &colour);
|
||||
}
|
||||
}
|
||||
|
||||
/* Texture states. */
|
||||
|
@ -1426,6 +1474,23 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb
|
|||
|
||||
stateblock->stateblock_state.rs[state] = value;
|
||||
stateblock->changed.renderState[state >> 5] |= 1u << (state & 0x1f);
|
||||
|
||||
if (state == WINED3D_RS_POINTSIZE
|
||||
&& (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE || value == WINED3D_ALPHA_TO_COVERAGE_DISABLE))
|
||||
{
|
||||
stateblock->changed.blend_state = 1;
|
||||
|
||||
if (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE && !stateblock->stateblock_state.blend_state)
|
||||
{
|
||||
wined3d_blend_state_incref(stateblock->device->blend_state_atoc_enabled);
|
||||
stateblock->stateblock_state.blend_state = stateblock->device->blend_state_atoc_enabled;
|
||||
}
|
||||
else if (value == WINED3D_ALPHA_TO_COVERAGE_DISABLE && stateblock->stateblock_state.blend_state)
|
||||
{
|
||||
wined3d_blend_state_decref(stateblock->stateblock_state.blend_state);
|
||||
stateblock->stateblock_state.blend_state = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDECL wined3d_stateblock_set_sampler_state(struct wined3d_stateblock *stateblock,
|
||||
|
|
|
@ -76,6 +76,9 @@
|
|||
|
||||
#define WINED3D_MAX_DIRTY_REGION_COUNT 7
|
||||
|
||||
#define WINED3D_ALPHA_TO_COVERAGE_ENABLE MAKEFOURCC('A','2','M','1')
|
||||
#define WINED3D_ALPHA_TO_COVERAGE_DISABLE MAKEFOURCC('A','2','M','0')
|
||||
|
||||
struct wined3d_fragment_pipe_ops;
|
||||
struct wined3d_adapter;
|
||||
struct wined3d_context;
|
||||
|
@ -3314,6 +3317,7 @@ struct wined3d_device
|
|||
/* Context management */
|
||||
struct wined3d_context **contexts;
|
||||
UINT context_count;
|
||||
struct wined3d_blend_state *blend_state_atoc_enabled;
|
||||
};
|
||||
|
||||
void wined3d_device_cleanup(struct wined3d_device *device) DECLSPEC_HIDDEN;
|
||||
|
@ -3932,7 +3936,8 @@ struct wined3d_saved_states
|
|||
DWORD vertexShader : 1;
|
||||
DWORD scissorRect : 1;
|
||||
DWORD store_stream_offset : 1;
|
||||
DWORD padding : 4;
|
||||
DWORD blend_state : 1;
|
||||
DWORD padding : 3;
|
||||
};
|
||||
|
||||
struct StageState {
|
||||
|
|
|
@ -2168,6 +2168,7 @@ struct wined3d_stateblock_state
|
|||
RECT scissor_rect;
|
||||
|
||||
struct wined3d_light_state *light_state;
|
||||
struct wined3d_blend_state *blend_state;
|
||||
};
|
||||
|
||||
struct wined3d_parent_ops
|
||||
|
|
Loading…
Reference in New Issue