From 5ce7adaace3637ff6f8a33264b62c69bf2e53967 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 15 Jul 2021 00:18:35 -0500 Subject: [PATCH] d3d11: Implement constant buffer offsetting for OpenGL. Based on a patch by Kimmo Myllyvirta. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45198 Signed-off-by: Zebediah Figura Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/d3d11/device.c | 149 ++++++++++++++++++++++++--------- 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, 159 insertions(+), 73 deletions(-) diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index fc34421f082..c47b5208360 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, @@ -3995,7 +4060,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CheckFeatureSupport(ID3D11Device2 options->ClearView = FALSE; options->CopyWithOverlap = FALSE; options->ConstantBufferPartialUpdate = FALSE; - options->ConstantBufferOffsetting = FALSE; + options->ConstantBufferOffsetting = TRUE; options->MapNoOverwriteOnDynamicConstantBuffer = FALSE; options->MapNoOverwriteOnDynamicBufferSRV = FALSE; options->MultisampleRTVWithForcedSampleCountOne = FALSE; @@ -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 360121e8fac..13c0fce5bb1 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -284,7 +284,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 @@ -881,8 +881,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) @@ -914,8 +914,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) @@ -1516,10 +1516,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); @@ -1532,7 +1532,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 431d1fc47e7..d2147447ee0 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); } @@ -2361,18 +2361,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 898b35050dd..a2048fc6ea6 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]; @@ -4805,7 +4805,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,