Commit 5ce7adaa authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

d3d11: Implement constant buffer offsetting for OpenGL.

Based on a patch by Kimmo Myllyvirta. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45198Signed-off-by: 's avatarZebediah Figura <zfigura@codeweavers.com> Signed-off-by: 's avatarHenri Verbeet <hverbeet@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent befaf4d6
......@@ -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)
......
......@@ -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);
......
......@@ -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;
......
......@@ -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(
......
......@@ -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");
......
......@@ -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,
......
......@@ -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)
......
......@@ -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,
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment