Henri Verbeet : wined3d: Send shader constant updates through the command stream.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon May 23 10:27:44 CDT 2016
Module: wine
Branch: master
Commit: aa666adfed929a2f711d9570fe389856bcaac346
URL: http://source.winehq.org/git/wine.git/?a=commit;h=aa666adfed929a2f711d9570fe389856bcaac346
Author: Henri Verbeet <hverbeet at codeweavers.com>
Date: Sun May 22 18:23:07 2016 +0200
wined3d: Send shader constant updates through the command stream.
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/wined3d/arb_program_shader.c | 12 -----------
dlls/wined3d/cs.c | 44 +++++++++++++++++++++++++++++++++++++++
dlls/wined3d/device.c | 22 ++++++--------------
dlls/wined3d/glsl_shader.c | 10 ---------
dlls/wined3d/wined3d_private.h | 18 ++++++++++++++++
5 files changed, 68 insertions(+), 38 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 0fb2f67..80702a2 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -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 */
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index ea4778c..edb5cf2 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -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)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index da83b56..967a831 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -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;
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 8c22468..b228718 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -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)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 00f34e9..65270d4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -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
More information about the wine-cvs
mailing list