Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3d11/device.c | 29 +++++++++----------- dlls/wined3d/cs.c | 49 ++++++++++++++++------------------ dlls/wined3d/device.c | 40 +++++++++++---------------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 10 ++----- include/wine/wined3d.h | 10 +++++-- 6 files changed, 63 insertions(+), 77 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 93df97e59ae..46e2c8ba67f 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -1181,24 +1181,23 @@ static void STDMETHODCALLTYPE d3d11_device_context_OMSetDepthStencilState(ID3D11 static void STDMETHODCALLTYPE d3d11_device_context_SOSetTargets(ID3D11DeviceContext1 *iface, UINT buffer_count, ID3D11Buffer *const *buffers, const UINT *offsets) { + struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS] = {0}; struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); unsigned int count, i;
TRACE("iface %p, buffer_count %u, buffers %p, offsets %p.\n", iface, buffer_count, buffers, offsets);
- count = min(buffer_count, D3D11_SO_BUFFER_SLOT_COUNT); - wined3d_mutex_lock(); + count = min(buffer_count, ARRAY_SIZE(outputs)); for (i = 0; i < count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]);
- wined3d_device_context_set_stream_output(context->wined3d_context, i, - buffer ? buffer->wined3d_buffer : NULL, offsets ? offsets[i] : 0); - } - for (; i < D3D11_SO_BUFFER_SLOT_COUNT; ++i) - { - wined3d_device_context_set_stream_output(context->wined3d_context, i, NULL, 0); + outputs[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + outputs[i].offset = offsets ? offsets[i] : 0; } + + wined3d_mutex_lock(); + wined3d_device_context_set_stream_outputs(context->wined3d_context, outputs); wined3d_mutex_unlock(); }
@@ -4909,25 +4908,23 @@ static void STDMETHODCALLTYPE d3d10_device_OMSetDepthStencilState(ID3D10Device1 static void STDMETHODCALLTYPE d3d10_device_SOSetTargets(ID3D10Device1 *iface, UINT target_count, ID3D10Buffer *const *targets, const UINT *offsets) { + struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS] = {0}; struct d3d_device *device = impl_from_ID3D10Device(iface); unsigned int count, i;
TRACE("iface %p, target_count %u, targets %p, offsets %p.\n", iface, target_count, targets, offsets);
- count = min(target_count, D3D10_SO_BUFFER_SLOT_COUNT); - wined3d_mutex_lock(); + count = min(target_count, ARRAY_SIZE(outputs)); for (i = 0; i < count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(targets[i]);
- wined3d_device_context_set_stream_output(device->immediate_context.wined3d_context, i, - buffer ? buffer->wined3d_buffer : NULL, offsets[i]); + outputs[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + outputs[i].offset = offsets ? offsets[i] : 0; }
- for (i = count; i < D3D10_SO_BUFFER_SLOT_COUNT; ++i) - { - wined3d_device_context_set_stream_output(device->immediate_context.wined3d_context, i, NULL, 0); - } + wined3d_mutex_lock(); + wined3d_device_context_set_stream_outputs(device->immediate_context.wined3d_context, outputs); wined3d_mutex_unlock(); }
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index f7e5009df46..49b4f529554 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -118,7 +118,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_VERTEX_DECLARATION, WINED3D_CS_OP_SET_STREAM_SOURCE, WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ, - WINED3D_CS_OP_SET_STREAM_OUTPUT, + WINED3D_CS_OP_SET_STREAM_OUTPUTS, WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_CONSTANT_BUFFERS, WINED3D_CS_OP_SET_TEXTURE, @@ -269,12 +269,10 @@ struct wined3d_cs_set_stream_source_freq UINT flags; };
-struct wined3d_cs_set_stream_output +struct wined3d_cs_set_stream_outputs { enum wined3d_cs_op opcode; - UINT stream_idx; - struct wined3d_buffer *buffer; - UINT offset; + struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]; };
struct wined3d_cs_set_index_buffer @@ -603,7 +601,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_VERTEX_DECLARATION); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE); 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_OUTPUTS); 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_TEXTURE); @@ -1471,35 +1469,34 @@ void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_i wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_stream_outputs(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_stream_output *op = data; - struct wined3d_stream_output *stream; - struct wined3d_buffer *prev; + const struct wined3d_cs_set_stream_outputs *op = data; + unsigned int i;
- stream = &cs->state.stream_output[op->stream_idx]; - prev = stream->buffer; - stream->buffer = op->buffer; - stream->offset = op->offset; + for (i = 0; i < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++i) + { + struct wined3d_buffer *prev = cs->state.stream_output[i].buffer; + struct wined3d_buffer *buffer = op->outputs[i].buffer;
- if (op->buffer) - InterlockedIncrement(&op->buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); + if (buffer) + InterlockedIncrement(&buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); + }
+ memcpy(cs->state.stream_output, op->outputs, sizeof(op->outputs)); device_invalidate_state(cs->c.device, STATE_STREAM_OUTPUT); }
-void wined3d_device_context_emit_set_stream_output(struct wined3d_device_context *context, unsigned int stream_idx, - struct wined3d_buffer *buffer, unsigned int offset) +void wined3d_device_context_emit_set_stream_outputs(struct wined3d_device_context *context, + const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) { - struct wined3d_cs_set_stream_output *op; + struct wined3d_cs_set_stream_outputs *op;
op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT; - op->stream_idx = stream_idx; - op->buffer = buffer; - op->offset = offset; + op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUTS; + memcpy(op->outputs, outputs, sizeof(op->outputs));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2928,7 +2925,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, /* 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_OUTPUTS */ wined3d_cs_exec_set_stream_outputs, /* 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_TEXTURE */ wined3d_cs_exec_set_texture, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index bb37f6aff51..7a78a271aa1 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1676,11 +1676,7 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte wined3d_device_context_emit_set_depth_stencil_view(context, state->fb.depth_stencil); wined3d_device_context_emit_set_vertex_declaration(context, state->vertex_declaration);
- for (i = 0; i < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++i) - { - wined3d_device_context_emit_set_stream_output(context, i, - state->stream_output[i].buffer, state->stream_output[i].offset); - } + wined3d_device_context_emit_set_stream_outputs(context, state->stream_output);
for (i = 0; i < WINED3D_MAX_STREAMS; ++i) { @@ -2334,30 +2330,26 @@ void CDECL wined3d_device_context_set_vertex_declaration(struct wined3d_device_c wined3d_vertex_declaration_decref(prev); }
-void CDECL wined3d_device_context_set_stream_output(struct wined3d_device_context *context, unsigned int idx, - struct wined3d_buffer *buffer, unsigned int offset) +void CDECL wined3d_device_context_set_stream_outputs(struct wined3d_device_context *context, + const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) { - struct wined3d_stream_output *stream; - struct wined3d_buffer *prev_buffer; + struct wined3d_state *state = context->state; + unsigned int i;
- TRACE("context %p, idx %u, buffer %p, offset %u.\n", context, idx, buffer, offset); + TRACE("context %p, outputs %p.\n", context, outputs);
- if (idx >= WINED3D_MAX_STREAM_OUTPUT_BUFFERS) + wined3d_device_context_emit_set_stream_outputs(context, outputs); + for (i = 0; i < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++i) { - WARN("Invalid stream output %u.\n", idx); - return; + struct wined3d_buffer *prev_buffer = state->stream_output[i].buffer; + struct wined3d_buffer *buffer = outputs[i].buffer; + + if (buffer) + wined3d_buffer_incref(buffer); + state->stream_output[i] = outputs[i]; + if (prev_buffer) + wined3d_buffer_decref(prev_buffer); } - - stream = &context->state->stream_output[idx]; - prev_buffer = stream->buffer; - - if (buffer) - wined3d_buffer_incref(buffer); - stream->buffer = buffer; - stream->offset = offset; - wined3d_device_context_emit_set_stream_output(context, idx, buffer, offset); - if (prev_buffer) - wined3d_buffer_decref(prev_buffer); }
void CDECL wined3d_device_context_draw(struct wined3d_device_context *context, unsigned int start_vertex, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 13c8b218b65..ccd941af7a7 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -136,7 +136,7 @@ @ cdecl wined3d_device_context_set_shader(ptr 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_stream_output(ptr long ptr long) +@ cdecl wined3d_device_context_set_stream_outputs(ptr ptr) @ cdecl wined3d_device_context_set_stream_source(ptr long ptr long long) @ cdecl wined3d_device_context_set_unordered_access_views(ptr long long long ptr ptr) @ cdecl wined3d_device_context_set_vertex_declaration(ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 36fdf56a73c..2708d5c7f32 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3660,12 +3660,6 @@ struct wined3d_rasterizer_state struct wine_rb_entry entry; };
-struct wined3d_stream_output -{ - struct wined3d_buffer *buffer; - UINT offset; -}; - #define LIGHTMAP_SIZE 43 #define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE)
@@ -4846,8 +4840,8 @@ void wined3d_device_context_emit_set_shader(struct wined3d_device_context *conte void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, 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, - struct wined3d_buffer *buffer, unsigned int offset) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_stream_outputs(struct wined3d_device_context *context, + const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context, unsigned int stage, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 21b9e01efd0..1369fffddf3 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2212,6 +2212,12 @@ struct wined3d_stateblock_state struct wined3d_light_state *light_state; };
+struct wined3d_stream_output +{ + struct wined3d_buffer *buffer; + unsigned int offset; +}; + struct wined3d_parent_ops { void (__stdcall *wined3d_object_destroyed)(void *parent); @@ -2523,8 +2529,8 @@ void __cdecl wined3d_device_context_set_shader_resource_views(struct wined3d_dev 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_stream_output(struct wined3d_device_context *context, unsigned int idx, - struct wined3d_buffer *buffer, unsigned int offset); +void __cdecl wined3d_device_context_set_stream_outputs(struct wined3d_device_context *context, + const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]); HRESULT __cdecl wined3d_device_context_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride); void __cdecl wined3d_device_context_set_unordered_access_views(struct wined3d_device_context *context,
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3d11/device.c | 20 ++++++++--- dlls/wined3d/cs.c | 54 ++++------------------------ dlls/wined3d/device.c | 64 +++++++++------------------------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 4 +-- include/wine/wined3d.h | 2 +- 6 files changed, 41 insertions(+), 105 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 46e2c8ba67f..20f0c27d020 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -851,9 +851,15 @@ static void STDMETHODCALLTYPE d3d11_device_context_IASetVertexBuffers(ID3D11Devi for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]); + struct wined3d_stream_state stream;
- wined3d_device_context_set_stream_source(context->wined3d_context, start_slot + i, - buffer ? buffer->wined3d_buffer : NULL, offsets[i], strides[i]); + stream.buffer = buffer ? buffer->wined3d_buffer : NULL; + stream.offset = offsets[i]; + stream.stride = strides[i]; + stream.frequency = 1; + stream.flags = 0; + + wined3d_device_context_set_stream_source(context->wined3d_context, start_slot + i, &stream); } wined3d_mutex_unlock(); } @@ -4705,9 +4711,15 @@ static void STDMETHODCALLTYPE d3d10_device_IASetVertexBuffers(ID3D10Device1 *ifa for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]); + struct wined3d_stream_state stream;
- wined3d_device_context_set_stream_source(device->immediate_context.wined3d_context, start_slot + i, - buffer ? buffer->wined3d_buffer : NULL, offsets[i], strides[i]); + stream.buffer = buffer ? buffer->wined3d_buffer : NULL; + stream.offset = offsets[i]; + stream.stride = strides[i]; + stream.frequency = 1; + stream.flags = 0; + + wined3d_device_context_set_stream_source(device->immediate_context.wined3d_context, start_slot + i, &stream); } wined3d_mutex_unlock(); } diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 49b4f529554..1cffd66d89a 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -117,7 +117,6 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW, WINED3D_CS_OP_SET_VERTEX_DECLARATION, WINED3D_CS_OP_SET_STREAM_SOURCE, - WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ, WINED3D_CS_OP_SET_STREAM_OUTPUTS, WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_CONSTANT_BUFFERS, @@ -256,17 +255,7 @@ struct wined3d_cs_set_stream_source { enum wined3d_cs_op opcode; UINT stream_idx; - struct wined3d_buffer *buffer; - UINT offset; - UINT stride; -}; - -struct wined3d_cs_set_stream_source_freq -{ - enum wined3d_cs_op opcode; - UINT stream_idx; - UINT frequency; - UINT flags; + struct wined3d_stream_state state; };
struct wined3d_cs_set_stream_outputs @@ -600,7 +589,6 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_VERTEX_DECLARATION); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE); - WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUTS); WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER); WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS); @@ -1417,12 +1405,10 @@ static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void
stream = &cs->state.streams[op->stream_idx]; prev = stream->buffer; - stream->buffer = op->buffer; - stream->offset = op->offset; - stream->stride = op->stride; + *stream = op->state;
- if (op->buffer) - InterlockedIncrement(&op->buffer->resource.bind_count); + if (op->state.buffer) + InterlockedIncrement(&op->state.buffer->resource.bind_count); if (prev) InterlockedDecrement(&prev->resource.bind_count);
@@ -1430,45 +1416,18 @@ static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void }
void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, - struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride) + const struct wined3d_stream_state *state) { struct wined3d_cs_set_stream_source *op;
op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; op->stream_idx = stream_idx; - op->buffer = buffer; - op->offset = offset; - op->stride = stride; + op->state = *state;
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_stream_source_freq(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_stream_source_freq *op = data; - struct wined3d_stream_state *stream; - - stream = &cs->state.streams[op->stream_idx]; - stream->frequency = op->frequency; - stream->flags = op->flags; - - device_invalidate_state(cs->c.device, STATE_STREAMSRC); -} - -void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, UINT frequency, UINT flags) -{ - struct wined3d_cs_set_stream_source_freq *op; - - op = wined3d_device_context_require_space(&cs->c, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ; - op->stream_idx = stream_idx; - op->frequency = frequency; - op->flags = flags; - - wined3d_device_context_submit(&cs->c, WINED3D_CS_QUEUE_DEFAULT); -} - static void wined3d_cs_exec_set_stream_outputs(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_stream_outputs *op = data; @@ -2924,7 +2883,6 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, - /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, /* WINED3D_CS_OP_SET_STREAM_OUTPUTS */ wined3d_cs_exec_set_stream_outputs, /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, /* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 7a78a271aa1..c8e81e923cc 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1274,23 +1274,6 @@ HRESULT CDECL wined3d_device_context_get_stream_source(const struct wined3d_devi return WINED3D_OK; }
-static void wined3d_device_set_stream_source_freq(struct wined3d_device *device, UINT stream_idx, UINT divider) -{ - struct wined3d_stream_state *stream; - UINT old_flags, old_freq; - - TRACE("device %p, stream_idx %u, divider %#x.\n", device, stream_idx, divider); - - stream = &device->cs->c.state->streams[stream_idx]; - old_flags = stream->flags; - old_freq = stream->frequency; - - stream->flags = divider & (WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA); - stream->frequency = divider & 0x7fffff; - if (stream->frequency != old_freq || stream->flags != old_flags) - wined3d_cs_emit_set_stream_source_freq(device->cs, stream_idx, stream->frequency, stream->flags); -} - static void wined3d_device_set_transform(struct wined3d_device *device, enum wined3d_transform_state state, const struct wined3d_matrix *matrix) { @@ -1679,10 +1662,7 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte wined3d_device_context_emit_set_stream_outputs(context, state->stream_output);
for (i = 0; i < WINED3D_MAX_STREAMS; ++i) - { - wined3d_device_context_emit_set_stream_source(context, i, state->streams[i].buffer, - state->streams[i].offset, state->streams[i].stride); - } + wined3d_device_context_emit_set_stream_source(context, i, &state->streams[i]);
wined3d_device_context_emit_set_index_buffer(context, state->index_buffer, state->index_format, state->index_offset); @@ -2240,42 +2220,38 @@ void CDECL wined3d_device_context_set_predication(struct wined3d_device_context }
HRESULT CDECL wined3d_device_context_set_stream_source(struct wined3d_device_context *context, - unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride) + unsigned int stream_idx, const struct wined3d_stream_state *src_stream) { - struct wined3d_stream_state *stream; + struct wined3d_buffer *buffer = src_stream->buffer; + struct wined3d_stream_state *dst_stream; struct wined3d_buffer *prev_buffer;
- TRACE("context %p, stream_idx %u, buffer %p, offset %u, stride %u.\n", - context, stream_idx, buffer, offset, stride); + TRACE("context %p, stream_idx %u, src_stream %p.\n", context, stream_idx, src_stream);
if (stream_idx >= WINED3D_MAX_STREAMS) { WARN("Stream index %u out of range.\n", stream_idx); return WINED3DERR_INVALIDCALL; } - else if (offset & 0x3) + else if (src_stream->offset & 0x3) { - WARN("Offset %u is not 4 byte aligned.\n", offset); + WARN("Offset %u is not 4 byte aligned.\n", src_stream->offset); return WINED3DERR_INVALIDCALL; }
- stream = &context->state->streams[stream_idx]; - prev_buffer = stream->buffer; + dst_stream = &context->state->streams[stream_idx]; + prev_buffer = dst_stream->buffer;
- if (prev_buffer == buffer - && stream->stride == stride - && stream->offset == offset) + if (!memcmp(src_stream, dst_stream, sizeof(*src_stream))) { - TRACE("Application is setting the old values over, nothing to do.\n"); - return WINED3D_OK; + TRACE("Application is setting the old values over, nothing to do.\n"); + return WINED3D_OK; }
- stream->buffer = buffer; - stream->stride = stride; - stream->offset = offset; + *dst_stream = *src_stream; if (buffer) wined3d_buffer_incref(buffer); - wined3d_device_context_emit_set_stream_source(context, stream_idx, buffer, offset, stride); + wined3d_device_context_emit_set_stream_source(context, stream_idx, src_stream); if (prev_buffer) wined3d_buffer_decref(prev_buffer);
@@ -3932,19 +3908,11 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, if (changed->scissorRect) wined3d_device_context_set_scissor_rects(context, 1, &state->scissor_rect);
- map = changed->streamSource; + map = changed->streamSource | changed->streamFreq; while (map) { i = wined3d_bit_scan(&map); - wined3d_device_context_set_stream_source(context, i, state->streams[i].buffer, - state->streams[i].offset, state->streams[i].stride); - } - map = changed->streamFreq; - while (map) - { - i = wined3d_bit_scan(&map); - wined3d_device_set_stream_source_freq(device, i, - state->streams[i].frequency | state->streams[i].flags); + wined3d_device_context_set_stream_source(context, i, &state->streams[i]); }
map = changed->textures; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index ccd941af7a7..1dac446a0e0 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -137,7 +137,7 @@ @ 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_stream_outputs(ptr ptr) -@ cdecl wined3d_device_context_set_stream_source(ptr long ptr long long) +@ cdecl wined3d_device_context_set_stream_source(ptr long ptr) @ cdecl wined3d_device_context_set_unordered_access_views(ptr long long long ptr ptr) @ cdecl wined3d_device_context_set_vertex_declaration(ptr ptr) @ cdecl wined3d_device_context_set_viewports(ptr long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 2708d5c7f32..98b387b73c0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4760,8 +4760,6 @@ void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs, enum wined3d_render_state state, DWORD value) DECLSPEC_HIDDEN; -void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx, - UINT frequency, UINT flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN; void wined3d_cs_init_object(struct wined3d_cs *cs, void (*callback)(void *object), void *object) DECLSPEC_HIDDEN; @@ -4843,7 +4841,7 @@ void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device void wined3d_device_context_emit_set_stream_outputs(struct wined3d_device_context *context, const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, - struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride) DECLSPEC_HIDDEN; + const struct wined3d_stream_state *state) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context, unsigned int stage, struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture_state(struct wined3d_device_context *context, unsigned int stage, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 1369fffddf3..94bbb4061c4 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2532,7 +2532,7 @@ void __cdecl wined3d_device_context_set_state(struct wined3d_device_context *con void __cdecl wined3d_device_context_set_stream_outputs(struct wined3d_device_context *context, const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]); HRESULT __cdecl wined3d_device_context_set_stream_source(struct wined3d_device_context *context, - unsigned int stream_idx, struct wined3d_buffer *buffer, unsigned int offset, unsigned int stride); + unsigned int stream_idx, const struct wined3d_stream_state *stream); void __cdecl wined3d_device_context_set_unordered_access_views(struct wined3d_device_context *context, enum wined3d_pipeline pipeline, unsigned int start_idx, unsigned int count, struct wined3d_unordered_access_view *const *uavs, const unsigned int *initial_counts);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- The validation of offset (and, in patch 4/6, bind flags) is awkward, but I don't see a nice way to do it without changing the current behaviour.
dlls/d3d11/device.c | 49 +++++++++++++++++---------- dlls/wined3d/cs.c | 53 ++++++++++++++++------------- dlls/wined3d/device.c | 62 ++++++++++++++++++---------------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 4 +-- include/wine/wined3d.h | 4 +-- 6 files changed, 98 insertions(+), 76 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 20f0c27d020..12675826394 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -841,26 +841,32 @@ static void STDMETHODCALLTYPE d3d11_device_context_IASetInputLayout(ID3D11Device static void STDMETHODCALLTYPE d3d11_device_context_IASetVertexBuffers(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer *const *buffers, const UINT *strides, const UINT *offsets) { + struct wined3d_stream_state streams[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); unsigned int i;
TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, strides %p, offsets %p.\n", iface, start_slot, buffer_count, buffers, strides, offsets);
- wined3d_mutex_lock(); + if (buffer_count > ARRAY_SIZE(streams)) + { + WARN("Buffer count %u exceeds limit.\n", buffer_count); + buffer_count = ARRAY_SIZE(streams); + } + for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]); - struct wined3d_stream_state stream;
- stream.buffer = buffer ? buffer->wined3d_buffer : NULL; - stream.offset = offsets[i]; - stream.stride = strides[i]; - stream.frequency = 1; - stream.flags = 0; - - wined3d_device_context_set_stream_source(context->wined3d_context, start_slot + i, &stream); + streams[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + streams[i].offset = offsets[i]; + streams[i].stride = strides[i]; + streams[i].frequency = 1; + streams[i].flags = 0; } + + wined3d_mutex_lock(); + wined3d_device_context_set_stream_sources(context->wined3d_context, start_slot, buffer_count, streams); wined3d_mutex_unlock(); }
@@ -4701,26 +4707,33 @@ static void STDMETHODCALLTYPE d3d10_device_IASetInputLayout(ID3D10Device1 *iface static void STDMETHODCALLTYPE d3d10_device_IASetVertexBuffers(ID3D10Device1 *iface, UINT start_slot, UINT buffer_count, ID3D10Buffer *const *buffers, const UINT *strides, const UINT *offsets) { + struct wined3d_stream_state streams[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; struct d3d_device *device = impl_from_ID3D10Device(iface); unsigned int i;
TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, strides %p, offsets %p\n", iface, start_slot, buffer_count, buffers, strides, offsets);
- wined3d_mutex_lock(); + if (buffer_count > ARRAY_SIZE(streams)) + { + WARN("Buffer count %u exceeds limit.\n", buffer_count); + buffer_count = ARRAY_SIZE(streams); + } + for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]); - struct wined3d_stream_state stream;
- stream.buffer = buffer ? buffer->wined3d_buffer : NULL; - stream.offset = offsets[i]; - stream.stride = strides[i]; - stream.frequency = 1; - stream.flags = 0; - - wined3d_device_context_set_stream_source(device->immediate_context.wined3d_context, start_slot + i, &stream); + streams[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + streams[i].offset = offsets[i]; + streams[i].stride = strides[i]; + streams[i].frequency = 1; + streams[i].flags = 0; } + + wined3d_mutex_lock(); + wined3d_device_context_set_stream_sources(device->immediate_context.wined3d_context, + start_slot, buffer_count, streams); wined3d_mutex_unlock(); }
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 1cffd66d89a..c2ba4010704 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -116,7 +116,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_RENDERTARGET_VIEW, WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW, WINED3D_CS_OP_SET_VERTEX_DECLARATION, - WINED3D_CS_OP_SET_STREAM_SOURCE, + WINED3D_CS_OP_SET_STREAM_SOURCES, WINED3D_CS_OP_SET_STREAM_OUTPUTS, WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_CONSTANT_BUFFERS, @@ -251,11 +251,12 @@ struct wined3d_cs_set_vertex_declaration struct wined3d_vertex_declaration *declaration; };
-struct wined3d_cs_set_stream_source +struct wined3d_cs_set_stream_sources { enum wined3d_cs_op opcode; - UINT stream_idx; - struct wined3d_stream_state state; + unsigned int start_idx; + unsigned int count; + struct wined3d_stream_state streams[1]; };
struct wined3d_cs_set_stream_outputs @@ -588,7 +589,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDERTARGET_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_VERTEX_DECLARATION); - WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCE); + WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCES); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_OUTPUTS); WINED3D_TO_STR(WINED3D_CS_OP_SET_INDEX_BUFFER); WINED3D_TO_STR(WINED3D_CS_OP_SET_CONSTANT_BUFFERS); @@ -1397,33 +1398,37 @@ void wined3d_device_context_emit_set_vertex_declaration(struct wined3d_device_co wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_stream_source(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_stream_sources(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_stream_source *op = data; - struct wined3d_stream_state *stream; - struct wined3d_buffer *prev; + const struct wined3d_cs_set_stream_sources *op = data; + unsigned int i;
- stream = &cs->state.streams[op->stream_idx]; - prev = stream->buffer; - *stream = op->state; + for (i = 0; i < op->count; ++i) + { + struct wined3d_buffer *prev = cs->state.streams[op->start_idx + i].buffer; + struct wined3d_buffer *buffer = op->streams[i].buffer;
- if (op->state.buffer) - InterlockedIncrement(&op->state.buffer->resource.bind_count); - if (prev) - InterlockedDecrement(&prev->resource.bind_count); + if (buffer) + InterlockedIncrement(&buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); + }
+ memcpy(&cs->state.streams[op->start_idx], op->streams, op->count * sizeof(*op->streams)); device_invalidate_state(cs->c.device, STATE_STREAMSRC); }
-void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, - const struct wined3d_stream_state *state) +void wined3d_device_context_emit_set_stream_sources(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, const struct wined3d_stream_state *streams) { - struct wined3d_cs_set_stream_source *op; + struct wined3d_cs_set_stream_sources *op;
- op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCE; - op->stream_idx = stream_idx; - op->state = *state; + op = wined3d_device_context_require_space(context, + offsetof(struct wined3d_cs_set_stream_sources, streams[count]), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_STREAM_SOURCES; + op->start_idx = start_idx; + op->count = count; + memcpy(op->streams, streams, count * sizeof(*streams));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2882,7 +2887,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, - /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, + /* WINED3D_CS_OP_SET_STREAM_SOURCES */ wined3d_cs_exec_set_stream_sources, /* WINED3D_CS_OP_SET_STREAM_OUTPUTS */ wined3d_cs_exec_set_stream_outputs, /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, /* WINED3D_CS_OP_SET_CONSTANT_BUFFERS */ wined3d_cs_exec_set_constant_buffers, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index c8e81e923cc..84bda7b44d9 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1661,8 +1661,7 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte
wined3d_device_context_emit_set_stream_outputs(context, state->stream_output);
- for (i = 0; i < WINED3D_MAX_STREAMS; ++i) - wined3d_device_context_emit_set_stream_source(context, i, &state->streams[i]); + wined3d_device_context_emit_set_stream_sources(context, 0, WINED3D_MAX_STREAMS, state->streams);
wined3d_device_context_emit_set_index_buffer(context, state->index_buffer, state->index_format, state->index_offset); @@ -2219,43 +2218,48 @@ void CDECL wined3d_device_context_set_predication(struct wined3d_device_context wined3d_query_decref(prev); }
-HRESULT CDECL wined3d_device_context_set_stream_source(struct wined3d_device_context *context, - unsigned int stream_idx, const struct wined3d_stream_state *src_stream) +HRESULT CDECL wined3d_device_context_set_stream_sources(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, const struct wined3d_stream_state *streams) { - struct wined3d_buffer *buffer = src_stream->buffer; - struct wined3d_stream_state *dst_stream; - struct wined3d_buffer *prev_buffer; + struct wined3d_state *state = context->state; + HRESULT hr = WINED3D_OK; + unsigned int i;
- TRACE("context %p, stream_idx %u, src_stream %p.\n", context, stream_idx, src_stream); + TRACE("context %p, start_idx %u, count %u, streams %p.\n", context, start_idx, count, streams);
- if (stream_idx >= WINED3D_MAX_STREAMS) + if (start_idx >= WINED3D_MAX_STREAMS) { - WARN("Stream index %u out of range.\n", stream_idx); - return WINED3DERR_INVALIDCALL; - } - else if (src_stream->offset & 0x3) - { - WARN("Offset %u is not 4 byte aligned.\n", src_stream->offset); + WARN("Start index %u is out of range.\n", start_idx); return WINED3DERR_INVALIDCALL; }
- dst_stream = &context->state->streams[stream_idx]; - prev_buffer = dst_stream->buffer; + count = min(count, WINED3D_MAX_STREAMS - start_idx);
- if (!memcmp(src_stream, dst_stream, sizeof(*src_stream))) - { - TRACE("Application is setting the old values over, nothing to do.\n"); + if (!memcmp(streams, &state->streams[start_idx], count * sizeof(*streams))) return WINED3D_OK; + + wined3d_device_context_emit_set_stream_sources(context, start_idx, count, streams); + for (i = 0; i < count; ++i) + { + struct wined3d_buffer *prev = state->streams[start_idx + i].buffer; + struct wined3d_buffer *buffer = streams[i].buffer; + + if (streams[i].offset & 0x3) + { + WARN("Offset %u is not 4 byte aligned.\n", streams[i].offset); + hr = WINED3DERR_INVALIDCALL; + continue; + } + + state->streams[start_idx + i] = streams[i]; + + if (buffer) + wined3d_buffer_incref(buffer); + if (prev) + wined3d_buffer_decref(prev); }
- *dst_stream = *src_stream; - if (buffer) - wined3d_buffer_incref(buffer); - wined3d_device_context_emit_set_stream_source(context, stream_idx, src_stream); - if (prev_buffer) - wined3d_buffer_decref(prev_buffer); - - return WINED3D_OK; + return hr; }
void CDECL wined3d_device_context_set_index_buffer(struct wined3d_device_context *context, @@ -3912,7 +3916,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, while (map) { i = wined3d_bit_scan(&map); - wined3d_device_context_set_stream_source(context, i, &state->streams[i]); + wined3d_device_context_set_stream_sources(context, i, 1, &state->streams[i]); }
map = changed->textures; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 1dac446a0e0..c6a61b98242 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -137,7 +137,7 @@ @ 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_stream_outputs(ptr ptr) -@ cdecl wined3d_device_context_set_stream_source(ptr long ptr) +@ cdecl wined3d_device_context_set_stream_sources(ptr long long ptr) @ cdecl wined3d_device_context_set_unordered_access_views(ptr long long long ptr ptr) @ cdecl wined3d_device_context_set_vertex_declaration(ptr ptr) @ cdecl wined3d_device_context_set_viewports(ptr long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 98b387b73c0..19a19dced27 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4840,8 +4840,8 @@ void wined3d_device_context_emit_set_shader_resource_views(struct wined3d_device struct wined3d_shader_resource_view *const *views) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_stream_outputs(struct wined3d_device_context *context, const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_stream_source(struct wined3d_device_context *context, unsigned int stream_idx, - const struct wined3d_stream_state *state) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_stream_sources(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, const struct wined3d_stream_state *streams) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context, unsigned int stage, struct wined3d_texture *texture) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_texture_state(struct wined3d_device_context *context, unsigned int stage, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 94bbb4061c4..6bfc755a5bb 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2531,8 +2531,8 @@ void __cdecl wined3d_device_context_set_shader_resource_views(struct wined3d_dev void __cdecl wined3d_device_context_set_state(struct wined3d_device_context *context, struct wined3d_state *state); void __cdecl wined3d_device_context_set_stream_outputs(struct wined3d_device_context *context, const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]); -HRESULT __cdecl wined3d_device_context_set_stream_source(struct wined3d_device_context *context, - unsigned int stream_idx, const struct wined3d_stream_state *stream); +HRESULT __cdecl wined3d_device_context_set_stream_sources(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, const struct wined3d_stream_state *streams); void __cdecl wined3d_device_context_set_unordered_access_views(struct wined3d_device_context *context, enum wined3d_pipeline pipeline, unsigned int start_idx, unsigned int count, struct wined3d_unordered_access_view *const *uavs, const unsigned int *initial_counts);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3d11/device.c | 53 ++++++++++-------- dlls/d3d8/device.c | 3 +- dlls/d3d9/device.c | 2 +- dlls/ddraw/ddraw.c | 2 +- dlls/ddraw/device.c | 13 +++-- dlls/ddraw/surface.c | 7 +-- dlls/wined3d/cs.c | 78 +++++++++++++++------------ dlls/wined3d/device.c | 99 +++++++++++++++++----------------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 4 +- include/wine/wined3d.h | 4 +- 11 files changed, 144 insertions(+), 123 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 12675826394..fc34421f082 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -1071,29 +1071,33 @@ static void STDMETHODCALLTYPE d3d11_device_context_GSSetSamplers(ID3D11DeviceCon }
static void STDMETHODCALLTYPE d3d11_device_context_OMSetRenderTargets(ID3D11DeviceContext1 *iface, - UINT render_target_view_count, ID3D11RenderTargetView *const *render_target_views, - ID3D11DepthStencilView *depth_stencil_view) + UINT rtv_count, ID3D11RenderTargetView *const *rtvs, ID3D11DepthStencilView *depth_stencil_view) { + struct wined3d_rendertarget_view *wined3d_rtvs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); struct d3d_depthstencil_view *dsv; unsigned int i;
- TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p.\n", - iface, render_target_view_count, render_target_views, depth_stencil_view); + TRACE("iface %p, rtv_count %u, rtvs %p, depth_stencil_view %p.\n", iface, rtv_count, rtvs, depth_stencil_view);
- wined3d_mutex_lock(); - for (i = 0; i < render_target_view_count; ++i) + if (rtv_count > ARRAY_SIZE(wined3d_rtvs)) { - struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D11RenderTargetView(render_target_views[i]); - wined3d_device_context_set_rendertarget_view(context->wined3d_context, i, - rtv ? rtv->wined3d_view : NULL, FALSE); + WARN("View count %u exceeds limit.\n", rtv_count); + rtv_count = ARRAY_SIZE(wined3d_rtvs); } - for (; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + + for (i = 0; i < rtv_count; ++i) { - wined3d_device_context_set_rendertarget_view(context->wined3d_context, i, NULL, FALSE); + struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D11RenderTargetView(rtvs[i]); + + wined3d_rtvs[i] = rtv ? rtv->wined3d_view : NULL; }
dsv = unsafe_impl_from_ID3D11DepthStencilView(depth_stencil_view); + + wined3d_mutex_lock(); + wined3d_device_context_set_rendertarget_views(context->wined3d_context, 0, + ARRAY_SIZE(wined3d_rtvs), wined3d_rtvs, FALSE); wined3d_device_context_set_depth_stencil_view(context->wined3d_context, dsv ? dsv->wined3d_view : NULL); wined3d_mutex_unlock(); } @@ -4873,30 +4877,33 @@ static void STDMETHODCALLTYPE d3d10_device_GSSetSamplers(ID3D10Device1 *iface, }
static void STDMETHODCALLTYPE d3d10_device_OMSetRenderTargets(ID3D10Device1 *iface, - UINT render_target_view_count, ID3D10RenderTargetView *const *render_target_views, - ID3D10DepthStencilView *depth_stencil_view) + UINT rtv_count, ID3D10RenderTargetView *const *rtvs, ID3D10DepthStencilView *depth_stencil_view) { + struct wined3d_rendertarget_view *wined3d_rtvs[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; struct d3d_device *device = impl_from_ID3D10Device(iface); struct d3d_depthstencil_view *dsv; unsigned int i;
- TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p.\n", - iface, render_target_view_count, render_target_views, depth_stencil_view); + TRACE("iface %p, rtv_count %u, rtvs %p, depth_stencil_view %p.\n", iface, rtv_count, rtvs, depth_stencil_view);
- wined3d_mutex_lock(); - for (i = 0; i < render_target_view_count; ++i) + if (rtv_count > ARRAY_SIZE(wined3d_rtvs)) { - struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D10RenderTargetView(render_target_views[i]); - - wined3d_device_context_set_rendertarget_view(device->immediate_context.wined3d_context, i, - rtv ? rtv->wined3d_view : NULL, FALSE); + WARN("View count %u exceeds limit.\n", rtv_count); + rtv_count = ARRAY_SIZE(wined3d_rtvs); } - for (; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + + for (i = 0; i < rtv_count; ++i) { - wined3d_device_context_set_rendertarget_view(device->immediate_context.wined3d_context, i, NULL, FALSE); + struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D10RenderTargetView(rtvs[i]); + + wined3d_rtvs[i] = rtv ? rtv->wined3d_view : NULL; }
dsv = unsafe_impl_from_ID3D10DepthStencilView(depth_stencil_view); + + wined3d_mutex_lock(); + wined3d_device_context_set_rendertarget_views(device->immediate_context.wined3d_context, 0, + ARRAY_SIZE(wined3d_rtvs), wined3d_rtvs, FALSE); wined3d_device_context_set_depth_stencil_view(device->immediate_context.wined3d_context, dsv ? dsv->wined3d_view : NULL); wined3d_mutex_unlock(); diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index c0fa38e090a..6c1646a1893 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -1544,7 +1544,8 @@ static HRESULT WINAPI d3d8_device_SetRenderTarget(IDirect3DDevice8 *iface, rtv = render_target ? d3d8_surface_acquire_rendertarget_view(rt_impl) : NULL; if (render_target) { - if (SUCCEEDED(hr = wined3d_device_context_set_rendertarget_view(device->immediate_context, 0, rtv, TRUE))) + if (SUCCEEDED(hr = wined3d_device_context_set_rendertarget_views(device->immediate_context, + 0, 1, &rtv, TRUE))) device_reset_viewport_state(device); else wined3d_device_context_set_depth_stencil_view(device->immediate_context, original_dsv); diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index c8b906a981f..1a1bc5ddb6c 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -2028,7 +2028,7 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO
wined3d_mutex_lock(); rtv = surface_impl ? d3d9_surface_acquire_rendertarget_view(surface_impl) : NULL; - hr = wined3d_device_context_set_rendertarget_view(device->immediate_context, idx, rtv, TRUE); + hr = wined3d_device_context_set_rendertarget_views(device->immediate_context, idx, 1, &rtv, TRUE); d3d9_surface_release_rendertarget_view(surface_impl, rtv); if (SUCCEEDED(hr)) { diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 972c18fbfe9..5b70bb4f86d 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -958,7 +958,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (rtv) { - wined3d_device_context_set_rendertarget_view(ddraw->immediate_context, 0, rtv, FALSE); + wined3d_device_context_set_rendertarget_views(ddraw->immediate_context, 0, 1, &rtv, FALSE); wined3d_rendertarget_view_decref(rtv); }
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index b66ae7698c8..8afbab0e58d 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -270,6 +270,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) * wined3d device when the render target is released. */ if (!ref) { + static struct wined3d_rendertarget_view *const null_rtv; DWORD i; struct list *vp_entry, *vp_entry2;
@@ -283,7 +284,7 @@ static ULONG WINAPI d3d_device_inner_Release(IUnknown *iface) if (This->vertex_buffer) wined3d_buffer_decref(This->vertex_buffer);
- wined3d_device_context_set_rendertarget_view(This->immediate_context, 0, NULL, FALSE); + wined3d_device_context_set_rendertarget_views(This->immediate_context, 0, 1, &null_rtv, FALSE);
wined3d_stateblock_decref(This->state); if (This->recording) @@ -1848,6 +1849,7 @@ static BOOL validate_surface_palette(struct ddraw_surface *surface) static HRESULT d3d_device_set_render_target(struct d3d_device *device, struct ddraw_surface *target, IUnknown *rt_iface) { + struct wined3d_rendertarget_view *rtv; HRESULT hr;
if (device->rt_iface == rt_iface) @@ -1861,8 +1863,8 @@ static HRESULT d3d_device_set_render_target(struct d3d_device *device, return DDERR_INVALIDPARAMS; }
- if (FAILED(hr = wined3d_device_context_set_rendertarget_view(device->immediate_context, - 0, ddraw_surface_get_rendertarget_view(target), FALSE))) + rtv = ddraw_surface_get_rendertarget_view(target); + if (FAILED(hr = wined3d_device_context_set_rendertarget_views(device->immediate_context, 0, 1, &rtv, FALSE))) return hr;
IUnknown_AddRef(rt_iface); @@ -6994,6 +6996,7 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; + struct wined3d_rendertarget_view *rtv; HRESULT hr;
if (ddraw->cooperative_level & DDSCL_FPUPRESERVE) @@ -7043,8 +7046,8 @@ static HRESULT d3d_device_init(struct d3d_device *device, struct ddraw *ddraw, c wined3d_stateblock_incref(ddraw->state);
/* Render to the back buffer */ - if (FAILED(hr = wined3d_device_context_set_rendertarget_view(device->immediate_context, - 0, ddraw_surface_get_rendertarget_view(target), TRUE))) + rtv = ddraw_surface_get_rendertarget_view(target); + if (FAILED(hr = wined3d_device_context_set_rendertarget_views(device->immediate_context, 0, 1, &rtv, TRUE))) { ERR("Failed to set render target, hr %#x.\n", hr); wined3d_stateblock_decref(device->state); diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 7834d9c943b..25aa2be41bb 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -1369,7 +1369,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface *
src_rtv = ddraw_surface_get_rendertarget_view(src_impl); if (rtv == dst_impl->wined3d_rtv) - wined3d_device_context_set_rendertarget_view(dst_impl->ddraw->immediate_context, 0, src_rtv, FALSE); + wined3d_device_context_set_rendertarget_views(dst_impl->ddraw->immediate_context, 0, 1, &src_rtv, FALSE); wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); @@ -1406,7 +1406,8 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * src_impl = impl_from_IDirectDrawSurface(current); src_rtv = ddraw_surface_get_rendertarget_view(src_impl); if (rtv == dst_impl->wined3d_rtv) - wined3d_device_context_set_rendertarget_view(dst_impl->ddraw->immediate_context, 0, src_rtv, FALSE); + wined3d_device_context_set_rendertarget_views(dst_impl->ddraw->immediate_context, + 0, 1, &src_rtv, FALSE); wined3d_rendertarget_view_set_parent(src_rtv, dst_impl); dst_impl->wined3d_rtv = src_rtv; wined3d_texture_set_sub_resource_parent(src_impl->wined3d_texture, 0, dst_impl); @@ -1429,7 +1430,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface * /* We don't have to worry about potential texture bindings, since * flippable surfaces can never be textures. */ if (rtv == src_impl->wined3d_rtv) - wined3d_device_context_set_rendertarget_view(dst_impl->ddraw->immediate_context, 0, tmp_rtv, FALSE); + wined3d_device_context_set_rendertarget_views(dst_impl->ddraw->immediate_context, 0, 1, &tmp_rtv, FALSE); wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl); src_impl->wined3d_rtv = tmp_rtv; wined3d_texture_set_sub_resource_parent(texture, 0, src_impl); diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index c2ba4010704..434a9c20fb1 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -113,7 +113,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_PREDICATION, WINED3D_CS_OP_SET_VIEWPORTS, WINED3D_CS_OP_SET_SCISSOR_RECTS, - WINED3D_CS_OP_SET_RENDERTARGET_VIEW, + WINED3D_CS_OP_SET_RENDERTARGET_VIEWS, WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW, WINED3D_CS_OP_SET_VERTEX_DECLARATION, WINED3D_CS_OP_SET_STREAM_SOURCES, @@ -232,11 +232,12 @@ struct wined3d_cs_set_scissor_rects RECT rects[1]; };
-struct wined3d_cs_set_rendertarget_view +struct wined3d_cs_set_rendertarget_views { enum wined3d_cs_op opcode; - unsigned int view_idx; - struct wined3d_rendertarget_view *view; + unsigned int start_idx; + unsigned int count; + struct wined3d_rendertarget_view *views[1]; };
struct wined3d_cs_set_depth_stencil_view @@ -586,7 +587,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_PREDICATION); WINED3D_TO_STR(WINED3D_CS_OP_SET_VIEWPORTS); WINED3D_TO_STR(WINED3D_CS_OP_SET_SCISSOR_RECTS); - WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDERTARGET_VIEW); + WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDERTARGET_VIEWS); WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_SET_VERTEX_DECLARATION); WINED3D_TO_STR(WINED3D_CS_OP_SET_STREAM_SOURCES); @@ -1289,43 +1290,50 @@ void wined3d_device_context_emit_set_scissor_rects(struct wined3d_device_context wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_rendertarget_view(struct wined3d_cs *cs, const void *data) +static void wined3d_cs_exec_set_rendertarget_views(struct wined3d_cs *cs, const void *data) { - const struct wined3d_cs_set_rendertarget_view *op = data; - bool prev_alpha_swizzle, curr_alpha_swizzle; - struct wined3d_rendertarget_view *prev; - bool prev_srgb_write, curr_srgb_write; - struct wined3d_device *device; + const struct wined3d_cs_set_rendertarget_views *op = data; + struct wined3d_device *device = cs->c.device; + unsigned int i;
- device = cs->c.device; - prev = cs->state.fb.render_targets[op->view_idx]; - cs->state.fb.render_targets[op->view_idx] = op->view; - device_invalidate_state(device, STATE_FRAMEBUFFER); - - prev_alpha_swizzle = prev && prev->format->id == WINED3DFMT_A8_UNORM; - curr_alpha_swizzle = op->view && op->view->format->id == WINED3DFMT_A8_UNORM; - if (prev_alpha_swizzle != curr_alpha_swizzle) - device_invalidate_state(device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); - - if (!(device->adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) - || cs->state.render_states[WINED3D_RS_SRGBWRITEENABLE]) + for (i = 0; i < op->count; ++i) { - prev_srgb_write = prev && prev->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; - curr_srgb_write = op->view && op->view->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; - if (prev_srgb_write != curr_srgb_write) - device_invalidate_state(device, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + struct wined3d_rendertarget_view *prev = cs->state.fb.render_targets[op->start_idx + i]; + struct wined3d_rendertarget_view *view = op->views[i]; + bool prev_alpha_swizzle, curr_alpha_swizzle; + bool prev_srgb_write, curr_srgb_write; + + cs->state.fb.render_targets[op->start_idx + i] = view; + + prev_alpha_swizzle = prev && prev->format->id == WINED3DFMT_A8_UNORM; + curr_alpha_swizzle = view && view->format->id == WINED3DFMT_A8_UNORM; + if (prev_alpha_swizzle != curr_alpha_swizzle) + device_invalidate_state(device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL)); + + if (!(device->adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL) + || cs->state.render_states[WINED3D_RS_SRGBWRITEENABLE]) + { + prev_srgb_write = prev && prev->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; + curr_srgb_write = view && view->format_flags & WINED3DFMT_FLAG_SRGB_WRITE; + if (prev_srgb_write != curr_srgb_write) + device_invalidate_state(device, STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE)); + } } + + device_invalidate_state(device, STATE_FRAMEBUFFER); }
-void wined3d_device_context_emit_set_rendertarget_view(struct wined3d_device_context *context, unsigned int view_idx, - struct wined3d_rendertarget_view *view) +void wined3d_device_context_emit_set_rendertarget_views(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, struct wined3d_rendertarget_view *const *views) { - struct wined3d_cs_set_rendertarget_view *op; + struct wined3d_cs_set_rendertarget_views *op;
- op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEW; - op->view_idx = view_idx; - op->view = view; + op = wined3d_device_context_require_space(context, + offsetof(struct wined3d_cs_set_rendertarget_views, views[count]), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_SET_RENDERTARGET_VIEWS; + op->start_idx = start_idx; + op->count = count; + memcpy(op->views, views, count * sizeof(*views));
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); } @@ -2884,7 +2892,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_PREDICATION */ wined3d_cs_exec_set_predication, /* WINED3D_CS_OP_SET_VIEWPORTS */ wined3d_cs_exec_set_viewports, /* WINED3D_CS_OP_SET_SCISSOR_RECTS */ wined3d_cs_exec_set_scissor_rects, - /* WINED3D_CS_OP_SET_RENDERTARGET_VIEW */ wined3d_cs_exec_set_rendertarget_view, + /* WINED3D_CS_OP_SET_RENDERTARGET_VIEWS */ wined3d_cs_exec_set_rendertarget_views, /* WINED3D_CS_OP_SET_DEPTH_STENCIL_VIEW */ wined3d_cs_exec_set_depth_stencil_view, /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, /* WINED3D_CS_OP_SET_STREAM_SOURCES */ wined3d_cs_exec_set_stream_sources, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 84bda7b44d9..e4a16e56a56 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -932,16 +932,14 @@ void CDECL wined3d_device_release_focus_window(struct wined3d_device *device)
static void device_init_swapchain_state(struct wined3d_device *device, struct wined3d_swapchain *swapchain) { + struct wined3d_rendertarget_view *views[WINED3D_MAX_RENDER_TARGETS] = {0}; BOOL ds_enable = swapchain->state.desc.enable_auto_depth_stencil; struct wined3d_device_context *context = &device->cs->c; - unsigned int i;
- for (i = 0; i < device->adapter->d3d_info.limits.max_rt_count; ++i) - { - wined3d_device_context_set_rendertarget_view(context, i, NULL, FALSE); - } if (device->back_buffer_view) - wined3d_device_context_set_rendertarget_view(context, 0, device->back_buffer_view, TRUE); + views[0] = device->back_buffer_view; + wined3d_device_context_set_rendertarget_views(context, 0, + device->adapter->d3d_info.limits.max_rt_count, views, !!device->back_buffer_view);
wined3d_device_context_set_depth_stencil_view(context, ds_enable ? device->auto_depth_stencil_view : NULL); } @@ -1651,10 +1649,8 @@ void CDECL wined3d_device_context_set_state(struct wined3d_device_context *conte context->state = state; wined3d_device_context_emit_set_feature_level(context, state->feature_level);
- for (i = 0; i < WINED3D_MAX_RENDER_TARGETS; ++i) - { - wined3d_device_context_emit_set_rendertarget_view(context, i, state->fb.render_targets[i]); - } + wined3d_device_context_emit_set_rendertarget_views(context, 0, + ARRAY_SIZE(state->fb.render_targets), state->fb.render_targets);
wined3d_device_context_emit_set_depth_stencil_view(context, state->fb.depth_stencil); wined3d_device_context_emit_set_vertex_declaration(context, state->vertex_declaration); @@ -2099,70 +2095,77 @@ static void wined3d_device_context_unbind_srv_for_rtv(struct wined3d_device_cont } }
-HRESULT CDECL wined3d_device_context_set_rendertarget_view(struct wined3d_device_context *context, - unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport) +HRESULT CDECL wined3d_device_context_set_rendertarget_views(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, struct wined3d_rendertarget_view *const *views, BOOL set_viewport) { struct wined3d_state *state = context->state; - struct wined3d_rendertarget_view *prev; - unsigned int max_rt_count; + unsigned int i, max_rt_count; + HRESULT hr = WINED3D_OK;
- TRACE("context %p, view_idx %u, view %p, set_viewport %#x.\n", - context, view_idx, view, set_viewport); + TRACE("context %p, start_idx %u, count %u, views %p, set_viewport %#x.\n", + context, start_idx, count, views, set_viewport);
max_rt_count = context->device->adapter->d3d_info.limits.max_rt_count; - if (view_idx >= max_rt_count) + if (start_idx >= max_rt_count) { WARN("Only %u render targets are supported.\n", max_rt_count); return WINED3DERR_INVALIDCALL; } - - if (view && !(view->resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) - { - WARN("View resource %p doesn't have render target bind flags.\n", view->resource); - return WINED3DERR_INVALIDCALL; - } + count = min(count, max_rt_count - start_idx);
/* Set the viewport and scissor rectangles, if requested. Tests show that * stateblock recording is ignored, the change goes directly into the * primary stateblock. */ - if (!view_idx && set_viewport) + if (!start_idx && set_viewport) { state->viewports[0].x = 0; state->viewports[0].y = 0; - state->viewports[0].width = view->width; - state->viewports[0].height = view->height; + state->viewports[0].width = views[0]->width; + state->viewports[0].height = views[0]->height; state->viewports[0].min_z = 0.0f; state->viewports[0].max_z = 1.0f; state->viewport_count = 1; wined3d_device_context_emit_set_viewports(context, 1, state->viewports);
- SetRect(&state->scissor_rects[0], 0, 0, view->width, view->height); + SetRect(&state->scissor_rects[0], 0, 0, views[0]->width, views[0]->height); state->scissor_rect_count = 1; wined3d_device_context_emit_set_scissor_rects(context, 1, state->scissor_rects); }
- prev = state->fb.render_targets[view_idx]; - if (view == prev) + if (!memcmp(views, &state->fb.render_targets[start_idx], count * sizeof(*views))) return WINED3D_OK;
- if (view) + wined3d_device_context_emit_set_rendertarget_views(context, start_idx, count, views); + for (i = 0; i < count; ++i) { - wined3d_rendertarget_view_incref(view); - wined3d_rtv_bind_count_inc(view); - } - state->fb.render_targets[view_idx] = view; - wined3d_device_context_emit_set_rendertarget_view(context, view_idx, view); - /* Release after the assignment, to prevent device_resource_released() - * from seeing the surface as still in use. */ - if (prev) - { - wined3d_rtv_bind_count_dec(prev); - wined3d_rendertarget_view_decref(prev); + struct wined3d_rendertarget_view *prev = state->fb.render_targets[start_idx + i]; + struct wined3d_rendertarget_view *view = views[i]; + + if (view && !(view->resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) + { + WARN("View resource %p doesn't have render target bind flags.\n", views[i]->resource); + hr = WINED3DERR_INVALIDCALL; + continue; + } + + if (view) + { + wined3d_rendertarget_view_incref(view); + wined3d_rtv_bind_count_inc(view); + } + state->fb.render_targets[start_idx + i] = view; + /* Release after the assignment, to prevent device_resource_released() + * from seeing the resource as still in use. */ + if (prev) + { + wined3d_rtv_bind_count_dec(prev); + wined3d_rendertarget_view_decref(prev); + } + + wined3d_device_context_unbind_srv_for_rtv(context, view, FALSE); }
- wined3d_device_context_unbind_srv_for_rtv(context, view, FALSE); - - return WINED3D_OK; + return hr; }
HRESULT CDECL wined3d_device_context_set_depth_stencil_view(struct wined3d_device_context *context, @@ -5187,6 +5190,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode, wined3d_device_reset_cb callback, BOOL reset_state) { + static struct wined3d_rendertarget_view *const views[WINED3D_MAX_RENDER_TARGETS]; const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info; struct wined3d_device_context *context = &device->cs->c; struct wined3d_swapchain_state *swapchain_state; @@ -5228,10 +5232,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, state_unbind_resources(state); }
- for (i = 0; i < d3d_info->limits.max_rt_count; ++i) - { - wined3d_device_context_set_rendertarget_view(context, i, NULL, FALSE); - } + wined3d_device_context_set_rendertarget_views(context, 0, d3d_info->limits.max_rt_count, views, FALSE); wined3d_device_context_set_depth_stencil_view(context, NULL);
if (reset_state) @@ -5454,7 +5455,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, else { if ((view = device->back_buffer_view)) - wined3d_device_context_set_rendertarget_view(context, 0, view, FALSE); + wined3d_device_context_set_rendertarget_views(context, 0, 1, &view, FALSE); if ((view = device->auto_depth_stencil_view)) wined3d_device_context_set_depth_stencil_view(context, view); } diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index c6a61b98242..2d36d0882ff 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -130,7 +130,7 @@ @ cdecl wined3d_device_context_set_predication(ptr ptr long) @ cdecl wined3d_device_context_set_primitive_type(ptr long long) @ cdecl wined3d_device_context_set_rasterizer_state(ptr ptr) -@ cdecl wined3d_device_context_set_rendertarget_view(ptr long ptr long) +@ cdecl wined3d_device_context_set_rendertarget_views(ptr long long ptr long) @ cdecl wined3d_device_context_set_samplers(ptr long long long ptr) @ cdecl wined3d_device_context_set_scissor_rects(ptr long ptr) @ cdecl wined3d_device_context_set_shader(ptr long ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 19a19dced27..fb25e856ead 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4825,8 +4825,8 @@ void wined3d_device_context_emit_set_rasterizer_state(struct wined3d_device_cont struct wined3d_rasterizer_state *rasterizer_state) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_render_state(struct wined3d_device_context *context, enum wined3d_render_state state, unsigned int value) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_rendertarget_view(struct wined3d_device_context *context, unsigned int view_idx, - struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; +void wined3d_device_context_emit_set_rendertarget_views(struct wined3d_device_context *context, unsigned int start_idx, + unsigned int count, struct wined3d_rendertarget_view *const *views) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_samplers(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, struct wined3d_sampler *const *samplers) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_sampler_state(struct wined3d_device_context *context, unsigned int sampler_idx, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 6bfc755a5bb..baa71758d17 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2517,8 +2517,8 @@ void __cdecl wined3d_device_context_set_primitive_type(struct wined3d_device_con enum wined3d_primitive_type primitive_topology, unsigned int patch_vertex_count); void __cdecl wined3d_device_context_set_rasterizer_state(struct wined3d_device_context *context, struct wined3d_rasterizer_state *rasterizer_state); -HRESULT __cdecl wined3d_device_context_set_rendertarget_view(struct wined3d_device_context *context, - unsigned int view_idx, struct wined3d_rendertarget_view *view, BOOL set_viewport); +HRESULT __cdecl wined3d_device_context_set_rendertarget_views(struct wined3d_device_context *context, + unsigned int start_idx, unsigned int count, struct wined3d_rendertarget_view *const *views, BOOL set_viewport); void __cdecl wined3d_device_context_set_samplers(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, struct wined3d_sampler *const *samplers); void __cdecl wined3d_device_context_set_scissor_rects(struct wined3d_device_context *context, unsigned int rect_count,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=93916
Your paranoid android.
=== debiant2 (32 bit report) ===
d3d8: Unhandled exception: page fault on read access to 0x00000009 in 32-bit code (0x7e8dfbd8).
d3d9: Unhandled exception: page fault on read access to 0x00000029 in 32-bit code (0x7e8dfbd8). Unhandled exception: page fault on read access to 0x00000030 in 32-bit code (0x7e8dfbd8).
=== debiant2 (32 bit Chinese:China report) ===
d3d8: Unhandled exception: page fault on read access to 0x00000009 in 32-bit code (0x7e855bd8).
d3d9: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e855bd8). Unhandled exception: page fault on read access to 0x00000061 in 32-bit code (0x7e855bd8).
=== debiant2 (32 bit WoW report) ===
d3d8: Unhandled exception: page fault on read access to 0x00000012 in 32-bit code (0x7e766bd8).
d3d9: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e8dfbd8). Unhandled exception: page fault on read access to 0x3f800000 in 32-bit code (0x7e8dfbd8).
ddraw: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7e8dfbd8).
=== debiant2 (64 bit WoW report) ===
d3d11: d3d11.c:5922: Test failed: Got unexpected hr 0x8876086a for query type 13.
d3d8: Unhandled exception: page fault on read access to 0x00000000 in 64-bit code (0x00007eff27038f86).
d3d9: Unhandled exception: page fault on read access to 0x00000000 in 64-bit code (0x00007f79d7849f86).
ddraw: Unhandled exception: page fault on read access to 0x00000000 in 64-bit code (0x00007f89af4e4f86).
On Fri, 9 Jul 2021 at 00:19, Zebediah Figura zfigura@codeweavers.com wrote:
- if (prev)
- {
wined3d_rtv_bind_count_dec(prev);
wined3d_rendertarget_view_decref(prev);
struct wined3d_rendertarget_view *prev = state->fb.render_targets[start_idx + i];
struct wined3d_rendertarget_view *view = views[i];
if (view && !(view->resource->bind_flags & WINED3D_BIND_RENDER_TARGET))
{
WARN("View resource %p doesn't have render target bind flags.\n", views[i]->resource);
hr = WINED3DERR_INVALIDCALL;
continue;
}
That mostly works, but you'd also need to skip the view in wined3d_cs_exec_set_rendertarget_views(). Specifically, if you don't, the command stream may store a pointer to the view, without us having a reference to it, and a subsequent wined3d_cs_exec_set_rendertarget_views() call may dereference an already freed "prev" pointer.
Based on a patch by Kimmo Myllyvirta.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- I'm working on the Vulkan part; I'll submit it separately.
dlls/d3d11/device.c | 147 ++++++++++++++++++++++++--------- dlls/wined3d/context_gl.c | 4 +- dlls/wined3d/context_vk.c | 4 +- dlls/wined3d/cs.c | 18 ++-- dlls/wined3d/device.c | 16 ++-- dlls/wined3d/state.c | 9 +- dlls/wined3d/stateblock.c | 12 ++- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 4 +- include/wine/wined3d.h | 14 +++- 10 files changed, 158 insertions(+), 72 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index fc34421f082..c2ad85217f8 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -534,8 +534,9 @@ static ULONG STDMETHODCALLTYPE d3d11_device_context_Release(ID3D11DeviceContext1 return refcount; }
-static void d3d11_device_context_get_constant_buffers(ID3D11DeviceContext1 *iface, - enum wined3d_shader_type type, UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers) +static void d3d11_device_context_get_constant_buffers(ID3D11DeviceContext1 *iface, enum wined3d_shader_type type, + unsigned int start_slot, unsigned int buffer_count, ID3D11Buffer **buffers, + unsigned int *offsets, unsigned int *counts) { struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); unsigned int i; @@ -543,17 +544,23 @@ static void d3d11_device_context_get_constant_buffers(ID3D11DeviceContext1 *ifac wined3d_mutex_lock(); for (i = 0; i < buffer_count; ++i) { - struct wined3d_buffer *wined3d_buffer; + struct wined3d_constant_buffer_state state; struct d3d_buffer *buffer_impl;
- if (!(wined3d_buffer = wined3d_device_context_get_constant_buffer(context->wined3d_context, - type, start_slot + i))) + wined3d_device_context_get_constant_buffer(context->wined3d_context, type, start_slot + i, &state); + + if (offsets) + offsets[i] = state.offset / sizeof(struct wined3d_vec4); + if (counts) + counts[i] = state.size / sizeof(struct wined3d_vec4); + + if (!state.buffer) { buffers[i] = NULL; continue; }
- buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + buffer_impl = wined3d_buffer_get_parent(state.buffer); buffers[i] = &buffer_impl->ID3D11Buffer_iface; ID3D11Buffer_AddRef(buffers[i]); } @@ -561,9 +568,11 @@ static void d3d11_device_context_get_constant_buffers(ID3D11DeviceContext1 *ifac }
static void d3d11_device_context_set_constant_buffers(ID3D11DeviceContext1 *iface, enum wined3d_shader_type type, - unsigned int start_slot, unsigned int buffer_count, ID3D11Buffer *const *buffers) + unsigned int start_slot, unsigned int buffer_count, ID3D11Buffer *const *buffers, + const unsigned int *offsets, const unsigned int *counts) { - struct wined3d_buffer *wined3d_buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + static const unsigned int alignment = D3D11_COMMONSHADER_CONSTANT_BUFFER_PARTIAL_UPDATE_EXTENTS_BYTE_ALIGNMENT; + struct wined3d_constant_buffer_state wined3d_buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface); unsigned int i;
@@ -573,11 +582,31 @@ static void d3d11_device_context_set_constant_buffers(ID3D11DeviceContext1 *ifac return; }
+ if (!offsets != !counts) + { + WARN("Got offsets pointer %p but counts pointer %p; ignoring call.\n", offsets, counts); + return; + } + for (i = 0; i < buffer_count; ++i) { struct d3d_buffer *buffer = unsafe_impl_from_ID3D11Buffer(buffers[i]);
- wined3d_buffers[i] = buffer ? buffer->wined3d_buffer : NULL; + if (offsets && (offsets[i] & (alignment - 1))) + { + WARN("Offset %u is not aligned.\n", offsets[i]); + return; + } + + if (counts && (counts[i] & (alignment - 1))) + { + WARN("Count %u is not aligned.\n", counts[i]); + return; + } + + wined3d_buffers[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + wined3d_buffers[i].offset = (offsets ? offsets[i] : 0) * sizeof(struct wined3d_vec4); + wined3d_buffers[i].size = (counts ? counts[i] : WINED3D_MAX_CONSTANT_BUFFER_SIZE) * sizeof(struct wined3d_vec4); }
wined3d_mutex_lock(); @@ -684,7 +713,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_VSSetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_PSSetShaderResources(ID3D11DeviceContext1 *iface, @@ -822,7 +851,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_PSSetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_IASetInputLayout(ID3D11DeviceContext1 *iface, @@ -926,7 +955,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_GSSetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_GSSetShader(ID3D11DeviceContext1 *iface, @@ -1604,7 +1633,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_HSSetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_HULL, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_DSSetShaderResources(ID3D11DeviceContext1 *iface, @@ -1650,7 +1679,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_DSSetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_DOMAIN, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_CSSetShaderResources(ID3D11DeviceContext1 *iface, @@ -1725,7 +1754,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_CSSetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_COMPUTE, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_VSGetConstantBuffers(ID3D11DeviceContext1 *iface, @@ -1735,7 +1764,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_VSGetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_PSGetShaderResources(ID3D11DeviceContext1 *iface, @@ -1861,7 +1890,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_PSGetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_IAGetInputLayout(ID3D11DeviceContext1 *iface, @@ -1956,7 +1985,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_GSGetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_GSGetShader(ID3D11DeviceContext1 *iface, @@ -2476,7 +2505,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_HSGetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_HULL, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_DSGetShaderResources(ID3D11DeviceContext1 *iface, @@ -2570,7 +2599,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_DSGetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_DOMAIN, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_CSGetShaderResources(ID3D11DeviceContext1 *iface, @@ -2690,7 +2719,7 @@ static void STDMETHODCALLTYPE d3d11_device_context_CSGetConstantBuffers(ID3D11De iface, start_slot, buffer_count, buffers);
d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_COMPUTE, start_slot, - buffer_count, buffers); + buffer_count, buffers, NULL, NULL); }
static void STDMETHODCALLTYPE d3d11_device_context_ClearState(ID3D11DeviceContext1 *iface) @@ -2839,90 +2868,126 @@ static void STDMETHODCALLTYPE d3d11_device_context_VSSetConstantBuffers1(ID3D11D UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, const UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_HSSetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, const UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_HULL, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_DSSetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, const UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_DOMAIN, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_GSSetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, const UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_PSSetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, const UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_CSSetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer * const *buffers, const UINT *first_constant, const UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_set_constant_buffers(iface, WINED3D_SHADER_TYPE_COMPUTE, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_VSGetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_VERTEX, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_HSGetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_HULL, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_DSGetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_DOMAIN, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_GSGetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_GEOMETRY, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_PSGetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_PIXEL, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_CSGetConstantBuffers1(ID3D11DeviceContext1 *iface, UINT start_slot, UINT buffer_count, ID3D11Buffer **buffers, UINT *first_constant, UINT *num_constants) { - FIXME("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p stub!\n", + TRACE("iface %p, start_slot %u, buffer_count %u, buffers %p, first_constant %p, num_constants %p.\n", iface, start_slot, buffer_count, buffers, first_constant, num_constants); + + d3d11_device_context_get_constant_buffers(iface, WINED3D_SHADER_TYPE_COMPUTE, start_slot, + buffer_count, buffers, first_constant, num_constants); }
static void STDMETHODCALLTYPE d3d11_device_context_SwapDeviceContextState(ID3D11DeviceContext1 *iface, @@ -4506,17 +4571,19 @@ static void d3d10_device_get_constant_buffers(ID3D10Device1 *iface, wined3d_mutex_lock(); for (i = 0; i < buffer_count; ++i) { - struct wined3d_buffer *wined3d_buffer; + struct wined3d_constant_buffer_state state; struct d3d_buffer *buffer_impl;
- if (!(wined3d_buffer = wined3d_device_context_get_constant_buffer(device->immediate_context.wined3d_context, - type, start_slot + i))) + wined3d_device_context_get_constant_buffer(device->immediate_context.wined3d_context, + type, start_slot + i, &state); + + if (!state.buffer) { buffers[i] = NULL; continue; }
- buffer_impl = wined3d_buffer_get_parent(wined3d_buffer); + buffer_impl = wined3d_buffer_get_parent(state.buffer); buffers[i] = &buffer_impl->ID3D10Buffer_iface; ID3D10Buffer_AddRef(buffers[i]); } @@ -4526,7 +4593,7 @@ static void d3d10_device_get_constant_buffers(ID3D10Device1 *iface, static void d3d10_device_set_constant_buffers(ID3D10Device1 *iface, enum wined3d_shader_type type, unsigned int start_slot, unsigned int buffer_count, ID3D10Buffer *const *buffers) { - struct wined3d_buffer *wined3d_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + struct wined3d_constant_buffer_state wined3d_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; struct d3d_device *device = impl_from_ID3D10Device(iface); unsigned int i;
@@ -4540,7 +4607,9 @@ static void d3d10_device_set_constant_buffers(ID3D10Device1 *iface, enum wined3d { struct d3d_buffer *buffer = unsafe_impl_from_ID3D10Buffer(buffers[i]);
- wined3d_buffers[i] = buffer ? buffer->wined3d_buffer : NULL; + wined3d_buffers[i].buffer = buffer ? buffer->wined3d_buffer : NULL; + wined3d_buffers[i].offset = 0; + wined3d_buffers[i].size = WINED3D_MAX_CONSTANT_BUFFER_SIZE * sizeof(struct wined3d_vec4); }
wined3d_mutex_lock(); diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 474003d7553..224c46efb6f 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -3759,10 +3759,10 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
for (j = 0; j < WINED3D_MAX_CBS; ++j) { - if (!state->cb[i][j]) + if (!state->cb[i][j].buffer) continue;
- buffer_gl = wined3d_buffer_gl(state->cb[i][j]); + buffer_gl = wined3d_buffer_gl(state->cb[i][j].buffer); wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state); wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo); if (!buffer_gl->bo_user.valid) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index cbff3968179..d1a113d1f81 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2713,7 +2713,7 @@ static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *con switch (binding->shader_descriptor_type) { case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV: - if (!(buffer = state->cb[binding->shader_type][binding->resource_idx])) + if (!(buffer = state->cb[binding->shader_type][binding->resource_idx].buffer)) { if (!wined3d_shader_descriptor_writes_vk_add_write(writes, vk_descriptor_set, binding->binding_idx, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, @@ -2988,7 +2988,7 @@ static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk * switch (binding->shader_descriptor_type) { case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV: - if (!(buffer = state->cb[binding->shader_type][binding->resource_idx])) + if (!(buffer = state->cb[binding->shader_type][binding->resource_idx].buffer)) break;
buffer_vk = wined3d_buffer_vk(buffer); diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 434a9c20fb1..3ce12659999 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -280,7 +280,7 @@ struct wined3d_cs_set_constant_buffers enum wined3d_shader_type type; unsigned int start_idx; unsigned int count; - struct wined3d_buffer *buffers[1]; + struct wined3d_constant_buffer_state buffers[1]; };
struct wined3d_cs_set_texture @@ -877,8 +877,8 @@ static void acquire_shader_resources(struct wined3d_device_context *context, uns
for (j = 0; j < WINED3D_MAX_CBS; ++j) { - if (state->cb[i][j]) - wined3d_device_context_acquire_resource(context, &state->cb[i][j]->resource); + if (state->cb[i][j].buffer) + wined3d_device_context_acquire_resource(context, &state->cb[i][j].buffer->resource); }
for (j = 0; j < shader->reg_maps.sampler_map.count; ++j) @@ -910,8 +910,8 @@ static void release_shader_resources(const struct wined3d_state *state, unsigned
for (j = 0; j < WINED3D_MAX_CBS; ++j) { - if (state->cb[i][j]) - wined3d_resource_release(&state->cb[i][j]->resource); + if (state->cb[i][j].buffer) + wined3d_resource_release(&state->cb[i][j].buffer->resource); }
for (j = 0; j < shader->reg_maps.sampler_map.count; ++j) @@ -1512,10 +1512,10 @@ static void wined3d_cs_exec_set_constant_buffers(struct wined3d_cs *cs, const vo
for (i = 0; i < op->count; ++i) { - struct wined3d_buffer *prev = cs->state.cb[op->type][op->start_idx + i]; - struct wined3d_buffer *buffer = op->buffers[i]; + struct wined3d_buffer *prev = cs->state.cb[op->type][op->start_idx + i].buffer; + struct wined3d_buffer *buffer = op->buffers[i].buffer;
- cs->state.cb[op->type][op->start_idx + i] = buffer; + cs->state.cb[op->type][op->start_idx + i] = op->buffers[i];
if (buffer) InterlockedIncrement(&buffer->resource.bind_count); @@ -1528,7 +1528,7 @@ static void wined3d_cs_exec_set_constant_buffers(struct wined3d_cs *cs, const vo
void wined3d_device_context_emit_set_constant_buffers(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, - struct wined3d_buffer *const *buffers) + const struct wined3d_constant_buffer_state *buffers) { struct wined3d_cs_set_constant_buffers *op;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index e4a16e56a56..f08ab0b109d 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1796,7 +1796,7 @@ struct wined3d_shader * CDECL wined3d_device_context_get_shader(const struct win
void CDECL wined3d_device_context_set_constant_buffers(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, - struct wined3d_buffer *const *buffers) + const struct wined3d_constant_buffer_state *buffers) { struct wined3d_state *state = context->state; unsigned int i; @@ -1815,12 +1815,12 @@ void CDECL wined3d_device_context_set_constant_buffers(struct wined3d_device_con wined3d_device_context_emit_set_constant_buffers(context, type, start_idx, count, buffers); for (i = 0; i < count; ++i) { - struct wined3d_buffer *prev = state->cb[type][start_idx + i]; - struct wined3d_buffer *buffer = buffers[i]; + struct wined3d_buffer *prev = state->cb[type][start_idx + i].buffer; + struct wined3d_buffer *buffer = buffers[i].buffer;
if (buffer) wined3d_buffer_incref(buffer); - state->cb[type][start_idx + i] = buffer; + state->cb[type][start_idx + i] = buffers[i]; if (prev) wined3d_buffer_decref(prev); } @@ -2359,18 +2359,18 @@ void CDECL wined3d_device_context_draw_indexed(struct wined3d_device_context *co base_vertex_index, start_index, index_count, start_instance, instance_count, true); }
-struct wined3d_buffer * CDECL wined3d_device_context_get_constant_buffer(const struct wined3d_device_context *context, - enum wined3d_shader_type shader_type, unsigned int idx) +void CDECL wined3d_device_context_get_constant_buffer(const struct wined3d_device_context *context, + enum wined3d_shader_type shader_type, unsigned int idx, struct wined3d_constant_buffer_state *state) { TRACE("context %p, shader_type %#x, idx %u.\n", context, shader_type, idx);
if (idx >= MAX_CONSTANT_BUFFERS) { WARN("Invalid constant buffer index %u.\n", idx); - return NULL; + return; }
- return context->state->cb[shader_type][idx]; + *state = context->state->cb[shader_type][idx]; }
struct wined3d_shader_resource_view * CDECL wined3d_device_context_get_shader_resource_view( diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index a9183278d86..8316269afcf 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4558,14 +4558,17 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, shader_type, &base, &count); for (i = 0; i < count; ++i) { - if (!state->cb[shader_type][i]) + const struct wined3d_constant_buffer_state *buffer_state = &state->cb[shader_type][i]; + + if (!buffer_state->buffer) { GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, 0)); continue; }
- buffer_gl = wined3d_buffer_gl(state->cb[shader_type][i]); - GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, buffer_gl->bo.id)); + buffer_gl = wined3d_buffer_gl(buffer_state->buffer); + GL_EXTCALL(glBindBufferRange(GL_UNIFORM_BUFFER, base + i, buffer_gl->bo.id, + buffer_state->offset, buffer_state->size)); buffer_gl->bo_user.valid = true; } checkGLcall("bind constant buffers"); diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 4cf30941d62..39a19984498 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -431,9 +431,9 @@ void state_unbind_resources(struct wined3d_state *state)
for (j = 0; j < MAX_CONSTANT_BUFFERS; ++j) { - if ((buffer = state->cb[i][j])) + if ((buffer = state->cb[i][j].buffer)) { - state->cb[i][j] = NULL; + state->cb[i][j].buffer = NULL; wined3d_buffer_decref(buffer); } } @@ -1829,8 +1829,8 @@ static void init_default_sampler_states(DWORD states[WINED3D_MAX_COMBINED_SAMPLE
static void state_init_default(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info) { - unsigned int i; struct wined3d_matrix identity; + unsigned int i, j;
TRACE("state %p, d3d_info %p.\n", state, d3d_info);
@@ -1867,6 +1867,12 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d
for (i = 0; i < WINED3D_MAX_STREAMS; ++i) state->streams[i].frequency = 1; + + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + { + for (j = 0; j < MAX_CONSTANT_BUFFERS; ++j) + state->cb[i][j].size = WINED3D_MAX_CONSTANT_BUFFER_SIZE * 16; + } }
void state_init(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 2d36d0882ff..1bce4def265 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -101,7 +101,7 @@ @ cdecl wined3d_device_context_flush(ptr) @ cdecl wined3d_device_context_generate_mipmaps(ptr ptr) @ cdecl wined3d_device_context_get_blend_state(ptr ptr ptr) -@ cdecl wined3d_device_context_get_constant_buffer(ptr long long) +@ cdecl wined3d_device_context_get_constant_buffer(ptr long long ptr) @ cdecl wined3d_device_context_get_depth_stencil_state(ptr ptr) @ cdecl wined3d_device_context_get_depth_stencil_view(ptr) @ cdecl wined3d_device_context_get_index_buffer(ptr ptr ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fb25e856ead..e8cc9d9e458 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3693,7 +3693,7 @@ struct wined3d_state BOOL predicate_value;
struct wined3d_shader *shader[WINED3D_SHADER_TYPE_COUNT]; - struct wined3d_buffer *cb[WINED3D_SHADER_TYPE_COUNT][MAX_CONSTANT_BUFFERS]; + struct wined3d_constant_buffer_state cb[WINED3D_SHADER_TYPE_COUNT][MAX_CONSTANT_BUFFERS]; struct wined3d_sampler *sampler[WINED3D_SHADER_TYPE_COUNT][MAX_SAMPLER_OBJECTS]; struct wined3d_shader_resource_view *shader_resource_view[WINED3D_SHADER_TYPE_COUNT][MAX_SHADER_RESOURCE_VIEWS]; struct wined3d_unordered_access_view *unordered_access_view[WINED3D_PIPELINE_COUNT][MAX_UNORDERED_ACCESS_VIEWS]; @@ -4804,7 +4804,7 @@ void wined3d_device_context_emit_set_clip_plane(struct wined3d_device_context *c const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_constant_buffers(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, - struct wined3d_buffer *const *buffers) DECLSPEC_HIDDEN; + const struct wined3d_constant_buffer_state *buffers) DECLSPEC_HIDDEN; 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; void wined3d_device_context_emit_set_depth_stencil_view(struct wined3d_device_context *context, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index baa71758d17..7be893b8f21 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1611,6 +1611,7 @@ enum wined3d_pipeline #define WINED3D_MAX_VS_CONSTS_F 256 #define WINED3D_MAX_PS_CONSTS_F 224 #define WINED3D_MAX_RENDER_TARGETS 8 +#define WINED3D_MAX_CONSTANT_BUFFER_SIZE 4096
struct wined3d_display_mode { @@ -2218,6 +2219,13 @@ struct wined3d_stream_output unsigned int offset; };
+struct wined3d_constant_buffer_state +{ + struct wined3d_buffer *buffer; + unsigned int offset; + unsigned int size; +}; + struct wined3d_parent_ops { void (__stdcall *wined3d_object_destroyed)(void *parent); @@ -2457,8 +2465,8 @@ void __cdecl wined3d_device_context_generate_mipmaps(struct wined3d_device_conte struct wined3d_shader_resource_view *view); struct wined3d_blend_state * __cdecl wined3d_device_context_get_blend_state( const struct wined3d_device_context *context, struct wined3d_color *blend_factor, unsigned int *sample_mask); -struct wined3d_buffer * __cdecl wined3d_device_context_get_constant_buffer(const struct wined3d_device_context *context, - enum wined3d_shader_type shader_type, unsigned int idx); +void __cdecl wined3d_device_context_get_constant_buffer(const struct wined3d_device_context *context, + enum wined3d_shader_type shader_type, unsigned int idx, struct wined3d_constant_buffer_state *state); struct wined3d_depth_stencil_state * __cdecl wined3d_device_context_get_depth_stencil_state( const struct wined3d_device_context *context, unsigned int *stencil_ref); struct wined3d_rendertarget_view * __cdecl wined3d_device_context_get_depth_stencil_view( @@ -2504,7 +2512,7 @@ void __cdecl wined3d_device_context_set_blend_state(struct wined3d_device_contex struct wined3d_blend_state *state, const struct wined3d_color *blend_factor, unsigned int sample_mask); void __cdecl wined3d_device_context_set_constant_buffers(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, - struct wined3d_buffer *const *buffers); + const struct wined3d_constant_buffer_state *buffers); 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); HRESULT __cdecl wined3d_device_context_set_depth_stencil_view(struct wined3d_device_context *context,
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3d11/tests/d3d11.c | 243 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index fcbe4f4a740..252a8c88051 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -33445,6 +33445,248 @@ static void test_texture_compressed_3d(void) release_test_context(&test_context); }
+static void test_constant_buffer_offset(void) +{ + static const float black[] = {0.0f, 0.0f, 0.0f, 1.0f}; + ID3D11Buffer *buffers[2], *ret_buffers[2]; + struct d3d11_test_context test_context; + struct vec4 buffer_data[32] = {0}; + ID3D11DeviceContext1 *context; + UINT offsets[2], counts[2]; + ID3D11PixelShader *ps; + ID3D11Device *device; + DWORD color; + HRESULT hr; + + static const DWORD ps_code[] = + { +#if 0 + cbuffer c1 : register(b1) + { + float r, g; + }; + cbuffer c2 : register(b2) + { + float b, a; + }; + + float4 main() : SV_Target + { + return float4(r, g, b, a); + } +#endif + 0x43425844, 0x8ca1d640, 0x33cd6f81, 0x987c9395, 0xc2110ba4, 0x00000001, 0x000000e0, 0x00000003, + 0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, + 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000068, 0x00000040, 0x0000001a, + 0x04000059, 0x00208e46, 0x00000001, 0x00000001, 0x04000059, 0x00208e46, 0x00000002, 0x00000001, + 0x03000065, 0x001020f2, 0x00000000, 0x06000036, 0x00102032, 0x00000000, 0x00208046, 0x00000001, + 0x00000000, 0x06000036, 0x001020c2, 0x00000000, 0x00208406, 0x00000002, 0x00000000, 0x0100003e, + }; + + if (!init_test_context(&test_context, NULL)) + return; + device = test_context.device; + + if (FAILED(ID3D11DeviceContext_QueryInterface(test_context.immediate_context, + &IID_ID3D11DeviceContext1, (void **)&context))) + { + skip("ID3D11DeviceContext1 is not available.\n"); + release_test_context(&test_context); + return; + } + + buffer_data[0].x = 0.1f; + buffer_data[0].y = 0.2f; + buffer_data[16].x = 0.3f; + buffer_data[16].y = 0.4f; + buffers[0] = create_buffer(device, D3D11_BIND_CONSTANT_BUFFER, sizeof(buffer_data), buffer_data); + buffer_data[0].x = 0.5f; + buffer_data[0].y = 0.6f; + buffer_data[16].x = 0.7f; + buffer_data[16].y = 0.8f; + buffers[1] = create_buffer(device, D3D11_BIND_CONSTANT_BUFFER, sizeof(buffer_data), buffer_data); + + hr = ID3D11Device_CreatePixelShader(device, ps_code, sizeof(ps_code), NULL, &ps); + ok(hr == S_OK, "Failed to create pixel shader, hr %#x.\n", hr); + + ID3D11DeviceContext1_ClearRenderTargetView(context, test_context.backbuffer_rtv, black); + ID3D11DeviceContext1_PSSetShader(context, ps, NULL, 0); + + memset(ret_buffers, 0xab, sizeof(ret_buffers)); + memset(offsets, 0xab, sizeof(offsets)); + memset(counts, 0xab, sizeof(counts)); + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts); + ok(!ret_buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(!ret_buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(!offsets[0], "Got offset %u.\n", offsets[0]); + ok(!offsets[1], "Got offset %u.\n", offsets[1]); + ok(counts[0] == 4096, "Got count %u.\n", counts[0]); + ok(counts[1] == 4096, "Got count %u.\n", counts[1]); + + offsets[0] = 0; + offsets[1] = 16; + counts[0] = 16; + counts[1] = 16; + ID3D11DeviceContext1_PSSetConstantBuffers1(context, 1, 2, buffers, offsets, counts); + + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(offsets[0] == 0, "Got offset %u.\n", offsets[0]); + ok(offsets[1] == 16, "Got offset %u.\n", offsets[1]); + ok(counts[0] == 16, "Got count %u.\n", counts[0]); + ok(counts[1] == 16, "Got count %u.\n", counts[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + memset(ret_buffers, 0xab, sizeof(ret_buffers)); + memset(offsets, 0xab, sizeof(offsets)); + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, NULL); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(offsets[0] == 0, "Got offset %u.\n", offsets[0]); + ok(offsets[1] == 16, "Got offset %u.\n", offsets[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + memset(ret_buffers, 0xab, sizeof(ret_buffers)); + memset(counts, 0xab, sizeof(counts)); + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, NULL, counts); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(counts[0] == 16, "Got count %u.\n", counts[0]); + ok(counts[1] == 16, "Got count %u.\n", counts[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + draw_quad(&test_context); + color = get_texture_color(test_context.backbuffer, 320, 240); + ok(compare_color(color, 0xccb23319, 1), "Got unexpected color 0x%08x.\n", color); + + /* The following calls are all invalid. */ + + offsets[0] = 0; + offsets[1] = 1; + counts[0] = 32; + counts[1] = 16; + ID3D11DeviceContext1_PSSetConstantBuffers1(context, 1, 2, buffers, offsets, counts); + + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(offsets[0] == 0, "Got offset %u.\n", offsets[0]); + ok(offsets[1] == 16, "Got offset %u.\n", offsets[1]); + ok(counts[0] == 16, "Got count %u.\n", counts[0]); + ok(counts[1] == 16, "Got count %u.\n", counts[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + offsets[0] = 0; + offsets[1] = 0; + counts[0] = 17; + counts[1] = 16; + ID3D11DeviceContext1_PSSetConstantBuffers1(context, 1, 2, buffers, offsets, counts); + + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(offsets[0] == 0, "Got offset %u.\n", offsets[0]); + ok(offsets[1] == 16, "Got offset %u.\n", offsets[1]); + ok(counts[0] == 16, "Got count %u.\n", counts[0]); + ok(counts[1] == 16, "Got count %u.\n", counts[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + ID3D11DeviceContext1_PSSetConstantBuffers1(context, 1, 2, buffers, offsets, NULL); + + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(offsets[0] == 0, "Got offset %u.\n", offsets[0]); + ok(offsets[1] == 16, "Got offset %u.\n", offsets[1]); + ok(counts[0] == 16, "Got count %u.\n", counts[0]); + ok(counts[1] == 16, "Got count %u.\n", counts[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + counts[0] = 32; + counts[1] = 16; + ID3D11DeviceContext1_PSSetConstantBuffers1(context, 1, 2, buffers, NULL, counts); + + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(offsets[0] == 0, "Got offset %u.\n", offsets[0]); + ok(offsets[1] == 16, "Got offset %u.\n", offsets[1]); + ok(counts[0] == 16, "Got count %u.\n", counts[0]); + ok(counts[1] == 16, "Got count %u.\n", counts[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + draw_quad(&test_context); + color = get_texture_color(test_context.backbuffer, 320, 240); + ok(compare_color(color, 0xccb23319, 1), "Got unexpected color 0x%08x.\n", color); + + ID3D11DeviceContext1_PSSetConstantBuffers1(context, 1, 2, buffers, NULL, NULL); + + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(!offsets[0], "Got offset %u.\n", offsets[0]); + ok(!offsets[1], "Got offset %u.\n", offsets[1]); + ok(counts[0] == 4096, "Got count %u.\n", counts[0]); + ok(counts[1] == 4096, "Got count %u.\n", counts[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + draw_quad(&test_context); + color = get_texture_color(test_context.backbuffer, 320, 240); + ok(compare_color(color, 0x99803319, 1), "Got unexpected color 0x%08x.\n", color); + + offsets[0] = 16; + offsets[1] = 0; + counts[0] = 16; + counts[1] = 32; + ID3D11DeviceContext1_PSSetConstantBuffers1(context, 1, 2, buffers, offsets, counts); + + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(offsets[0] == 16, "Got offset %u.\n", offsets[0]); + ok(offsets[1] == 0, "Got offset %u.\n", offsets[1]); + ok(counts[0] == 16, "Got count %u.\n", counts[0]); + ok(counts[1] == 32, "Got count %u.\n", counts[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + draw_quad(&test_context); + color = get_texture_color(test_context.backbuffer, 320, 240); + ok(compare_color(color, 0x9980664c, 1), "Got unexpected color 0x%08x.\n", color); + + ID3D11DeviceContext1_PSSetConstantBuffers(context, 1, 2, buffers); + + ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts); + ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]); + ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]); + ok(!offsets[0], "Got offset %u.\n", offsets[0]); + ok(!offsets[1], "Got offset %u.\n", offsets[1]); + ok(counts[0] == 4096, "Got count %u.\n", counts[0]); + ok(counts[1] == 4096, "Got count %u.\n", counts[1]); + ID3D11Buffer_Release(ret_buffers[0]); + ID3D11Buffer_Release(ret_buffers[1]); + + draw_quad(&test_context); + color = get_texture_color(test_context.backbuffer, 320, 240); + ok(compare_color(color, 0x99803319, 1), "Got unexpected color 0x%08x.\n", color); + + ID3D11DeviceContext1_Release(context); + ID3D11Buffer_Release(buffers[0]); + ID3D11Buffer_Release(buffers[1]); + ID3D11PixelShader_Release(ps); + release_test_context(&test_context); +} + START_TEST(d3d11) { unsigned int argc, i; @@ -33619,6 +33861,7 @@ START_TEST(d3d11) queue_test(test_deferred_context_map); queue_test(test_unbound_streams); queue_test(test_texture_compressed_3d); + queue_test(test_constant_buffer_offset);
run_queued_tests(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=93918
Your paranoid android.
=== w2008s64 (32 bit report) ===
d3d11: d3d11.c:5918: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5921: Test failed: Got unexpected CInvocations count: 0.
=== w1064v1809 (32 bit report) ===
d3d11: d3d11.c:5916: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5917: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5918: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5921: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5922: Test failed: Got unexpected CPrimitives count: 0.
=== w1064 (32 bit report) ===
d3d11: d3d11.c:5916: Test failed: Got unexpected IAVertices count: 0. d3d11.c:5917: Test failed: Got unexpected IAPrimitives count: 0. d3d11.c:5918: Test failed: Got unexpected VSInvocations count: 0. d3d11.c:5921: Test failed: Got unexpected CInvocations count: 0. d3d11.c:5922: Test failed: Got unexpected CPrimitives count: 0.
=== debiant2 (32 bit Hindi:India report) ===
d3d11: d3d11.c:5939: Test failed: d3d11.c:5640: Test marked todo: Got unexpected hr 0x8876086a for query type 13.
=== debiant2 (32 bit Japanese:Japan report) ===
d3d11: d3d11.c:9766: Test failed: d3d11.c:15127: Test marked todo: Got hr 0 for WRITE_DISCARD. d3d11.c:9766: Test failed: Got hr 0 for WRITE.
=== debiant2 (32 bit WoW report) ===
d3d11: d3d11.c:9766: Test failed: d3d11.c:15218: Test marked todo: Got hr 0 for WRITE_DISCARD.
On Fri, 9 Jul 2021 at 00:18, Zebediah Figura zfigura@codeweavers.com wrote:
- ID3D11DeviceContext1_PSGetConstantBuffers1(context, 1, 2, ret_buffers, offsets, counts);
- ok(ret_buffers[0] == buffers[0], "Got buffer %p.\n", ret_buffers[0]);
- ok(ret_buffers[1] == buffers[1], "Got buffer %p.\n", ret_buffers[1]);
- ok(offsets[0] == 0, "Got offset %u.\n", offsets[0]);
- ok(offsets[1] == 16, "Got offset %u.\n", offsets[1]);
- ok(counts[0] == 16, "Got count %u.\n", counts[0]);
- ok(counts[1] == 16, "Got count %u.\n", counts[1]);
- ID3D11Buffer_Release(ret_buffers[0]);
- ID3D11Buffer_Release(ret_buffers[1]);
This ends up failing (and then crashing) here on Windows.
And indeed, my driver reports "FALSE" for D3D11_FEATURE_DATA_D3D11_OPTIONS.ConstantBufferOffsetting. Conversely, we should probably report the feature as supported in Wine.
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=93912
Your paranoid android.
=== debiant2 (32 bit report) ===
d3d11: d3d11.c:9766: Test failed: d3d11.c:15149: Test marked todo: Got hr 0 for WRITE_DISCARD.