wined3d: Set an array of constant buffers as a single CS operation.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-07-05 21:40:52 -05:00 committed by Alexandre Julliard
parent a68cdf4a41
commit e6bbf6ee91
6 changed files with 87 additions and 53 deletions

View File

@ -560,20 +560,29 @@ static void d3d11_device_context_get_constant_buffers(ID3D11DeviceContext1 *ifac
wined3d_mutex_unlock(); wined3d_mutex_unlock();
} }
static void d3d11_device_context_set_constant_buffers(ID3D11DeviceContext1 *iface, static void d3d11_device_context_set_constant_buffers(ID3D11DeviceContext1 *iface, enum wined3d_shader_type type,
enum wined3d_shader_type type, UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers) unsigned int start_slot, unsigned int buffer_count, ID3D11Buffer *const *buffers)
{ {
struct wined3d_buffer *wined3d_buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface);
unsigned int i; unsigned int i;
wined3d_mutex_lock(); if (buffer_count > ARRAY_SIZE(wined3d_buffers))
{
WARN("Buffer count %u exceeds limit; ignoring call.\n", buffer_count);
return;
}
for (i = 0; i < buffer_count; ++i) for (i = 0; i < buffer_count; ++i)
{ {
struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]); struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]);
wined3d_device_context_set_constant_buffer(context->wined3d_context, type, start_slot + i, wined3d_buffers[i] = buffer ? buffer->wined3d_buffer : NULL;
buffer ? buffer->wined3d_buffer : NULL);
} }
wined3d_mutex_lock();
wined3d_device_context_set_constant_buffers(context->wined3d_context,
type, start_slot, buffer_count, wined3d_buffers);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
} }
@ -4571,20 +4580,29 @@ static void d3d10_device_get_constant_buffers(ID3D10Device1 *iface,
wined3d_mutex_unlock(); wined3d_mutex_unlock();
} }
static void d3d10_device_set_constant_buffers(ID3D10Device1 *iface, static void d3d10_device_set_constant_buffers(ID3D10Device1 *iface, enum wined3d_shader_type type,
enum wined3d_shader_type type, UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers) unsigned int start_slot, unsigned int buffer_count, ID3D10Buffer *const *buffers)
{ {
struct wined3d_buffer *wined3d_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
struct d3d_device *device = impl_from_ID3D10Device(iface); struct d3d_device *device = impl_from_ID3D10Device(iface);
unsigned int i; unsigned int i;
wined3d_mutex_lock(); if (buffer_count > ARRAY_SIZE(wined3d_buffers))
{
WARN("Buffer count %u exceeds limit; ignoring call.\n", buffer_count);
return;
}
for (i = 0; i < buffer_count; ++i) for (i = 0; i < buffer_count; ++i)
{ {
struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]); struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]);
wined3d_device_context_set_constant_buffer(device->immediate_context.wined3d_context, type, start_slot + i, wined3d_buffers[i] = buffer ? buffer->wined3d_buffer : NULL;
buffer ? buffer->wined3d_buffer : NULL);
} }
wined3d_mutex_lock();
wined3d_device_context_set_constant_buffers(device->immediate_context.wined3d_context,
type, start_slot, buffer_count, wined3d_buffers);
wined3d_mutex_unlock(); wined3d_mutex_unlock();
} }

View File

