wined3d: Send shader constant updates through the command stream.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2016-05-22 18:23:07 +02:00 committed by Alexandre Julliard
parent d104891433
commit aa666adfed
5 changed files with 68 additions and 38 deletions

View File

@ -729,12 +729,6 @@ static void shader_arb_update_float_vertex_constants(struct wined3d_device *devi
{
struct wined3d_context *context = context_get_current();
struct shader_arb_priv *priv = device->shader_priv;
unsigned int i;
for (i = 0; i < device->context_count; ++i)
{
device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F;
}
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
* context. On a context switch the old context will be fully dirtified */
@ -748,12 +742,6 @@ static void shader_arb_update_float_pixel_constants(struct wined3d_device *devic
{
struct wined3d_context *context = context_get_current();
struct shader_arb_priv *priv = device->shader_priv;
unsigned int i;
for (i = 0; i < device->context_count; ++i)
{
device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_PS_F;
}
/* We don't want shader constant dirtification to be an O(contexts), so just dirtify the active
* context. On a context switch the old context will be fully dirtified */

View File

@ -1070,10 +1070,54 @@ static void wined3d_cs_st_submit(struct wined3d_cs *cs)
wined3d_cs_op_handlers[opcode](cs, cs->data);
}
static void wined3d_cs_st_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p,
unsigned int start_idx, unsigned int count, const void *constants)
{
struct wined3d_device *device = cs->device;
unsigned int context_count;
unsigned int i;
size_t offset;
static const struct
{
size_t offset;
size_t size;
DWORD mask;
}
push_constant_info[] =
{
/* WINED3D_PUSH_CONSTANTS_VS_F */
{FIELD_OFFSET(struct wined3d_state, vs_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_VS_F},
/* WINED3D_PUSH_CONSTANTS_PS_F */
{FIELD_OFFSET(struct wined3d_state, ps_consts_f), sizeof(struct wined3d_vec4), WINED3D_SHADER_CONST_PS_F},
/* WINED3D_PUSH_CONSTANTS_VS_I */
{FIELD_OFFSET(struct wined3d_state, vs_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_VS_I},
/* WINED3D_PUSH_CONSTANTS_PS_I */
{FIELD_OFFSET(struct wined3d_state, ps_consts_i), sizeof(struct wined3d_ivec4), WINED3D_SHADER_CONST_PS_I},
/* WINED3D_PUSH_CONSTANTS_VS_B */
{FIELD_OFFSET(struct wined3d_state, vs_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_VS_B},
/* WINED3D_PUSH_CONSTANTS_PS_B */
{FIELD_OFFSET(struct wined3d_state, ps_consts_b), sizeof(BOOL), WINED3D_SHADER_CONST_PS_B},
};
if (p == WINED3D_PUSH_CONSTANTS_VS_F)
device->shader_backend->shader_update_float_vertex_constants(device, start_idx, count);
else if (p == WINED3D_PUSH_CONSTANTS_PS_F)
device->shader_backend->shader_update_float_pixel_constants(device, start_idx, count);
offset = push_constant_info[p].offset + start_idx * push_constant_info[p].size;
memcpy((BYTE *)&cs->state + offset, constants, count * push_constant_info[p].size);
for (i = 0, context_count = device->context_count; i < context_count; ++i)
{
device->contexts[i]->constant_update_mask |= push_constant_info[p].mask;
}
}
static const struct wined3d_cs_ops wined3d_cs_st_ops =
{
wined3d_cs_st_require_space,
wined3d_cs_st_submit,
wined3d_cs_st_push_constants,
};
struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)

View File

@ -2363,16 +2363,6 @@ struct wined3d_sampler * CDECL wined3d_device_get_vs_sampler(const struct wined3
return device->state.sampler[WINED3D_SHADER_TYPE_VERTEX][idx];
}
static void device_invalidate_shader_constants(const struct wined3d_device *device, DWORD mask)
{
UINT i;
for (i = 0; i < device->context_count; ++i)
{
device->contexts[i]->constant_update_mask |= mask;
}
}
HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device,
unsigned int start_idx, unsigned int count, const BOOL *constants)
{
@ -2400,7 +2390,7 @@ HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device,
}
else
{
device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_B);
wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_B, start_idx, count, constants);
}
return WINED3D_OK;
@ -2449,7 +2439,7 @@ HRESULT CDECL wined3d_device_set_vs_consts_i(struct wined3d_device *device,
}
else
{
device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_VS_I);
wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_I, start_idx, count, constants);
}
return WINED3D_OK;
@ -2494,7 +2484,7 @@ HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device,
memset(&device->recording->changed.vs_consts_f[start_idx], 1,
count * sizeof(*device->recording->changed.vs_consts_f));
else
device->shader_backend->shader_update_float_vertex_constants(device, start_idx, count);
wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_F, start_idx, count, constants);
return WINED3D_OK;
}
@ -2633,7 +2623,7 @@ HRESULT CDECL wined3d_device_set_ps_consts_b(struct wined3d_device *device,
}
else
{
device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_B);
wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_B, start_idx, count, constants);
}
return WINED3D_OK;
@ -2682,7 +2672,7 @@ HRESULT CDECL wined3d_device_set_ps_consts_i(struct wined3d_device *device,
}
else
{
device_invalidate_shader_constants(device, WINED3D_SHADER_CONST_PS_I);
wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_I, start_idx, count, constants);
}
return WINED3D_OK;
@ -2728,7 +2718,7 @@ HRESULT CDECL wined3d_device_set_ps_consts_f(struct wined3d_device *device,
memset(&device->recording->changed.ps_consts_f[start_idx], 1,
count * sizeof(*device->recording->changed.ps_consts_f));
else
device->shader_backend->shader_update_float_pixel_constants(device, start_idx, count);
wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_PS_F, start_idx, count, constants);
return WINED3D_OK;
}

View File

@ -1540,11 +1540,6 @@ static void shader_glsl_update_float_vertex_constants(struct wined3d_device *dev
{
update_heap_entry(heap, i, priv->next_constant_version);
}
for (i = 0; i < device->context_count; ++i)
{
device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_VS_F;
}
}
static void shader_glsl_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count)
@ -1557,11 +1552,6 @@ static void shader_glsl_update_float_pixel_constants(struct wined3d_device *devi
{
update_heap_entry(heap, i, priv->next_constant_version);
}
for (i = 0; i < device->context_count; ++i)
{
device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_PS_F;
}
}
static unsigned int vec4_varyings(DWORD shader_major, const struct wined3d_gl_info *gl_info)

View File

@ -2837,10 +2837,22 @@ void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb,
DWORD flags) DECLSPEC_HIDDEN;
void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN;
enum wined3d_push_constants
{
WINED3D_PUSH_CONSTANTS_VS_F,
WINED3D_PUSH_CONSTANTS_PS_F,
WINED3D_PUSH_CONSTANTS_VS_I,
WINED3D_PUSH_CONSTANTS_PS_I,
WINED3D_PUSH_CONSTANTS_VS_B,
WINED3D_PUSH_CONSTANTS_PS_B,
};
struct wined3d_cs_ops
{
void *(*require_space)(struct wined3d_cs *cs, size_t size);
void (*submit)(struct wined3d_cs *cs);
void (*push_constants)(struct wined3d_cs *cs, enum wined3d_push_constants p,
unsigned int start_idx, unsigned int count, const void *constants);
};
struct wined3d_cs
@ -2905,6 +2917,12 @@ void wined3d_cs_emit_set_vertex_declaration(struct wined3d_cs *cs,
struct wined3d_vertex_declaration *declaration) DECLSPEC_HIDDEN;
void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN;
static inline void wined3d_cs_push_constants(struct wined3d_cs *cs, enum wined3d_push_constants p,
unsigned int start_idx, unsigned int count, const void *constants)
{
cs->ops->push_constants(cs, p, start_idx, count, constants);
}
/* Direct3D terminology with little modifications. We do not have an issued state
* because only the driver knows about it, but we have a created state because d3d
* allows GetData on a created issue, but opengl doesn't