From 96570c521662ebab4f9894bab10ec6d5cec93745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Wed, 29 Mar 2017 15:11:08 +0200 Subject: [PATCH] wined3d: Bind transform feedback buffers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/buffer.c | 2 ++ dlls/wined3d/context.c | 17 +++++++++++++++ dlls/wined3d/cs.c | 2 ++ dlls/wined3d/state.c | 38 +++++++++++++++++++++++++++++++++- dlls/wined3d/utils.c | 2 ++ dlls/wined3d/wined3d_private.h | 5 ++++- 6 files changed, 64 insertions(+), 2 deletions(-) diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 3c6bc61aa95..4e8569cbe21 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -176,6 +176,8 @@ static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, const st device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL)); device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE)); } + if (buffer->bind_flags & WINED3D_BIND_STREAM_OUTPUT) + device_invalidate_state(resource->device, STATE_STREAM_OUTPUT); } if (buffer->query) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index 426d697c22e..3c297df1de4 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3518,6 +3518,22 @@ static void context_bind_unordered_access_views(struct wined3d_context *context, checkGLcall("Bind unordered access views"); } +static void context_load_stream_output_buffers(struct wined3d_context *context, + const struct wined3d_state *state) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i) + { + struct wined3d_buffer *buffer; + if (!(buffer = state->stream_output[i].buffer)) + continue; + + wined3d_buffer_load(buffer, context, state); + wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER); + } +} + /* Context activation is done by the caller. */ BOOL context_apply_draw_state(struct wined3d_context *context, const struct wined3d_device *device, const struct wined3d_state *state) @@ -3544,6 +3560,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context, context_load_shader_resources(context, state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)); context_load_unordered_access_resources(context, state->shader[WINED3D_SHADER_TYPE_PIXEL], state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]); + context_load_stream_output_buffers(context, state); /* TODO: Right now the dependency on the vertex shader is necessary * since wined3d_stream_info_from_declaration() depends on the reg_maps of * the current VS but maybe it's possible to relax the coupling in some diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 71099e7519b..423650c6adf 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -925,6 +925,8 @@ static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void InterlockedIncrement(&op->buffer->resource.bind_count); if (prev) InterlockedDecrement(&prev->resource.bind_count); + + device_invalidate_state(cs->device, STATE_STREAM_OUTPUT); } void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 7ad98b8fd27..2b846ae2775 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4930,7 +4930,7 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state buffer = state->cb[shader_type][i]; GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, buffer ? buffer->buffer_object : 0)); } - checkGLcall("glBindBufferBase"); + checkGLcall("bind constant buffers"); } static void state_cb_warn(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) @@ -4974,6 +4974,40 @@ static void state_uav_warn(struct wined3d_context *context, const struct wined3d WARN("ARB_image_load_store is not supported by OpenGL implementation.\n"); } +static void state_so(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_buffer *buffer; + unsigned int offset, size, i; + + TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); + + for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i) + { + if (!(buffer = state->stream_output[i].buffer)) + { + GL_EXTCALL(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, 0)); + continue; + } + + offset = state->stream_output[i].offset; + if (offset == ~0u) + { + FIXME("Appending to stream output buffers not implemented.\n"); + offset = 0; + } + size = buffer->resource.size - offset; + GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, + buffer->buffer_object, offset, size)); + } + checkGLcall("bind transform feedback buffers"); +} + +static void state_so_warn(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +{ + WARN("Transform feedback not supported.\n"); +} + const struct StateEntryTemplate misc_state_template[] = { { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), { STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), state_cb, }, ARB_UNIFORM_BUFFER_OBJECT }, @@ -4990,6 +5024,8 @@ const struct StateEntryTemplate misc_state_template[] = { STATE_COMPUTE_SHADER_RESOURCE_BINDING, { STATE_COMPUTE_SHADER_RESOURCE_BINDING, state_cs_resource_binding}, WINED3D_GL_EXT_NONE }, { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, state_cs_uav_binding}, ARB_SHADER_IMAGE_LOAD_STORE }, { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, state_uav_warn }, WINED3D_GL_EXT_NONE }, + { STATE_STREAM_OUTPUT, { STATE_STREAM_OUTPUT, state_so, }, WINED3D_GL_VERSION_3_2 }, + { STATE_STREAM_OUTPUT, { STATE_STREAM_OUTPUT, state_so_warn, }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE }, { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 1627752596f..87afcaba832 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4462,6 +4462,8 @@ const char *debug_d3dstate(DWORD state) return "STATE_POINT_ENABLE"; if (STATE_IS_COLOR_KEY(state)) return "STATE_COLOR_KEY"; + if (STATE_IS_STREAM_OUTPUT(state)) + return "STATE_STREAM_OUTPUT"; return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 1d599829ec3..3c666d6aa04 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1513,7 +1513,10 @@ enum wined3d_pipeline #define STATE_COLOR_KEY (STATE_POINT_ENABLE + 1) #define STATE_IS_COLOR_KEY(a) ((a) == STATE_COLOR_KEY) -#define STATE_COMPUTE_OFFSET (STATE_COLOR_KEY + 1) +#define STATE_STREAM_OUTPUT (STATE_COLOR_KEY + 1) +#define STATE_IS_STREAM_OUTPUT(a) ((a) == STATE_STREAM_OUTPUT) + +#define STATE_COMPUTE_OFFSET (STATE_STREAM_OUTPUT + 1) #define STATE_COMPUTE_SHADER (STATE_COMPUTE_OFFSET) #define STATE_IS_COMPUTE_SHADER(a) ((a) == STATE_COMPUTE_SHADER)