@ -120,7 +120,7 @@ enum wined3d_cs_op
WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ, WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ,
WINED3D_CS_OP_SET_STREAM_OUTPUT, WINED3D_CS_OP_SET_STREAM_OUTPUT,
WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_INDEX_BUFFER,
WINED3D_CS_OP_SET_CONSTANT_BUFFER, 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_VIEW,
WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW, WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW,
@ -285,12 +285,13 @@ struct wined3d_cs_set_index_buffer
unsigned int offset; unsigned int offset;
}; };
struct wined3d_cs_set_constant_buffer struct wined3d_cs_set_constant_buffers
{ {
enum wined3d_cs_op opcode; enum wined3d_cs_op opcode;
enum wined3d_shader_type type; enum wined3d_shader_type type;
UINT cb_idx; unsigned int start_idx;
struct wined3d_buffer *buffer; unsigned int count;
struct wined3d_buffer *buffers[1];
}; };
struct wined3d_cs_set_texture struct wined3d_cs_set_texture
@ -598,7 +599,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op)
WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ);
WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUT); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUT);
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_BUFFER); 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_VIEW);
WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW);
@ -1529,32 +1530,40 @@ void wined3d_device_context_emit_set_index_buffer(struct wined3d_device_context
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT);
} }
static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const void *data) static void wined3d_cs_exec_set_constant_buffers(struct wined3d_cs *cs, const void *data)
{ {
const struct wined3d_cs_set_constant_buffer *op = data; const struct wined3d_cs_set_constant_buffers *op = data;
struct wined3d_buffer *prev; unsigned int i;
prev = cs->state.cb[op->type][op->cb_idx]; for (i = 0; i < op->count; ++i)
cs->state.cb[op->type][op->cb_idx] = op->buffer; {
struct wined3d_buffer *prev = cs->state.cb[op->type][op->start_idx + i];
struct wined3d_buffer *buffer = op->buffers[i];
if (op->buffer) cs->state.cb[op->type][op->start_idx + i] = buffer;
InterlockedIncrement(&op->buffer->resource.bind_count);
if (prev) if (buffer)
InterlockedDecrement(&prev->resource.bind_count); InterlockedIncrement(&buffer->resource.bind_count);
if (prev)
InterlockedDecrement(&prev->resource.bind_count);
}
device_invalidate_state(cs->c.device, STATE_CONSTANT_BUFFER(op->type)); device_invalidate_state(cs->c.device, STATE_CONSTANT_BUFFER(op->type));
} }
void wined3d_device_context_emit_set_constant_buffer(struct wined3d_device_context *context, void wined3d_device_context_emit_set_constant_buffers(struct wined3d_device_context *context,
enum wined3d_shader_type type, UINT cb_idx, struct wined3d_buffer *buffer) enum wined3d_shader_type type, unsigned int start_idx, unsigned int count,
struct wined3d_buffer *const *buffers)
{ {
struct wined3d_cs_set_constant_buffer *op; struct wined3d_cs_set_constant_buffers *op;
op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op = wined3d_device_context_require_space(context, offsetof(struct wined3d_cs_set_constant_buffers, buffers[count]),
op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFER; WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_SET_CONSTANT_BUFFERS;
op->type = type; op->type = type;
op->cb_idx = cb_idx; op->start_idx = start_idx;
op->buffer = buffer; op->count = count;
memcpy(op->buffers, buffers, count * sizeof(*buffers));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT);
} }
@ -2890,7 +2899,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
/* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq,
/* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output,
/* 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_BUFFER */ wined3d_cs_exec_set_constant_buffer, /* 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_VIEW */ wined3d_cs_exec_set_shader_resource_view,
/* 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,

View File

@ -1696,8 +1696,7 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte
for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
{ {
wined3d_device_context_emit_set_shader(context, i, state->shader[i]); wined3d_device_context_emit_set_shader(context, i, state->shader[i]);
for (j = 0; j < MAX_CONSTANT_BUFFERS; ++j) wined3d_device_context_emit_set_constant_buffers(context, i, 0, MAX_CONSTANT_BUFFERS, state->cb[i]);
wined3d_device_context_emit_set_constant_buffer(context, i, j, state->cb[i][j]);
for (j = 0; j < MAX_SAMPLER_OBJECTS; ++j) for (j = 0; j < MAX_SAMPLER_OBJECTS; ++j)
{ {
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]);
@ -1834,30 +1833,36 @@ struct wined3d_shader * CDECL wined3d_device_context_get_shader(const struct win
return context->state->shader[type]; return context->state->shader[type];
} }
void CDECL wined3d_device_context_set_constant_buffer(struct wined3d_device_context *context, void CDECL wined3d_device_context_set_constant_buffers(struct wined3d_device_context *context,
enum wined3d_shader_type type, unsigned int idx, struct wined3d_buffer *buffer) enum wined3d_shader_type type, unsigned int start_idx, unsigned int count,
struct wined3d_buffer *const *buffers)
{ {
struct wined3d_state *state = context->state; struct wined3d_state *state = context->state;
struct wined3d_buffer *prev; unsigned int i;
TRACE("context %p, type %#x, idx %u, buffer %p.\n", context, type, idx, buffer); TRACE("context %p, type %#x, start_idx %u, count %u, buffers %p.\n", context, type, start_idx, count, buffers);
if (idx >= MAX_CONSTANT_BUFFERS) if (start_idx >= MAX_CONSTANT_BUFFERS || count > MAX_CONSTANT_BUFFERS - start_idx)
{ {
WARN("Invalid constant buffer index %u.\n", idx); WARN("Invalid constant buffer index %u, count %u.\n", start_idx, count);
return; return;
} }
prev = state->cb[type][idx]; if (!memcmp(buffers, &state->cb[type][start_idx], count * sizeof(*buffers)))
if (buffer == prev)
return; return;
if (buffer) wined3d_device_context_emit_set_constant_buffers(context, type, start_idx, count, buffers);
wined3d_buffer_incref(buffer); for (i = 0; i < count; ++i)
state->cb[type][idx] = buffer; {
wined3d_device_context_emit_set_constant_buffer(context, type, idx, buffer); struct wined3d_buffer *prev = state->cb[type][start_idx + i];
if (prev) struct wined3d_buffer *buffer = buffers[i];
wined3d_buffer_decref(prev);
if (buffer)
wined3d_buffer_incref(buffer);
state->cb[type][start_idx + i] = buffer;
if (prev)
wined3d_buffer_decref(prev);
}
} }
void CDECL wined3d_device_context_set_blend_state(struct wined3d_device_context *context, void CDECL wined3d_device_context_set_blend_state(struct wined3d_device_context *context,

View File

@ -123,7 +123,7 @@
@ cdecl wined3d_device_context_reset_state(ptr) @ cdecl wined3d_device_context_reset_state(ptr)
@ cdecl wined3d_device_context_resolve_sub_resource(ptr ptr long ptr long long) @ cdecl wined3d_device_context_resolve_sub_resource(ptr ptr long ptr long long)
@ cdecl wined3d_device_context_set_blend_state(ptr ptr ptr long) @ cdecl wined3d_device_context_set_blend_state(ptr ptr ptr long)
@ cdecl wined3d_device_context_set_constant_buffer(ptr long long ptr) @ cdecl wined3d_device_context_set_constant_buffers(ptr long long long ptr)
@ cdecl wined3d_device_context_set_depth_stencil_state(ptr ptr long) @ cdecl wined3d_device_context_set_depth_stencil_state(ptr ptr long)
@ cdecl wined3d_device_context_set_depth_stencil_view(ptr ptr) @ cdecl wined3d_device_context_set_depth_stencil_view(ptr ptr)
@ cdecl wined3d_device_context_set_index_buffer(ptr ptr long long) @ cdecl wined3d_device_context_set_index_buffer(ptr ptr long long)

View File

@ -4810,8 +4810,9 @@ void wined3d_device_context_emit_set_blend_state(struct wined3d_device_context *
unsigned int sample_mask) DECLSPEC_HIDDEN; unsigned int sample_mask) DECLSPEC_HIDDEN;
void wined3d_device_context_emit_set_clip_plane(struct wined3d_device_context *context, unsigned int plane_idx, void wined3d_device_context_emit_set_clip_plane(struct wined3d_device_context *context, unsigned int plane_idx,
const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN; const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN;
void wined3d_device_context_emit_set_constant_buffer(struct wined3d_device_context *context, void wined3d_device_context_emit_set_constant_buffers(struct wined3d_device_context *context,
enum wined3d_shader_type type, UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN; enum wined3d_shader_type type, unsigned int start_idx, unsigned int count,
struct wined3d_buffer *const *buffers) DECLSPEC_HIDDEN;
void wined3d_device_context_emit_set_depth_stencil_state(struct wined3d_device_context *context, void wined3d_device_context_emit_set_depth_stencil_state(struct wined3d_device_context *context,
struct wined3d_depth_stencil_state *state, unsigned int stencil_ref) DECLSPEC_HIDDEN; struct wined3d_depth_stencil_state *state, unsigned int stencil_ref) DECLSPEC_HIDDEN;
void wined3d_device_context_emit_set_depth_stencil_view(struct wined3d_device_context *context, void wined3d_device_context_emit_set_depth_stencil_view(struct wined3d_device_context *context,

View File

@ -2496,8 +2496,9 @@ void __cdecl wined3d_device_context_resolve_sub_resource(struct wined3d_device_c
struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, enum wined3d_format_id format_id); struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, enum wined3d_format_id format_id);
void __cdecl wined3d_device_context_set_blend_state(struct wined3d_device_context *context, void __cdecl wined3d_device_context_set_blend_state(struct wined3d_device_context *context,
struct wined3d_blend_state *state, const struct wined3d_color *blend_factor, unsigned int sample_mask); struct wined3d_blend_state *state, const struct wined3d_color *blend_factor, unsigned int sample_mask);
void __cdecl wined3d_device_context_set_constant_buffer(struct wined3d_device_context *context, void __cdecl wined3d_device_context_set_constant_buffers(struct wined3d_device_context *context,
enum wined3d_shader_type type, unsigned int idx, struct wined3d_buffer *buffer); enum wined3d_shader_type type, unsigned int start_idx, unsigned int count,
struct wined3d_buffer *const *buffers);
void __cdecl wined3d_device_context_set_depth_stencil_state(struct wined3d_device_context *context, void __cdecl wined3d_device_context_set_depth_stencil_state(struct wined3d_device_context *context,
struct wined3d_depth_stencil_state *depth_stencil_state, unsigned int stencil_ref); struct wined3d_depth_stencil_state *depth_stencil_state, unsigned int stencil_ref);
HRESULT __cdecl wined3d_device_context_set_depth_stencil_view(struct wined3d_device_context *context, HRESULT __cdecl wined3d_device_context_set_depth_stencil_view(struct wined3d_device_context *context,