wined3d: Implement applying state for compute pipeline.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2017-02-06 14:12:14 +01:00 committed by Alexandre Julliard
parent 9311141cd4
commit 1b400f7433
4 changed files with 68 additions and 9 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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)
{

View File

@ -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)