Commit 7698b9e2 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

wined3d: Set an array of shader resource views as a single CS operation.

parent e6bbf6ee
...@@ -122,7 +122,7 @@ enum wined3d_cs_op ...@@ -122,7 +122,7 @@ enum wined3d_cs_op
WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_INDEX_BUFFER,
WINED3D_CS_OP_SET_CONSTANT_BUFFERS, WINED3D_CS_OP_SET_CONSTANT_BUFFERS,
WINED3D_CS_OP_SET_TEXTURE, WINED3D_CS_OP_SET_TEXTURE,
WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW, WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS,
WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW, WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW,
WINED3D_CS_OP_SET_SAMPLER, WINED3D_CS_OP_SET_SAMPLER,
WINED3D_CS_OP_SET_SHADER, WINED3D_CS_OP_SET_SHADER,
...@@ -310,12 +310,13 @@ struct wined3d_cs_set_color_key ...@@ -310,12 +310,13 @@ struct wined3d_cs_set_color_key
struct wined3d_color_key color_key; struct wined3d_color_key color_key;
}; };
struct wined3d_cs_set_shader_resource_view struct wined3d_cs_set_shader_resource_views
{ {
enum wined3d_cs_op opcode; enum wined3d_cs_op opcode;
enum wined3d_shader_type type; enum wined3d_shader_type type;
UINT view_idx; unsigned int start_idx;
struct wined3d_shader_resource_view *view; unsigned int count;
struct wined3d_shader_resource_view *views[1];
}; };
struct wined3d_cs_set_unordered_access_view struct wined3d_cs_set_unordered_access_view
...@@ -601,7 +602,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) ...@@ -601,7 +602,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op)
WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER); WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER);
WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS); WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS);
WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE); WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE);
WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS);
WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW);
WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLER); WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLER);
WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER); WINED3D_TO_STR(WINED3D_CS_OP_SET_SHADER);
...@@ -1659,18 +1660,23 @@ void wined3d_device_context_emit_set_texture(struct wined3d_device_context *cont ...@@ -1659,18 +1660,23 @@ void wined3d_device_context_emit_set_texture(struct wined3d_device_context *cont
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT);
} }
static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, const void *data) static void wined3d_cs_exec_set_shader_resource_views(struct wined3d_cs *cs, const void *data)
{ {
const struct wined3d_cs_set_shader_resource_view *op = data; const struct wined3d_cs_set_shader_resource_views *op = data;
struct wined3d_shader_resource_view *prev; unsigned int i;
prev = cs->state.shader_resource_view[op->type][op->view_idx]; for (i = 0; i < op->count; ++i)
cs->state.shader_resource_view[op->type][op->view_idx] = op->view; {
struct wined3d_shader_resource_view *prev = cs->state.shader_resource_view[op->type][op->start_idx + i];
struct wined3d_shader_resource_view *view = op->views[i];
if (op->view) cs->state.shader_resource_view[op->type][op->start_idx + i] = view;
InterlockedIncrement(&op->view->resource->bind_count);
if (prev) if (view)
InterlockedDecrement(&prev->resource->bind_count); InterlockedIncrement(&view->resource->bind_count);
if (prev)
InterlockedDecrement(&prev->resource->bind_count);
}
if (op->type != WINED3D_SHADER_TYPE_COMPUTE) if (op->type != WINED3D_SHADER_TYPE_COMPUTE)
device_invalidate_state(cs->c.device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); device_invalidate_state(cs->c.device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
...@@ -1678,16 +1684,19 @@ static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, cons ...@@ -1678,16 +1684,19 @@ static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, cons
device_invalidate_state(cs->c.device, STATE_COMPUTE_SHADER_RESOURCE_BINDING); device_invalidate_state(cs->c.device, STATE_COMPUTE_SHADER_RESOURCE_BINDING);
} }
void wined3d_device_context_emit_set_shader_resource_view(struct wined3d_device_context *context, void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device_context *context,
enum wined3d_shader_type type, unsigned int view_idx, struct wined3d_shader_resource_view *view) enum wined3d_shader_type type, unsigned int start_idx, unsigned int count,
struct wined3d_shader_resource_view *const *views)
{ {
struct wined3d_cs_set_shader_resource_view *op; struct wined3d_cs_set_shader_resource_views *op;
op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op = wined3d_device_context_require_space(context,
op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW; offsetof(struct wined3d_cs_set_shader_resource_views, views[count]), WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS;
op->type = type; op->type = type;
op->view_idx = view_idx; op->start_idx = start_idx;
op->view = view; op->count = count;
memcpy(op->views, views, count * sizeof(*views));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT);
} }
...@@ -2901,7 +2910,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void ...@@ -2901,7 +2910,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
/* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer,
/* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers, /* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers,
/* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture,
/* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW */ wined3d_cs_exec_set_shader_resource_view, /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEWS */ wined3d_cs_exec_set_shader_resource_views,
/* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view, /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_set_unordered_access_view,
/* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler, /* WINED3D_CS_OP_SET_SAMPLER */ wined3d_cs_exec_set_sampler,
/* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader, /* WINED3D_CS_OP_SET_SHADER */ wined3d_cs_exec_set_shader,
......
...@@ -1701,10 +1701,8 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte ...@@ -1701,10 +1701,8 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte
{ {
wined3d_device_context_emit_set_sampler(context, i, j, state->sampler[i][j]); wined3d_device_context_emit_set_sampler(context, i, j, state->sampler[i][j]);
} }
for (j = 0; j < MAX_SHADER_RESOURCE_VIEWS; ++j) wined3d_device_context_emit_set_shader_resource_views(context, i, 0,
{ MAX_SHADER_RESOURCE_VIEWS, state->shader_resource_view[i]);
wined3d_device_context_emit_set_shader_resource_view(context, i, j, state->shader_resource_view[i][j]);
}
} }
for (i = 0; i < WINED3D_PIPELINE_COUNT; ++i) for (i = 0; i < WINED3D_PIPELINE_COUNT; ++i)
...@@ -1982,45 +1980,58 @@ void CDECL wined3d_device_context_set_scissor_rects(struct wined3d_device_contex ...@@ -1982,45 +1980,58 @@ void CDECL wined3d_device_context_set_scissor_rects(struct wined3d_device_contex
wined3d_device_context_emit_set_scissor_rects(context, rect_count, rects); wined3d_device_context_emit_set_scissor_rects(context, rect_count, rects);
} }
void CDECL wined3d_device_context_set_shader_resource_view(struct wined3d_device_context *context, void CDECL wined3d_device_context_set_shader_resource_views(struct wined3d_device_context *context,
enum wined3d_shader_type type, unsigned int idx, struct wined3d_shader_resource_view *view) enum wined3d_shader_type type, unsigned int start_idx, unsigned int count,
struct wined3d_shader_resource_view *const *const views)
{ {
struct wined3d_shader_resource_view *real_views[MAX_SHADER_RESOURCE_VIEWS];
struct wined3d_state *state = context->state; struct wined3d_state *state = context->state;
const struct wined3d_rendertarget_view *dsv; const struct wined3d_rendertarget_view *dsv = state->fb.depth_stencil;
struct wined3d_shader_resource_view *prev; unsigned int i;
TRACE("context %p, type %#x, idx %u, view %p.\n", context, type, idx, view); TRACE("context %p, type %#x, start_idx %u, count %u, views %p.\n", context, type, start_idx, count, views);
if (idx >= MAX_SHADER_RESOURCE_VIEWS) if (start_idx >= MAX_SHADER_RESOURCE_VIEWS || count > MAX_SHADER_RESOURCE_VIEWS - start_idx)
{ {
WARN("Invalid view index %u.\n", idx); WARN("Invalid view index %u, count %u.\n", start_idx, count);
return; return;
} }
prev = state->shader_resource_view[type][idx]; if (!memcmp(views, &state->shader_resource_view[type][start_idx], count * sizeof(*views)))
if (view == prev)
return; return;
if (view && (wined3d_is_srv_rtv_bound(state, view) memcpy(real_views, views, count * sizeof(*views));
|| ((dsv = state->fb.depth_stencil)
&& dsv->resource == view->resource && wined3d_dsv_srv_conflict(dsv, view->format))))
{
WARN("Application is trying to bind resource which is attached as render target.\n");
view = NULL;
}
if (view) for (i = 0; i < count; ++i)
{ {
wined3d_shader_resource_view_incref(view); struct wined3d_shader_resource_view *view = real_views[i];
wined3d_srv_bind_count_inc(view);
if (view && (wined3d_is_srv_rtv_bound(state, view)
|| (dsv && dsv->resource == view->resource && wined3d_dsv_srv_conflict(dsv, view->format))))
{
WARN("Application is trying to bind resource which is attached as render target.\n");
real_views[i] = NULL;
}
} }
state->shader_resource_view[type][idx] = view; wined3d_device_context_emit_set_shader_resource_views(context, type, start_idx, count, real_views);
wined3d_device_context_emit_set_shader_resource_view(context, type, idx, view); for (i = 0; i < count; ++i)
if (prev)
{ {
wined3d_srv_bind_count_dec(prev); struct wined3d_shader_resource_view *prev = state->shader_resource_view[type][start_idx + i];
wined3d_shader_resource_view_decref(prev); struct wined3d_shader_resource_view *view = real_views[i];
if (view)
{
wined3d_shader_resource_view_incref(view);
wined3d_srv_bind_count_inc(view);
}
state->shader_resource_view[type][start_idx + i] = view;
if (prev)
{
wined3d_srv_bind_count_dec(prev);
wined3d_shader_resource_view_decref(prev);
}
} }
} }
...@@ -2100,8 +2111,10 @@ static void wined3d_device_context_unbind_srv_for_rtv(struct wined3d_device_cont ...@@ -2100,8 +2111,10 @@ static void wined3d_device_context_unbind_srv_for_rtv(struct wined3d_device_cont
&& ((!dsv && wined3d_is_srv_rtv_bound(state, srv)) && ((!dsv && wined3d_is_srv_rtv_bound(state, srv))
|| (dsv && wined3d_dsv_srv_conflict(view, srv->format)))) || (dsv && wined3d_dsv_srv_conflict(view, srv->format))))
{ {
static struct wined3d_shader_resource_view *const null_srv;
WARN("Application sets bound resource as render target.\n"); WARN("Application sets bound resource as render target.\n");
wined3d_device_context_set_shader_resource_view(context, i, j, NULL); wined3d_device_context_set_shader_resource_views(context, i, j, 1, &null_srv);
} }
} }
} }
......
...@@ -134,7 +134,7 @@ ...@@ -134,7 +134,7 @@
@ cdecl wined3d_device_context_set_sampler(ptr long long ptr) @ cdecl wined3d_device_context_set_sampler(ptr long long ptr)
@ cdecl wined3d_device_context_set_scissor_rects(ptr long ptr) @ cdecl wined3d_device_context_set_scissor_rects(ptr long ptr)
@ cdecl wined3d_device_context_set_shader(ptr long ptr) @ cdecl wined3d_device_context_set_shader(ptr long ptr)
@ cdecl wined3d_device_context_set_shader_resource_view(ptr long long ptr) @ cdecl wined3d_device_context_set_shader_resource_views(ptr long long long ptr)
@ cdecl wined3d_device_context_set_state(ptr ptr) @ cdecl wined3d_device_context_set_state(ptr ptr)
@ cdecl wined3d_device_context_set_stream_output(ptr long ptr long) @ cdecl wined3d_device_context_set_stream_output(ptr long ptr long)
@ cdecl wined3d_device_context_set_stream_source(ptr long ptr long long) @ cdecl wined3d_device_context_set_stream_source(ptr long ptr long long)
......
...@@ -4843,9 +4843,9 @@ void wined3d_device_context_emit_set_scissor_rects(struct wined3d_device_context ...@@ -4843,9 +4843,9 @@ void wined3d_device_context_emit_set_scissor_rects(struct wined3d_device_context
unsigned int rect_count, const RECT *rects) DECLSPEC_HIDDEN; unsigned int rect_count, const RECT *rects) DECLSPEC_HIDDEN;
void wined3d_device_context_emit_set_shader(struct wined3d_device_context *context, enum wined3d_shader_type type, void wined3d_device_context_emit_set_shader(struct wined3d_device_context *context, enum wined3d_shader_type type,
struct wined3d_shader *shader) DECLSPEC_HIDDEN; struct wined3d_shader *shader) DECLSPEC_HIDDEN;
void wined3d_device_context_emit_set_shader_resource_view(struct wined3d_device_context *context, void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device_context *context,
enum wined3d_shader_type type, unsigned int view_idx, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count,
struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN; struct wined3d_shader_resource_view *const *views) DECLSPEC_HIDDEN;
void wined3d_device_context_emit_set_stream_output(struct wined3d_device_context *context, unsigned int stream_idx, void wined3d_device_context_emit_set_stream_output(struct wined3d_device_context *context, unsigned int stream_idx,
struct wined3d_buffer *buffer, unsigned int offset) DECLSPEC_HIDDEN; struct wined3d_buffer *buffer, unsigned int offset) DECLSPEC_HIDDEN;
void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx,
......
...@@ -2519,8 +2519,9 @@ void __cdecl wined3d_device_context_set_scissor_rects(struct wined3d_device_cont ...@@ -2519,8 +2519,9 @@ void __cdecl wined3d_device_context_set_scissor_rects(struct wined3d_device_cont
const RECT *rects); const RECT *rects);
void __cdecl wined3d_device_context_set_shader(struct wined3d_device_context *context, void __cdecl wined3d_device_context_set_shader(struct wined3d_device_context *context,
enum wined3d_shader_type type, struct wined3d_shader *shader); enum wined3d_shader_type type, struct wined3d_shader *shader);
void __cdecl wined3d_device_context_set_shader_resource_view(struct wined3d_device_context *context, void __cdecl wined3d_device_context_set_shader_resource_views(struct wined3d_device_context *context,
enum wined3d_shader_type type, unsigned int idx, struct wined3d_shader_resource_view *view); enum wined3d_shader_type type, unsigned int start_idx, unsigned int count,
struct wined3d_shader_resource_view *const *views);
void __cdecl wined3d_device_context_set_state(struct wined3d_device_context *context, struct wined3d_state *state); void __cdecl wined3d_device_context_set_state(struct wined3d_device_context *context, struct wined3d_state *state);
void __cdecl wined3d_device_context_set_stream_output(struct wined3d_device_context *context, unsigned int idx, void __cdecl wined3d_device_context_set_stream_output(struct wined3d_device_context *context, unsigned int idx,
struct wined3d_buffer *buffer, unsigned int offset); struct wined3d_buffer *buffer, unsigned int offset);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment