=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Implement applying state for compute pipeline.
Alexandre Julliard
julliard at winehq.org
Tue Feb 7 16:02:28 CST 2017
Module: wine
Branch: master
Commit: 1b400f74335e8c4b9e919aeeb72de60f16a44b4d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1b400f74335e8c4b9e919aeeb72de60f16a44b4d
Author: Józef Kucia <jkucia at codeweavers.com>
Date: Mon Feb 6 14:12:14 2017 +0100
wined3d: Implement applying state for compute pipeline.
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/wined3d/context.c | 45 +++++++++++++++++++++++++++++++++++++-----
dlls/wined3d/cs.c | 19 ++++++++++++++----
dlls/wined3d/device.c | 8 ++++++++
dlls/wined3d/wined3d_private.h | 5 +++++
4 files changed, 68 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index c141d70..5ae1bdc 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1405,6 +1405,16 @@ static void context_enter(struct wined3d_context *context)
}
}
+void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id)
+{
+ DWORD representative = context->state_table[state_id].representative;
+ unsigned int index, shift;
+
+ index = representative / (sizeof(*context->dirty_compute_states) * CHAR_BIT);
+ shift = representative & (sizeof(*context->dirty_compute_states) * CHAR_BIT - 1);
+ context->dirty_compute_states[index] |= (1u << shift);
+}
+
void context_invalidate_state(struct wined3d_context *context, DWORD state)
{
DWORD rep = context->state_table[state].representative;
@@ -3312,7 +3322,8 @@ static void context_preload_textures(struct wined3d_context *context, const stru
}
}
-static void context_load_shader_resources(struct wined3d_context *context, const struct wined3d_state *state)
+static void context_load_shader_resources(struct wined3d_context *context, const struct wined3d_state *state,
+ unsigned int shader_mask)
{
struct wined3d_shader_sampler_map_entry *entry;
struct wined3d_shader_resource_view *view;
@@ -3321,6 +3332,9 @@ static void context_load_shader_resources(struct wined3d_context *context, const
for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
{
+ if (!(shader_mask & (1u << i)))
+ continue;
+
if (!(shader = state->shader[i]))
continue;
@@ -3489,7 +3503,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
* updating a resource location. */
context_update_tex_unit_map(context, state);
context_preload_textures(context, state);
- context_load_shader_resources(context, state);
+ context_load_shader_resources(context, state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE));
/* TODO: Right now the dependency on the vertex shader is necessary
* since context_stream_info_from_declaration depends on the reg_maps of
* the current VS but maybe it's possible to relax the coupling in some
@@ -3528,10 +3542,10 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
state_table[rep].apply(context, state, rep);
}
- if (context->shader_update_mask)
+ if (context->shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE))
{
device->shader_backend->shader_select(device->shader_priv, context, state);
- context->shader_update_mask = 0;
+ context->shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE;
}
if (context->constant_update_mask)
@@ -3566,7 +3580,28 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
void context_apply_compute_state(struct wined3d_context *context,
const struct wined3d_device *device, const struct wined3d_state *state)
{
- FIXME("Implement applying compute state.\n");
+ const struct StateEntry *state_table = context->state_table;
+ unsigned int state_id, i, j;
+
+ context_load_shader_resources(context, state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
+
+ for (i = 0, state_id = 0; i < ARRAY_SIZE(context->dirty_compute_states); ++i)
+ {
+ for (j = 0; j < sizeof(*context->dirty_compute_states) * CHAR_BIT; ++j, ++state_id)
+ {
+ if (context->dirty_compute_states[i] & (1u << j))
+ state_table[state_id].apply(context, state, state_id);
+ }
+ }
+ memset(context->dirty_compute_states, 0, sizeof(*context->dirty_compute_states));
+
+ if (context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE))
+ {
+ device->shader_backend->shader_select_compute(device->shader_priv, context, state);
+ context->shader_update_mask &= ~(1u << WINED3D_SHADER_TYPE_COMPUTE);
+ }
+
+ context->last_was_blit = FALSE;
}
static void context_setup_target(struct wined3d_context *context,
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 220ddee..d575159 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -907,7 +907,10 @@ static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const voi
if (prev)
InterlockedDecrement(&prev->resource.bind_count);
- device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
+ if (op->type != WINED3D_SHADER_TYPE_COMPUTE)
+ device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
+ else
+ device_invalidate_compute_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
}
void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type,
@@ -1020,7 +1023,8 @@ static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, cons
const struct wined3d_cs_set_shader_resource_view *op = data;
cs->state.shader_resource_view[op->type][op->view_idx] = op->view;
- device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
+ if (op->type != WINED3D_SHADER_TYPE_COMPUTE)
+ device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
}
void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, unsigned int view_idx,
@@ -1093,8 +1097,15 @@ static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data)
const struct wined3d_cs_set_shader *op = data;
cs->state.shader[op->type] = op->shader;
- device_invalidate_state(cs->device, STATE_SHADER(op->type));
- device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
+ if (op->type != WINED3D_SHADER_TYPE_COMPUTE)
+ {
+ device_invalidate_state(cs->device, STATE_SHADER(op->type));
+ device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
+ }
+ else
+ {
+ device_invalidate_compute_state(cs->device, STATE_SHADER(op->type));
+ }
}
void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 0e969be..71bb929 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5113,6 +5113,14 @@ void device_invalidate_state(const struct wined3d_device *device, DWORD state)
}
}
+void device_invalidate_compute_state(const struct wined3d_device *device, DWORD state_id)
+{
+ unsigned int i;
+
+ for (i = 0; i < device->context_count; ++i)
+ context_invalidate_compute_state(device->contexts[i], state_id);
+}
+
LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc)
{
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9b16e14..ead8847 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1427,6 +1427,8 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
#define STATE_HIGHEST (STATE_COLOR_KEY)
+#define STATE_COMPUTE_HIGHEST (STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE))
+
enum fogsource {
FOGSOURCE_FFP,
FOGSOURCE_VS,
@@ -1530,6 +1532,7 @@ struct wined3d_context
DWORD dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */
DWORD numDirtyEntries;
DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */
+ unsigned int dirty_compute_states[STATE_COMPUTE_HIGHEST / (sizeof(unsigned int) * CHAR_BIT) + 1];
struct wined3d_device *device;
struct wined3d_swapchain *swapchain;
@@ -1811,6 +1814,7 @@ GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) DE
DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN;
void context_gl_resource_released(struct wined3d_device *device,
GLuint name, BOOL rb_namespace) DECLSPEC_HIDDEN;
+void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
void context_invalidate_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_resource_released(const struct wined3d_device *device,
@@ -2627,6 +2631,7 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN;
void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+void device_invalidate_compute_state(const struct wined3d_device *device, DWORD state_id) DECLSPEC_HIDDEN;
void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN;
static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state)
More information about the wine-cvs
mailing list