wined3d: Enable transform feedback if geometry shader with stream output is active.
Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c8dc913c47
commit
2e3300fa59
|
@ -11489,7 +11489,6 @@ static void test_index_buffer_offset(void)
|
|||
for (i = 0; i < ARRAY_SIZE(expected_data); ++i)
|
||||
{
|
||||
data = get_readback_vec4(&rb, i, 0);
|
||||
todo_wine
|
||||
ok(compare_vec4(data, &expected_data[i], 0)
|
||||
|| broken(is_nvidia_device(device) && !(i % 2) && compare_vec4(data, &broken_result, 0)),
|
||||
"Got unexpected result {%.8e, %.8e, %.8e, %.8e} at %u.\n",
|
||||
|
|
|
@ -144,7 +144,7 @@ static void buffer_bind(struct wined3d_buffer *buffer, struct wined3d_context *c
|
|||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, const struct wined3d_context *context)
|
||||
static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, struct wined3d_context *context)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
struct wined3d_resource *resource = &buffer->resource;
|
||||
|
@ -152,10 +152,6 @@ static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, const st
|
|||
if (!buffer->buffer_object)
|
||||
return;
|
||||
|
||||
GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object));
|
||||
checkGLcall("glDeleteBuffers");
|
||||
buffer->buffer_object = 0;
|
||||
|
||||
/* The stream source state handler might have read the memory of the
|
||||
* vertex buffer already and got the memory in the vbo which is not
|
||||
* valid any longer. Dirtify the stream source to force a reload. This
|
||||
|
@ -177,9 +173,25 @@ static void buffer_destroy_buffer_object(struct wined3d_buffer *buffer, const st
|
|||
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 (context->transform_feedback_active)
|
||||
{
|
||||
/* We have to make sure that transform feedback is not active
|
||||
* when deleting a potentially bound transform feedback buffer.
|
||||
* This may happen when the device is being destroyed. */
|
||||
WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer);
|
||||
GL_EXTCALL(glEndTransformFeedback());
|
||||
checkGLcall("glEndTransformFeedback");
|
||||
context->transform_feedback_active = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GL_EXTCALL(glDeleteBuffers(1, &buffer->buffer_object));
|
||||
checkGLcall("glDeleteBuffers");
|
||||
buffer->buffer_object = 0;
|
||||
|
||||
if (buffer->query)
|
||||
{
|
||||
wined3d_event_query_destroy(buffer->query);
|
||||
|
|
|
@ -406,6 +406,14 @@ static void remove_vbos(struct wined3d_context *context,
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL use_transform_feedback(const struct wined3d_state *state)
|
||||
{
|
||||
const struct wined3d_shader *shader;
|
||||
if (!(shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]))
|
||||
return FALSE;
|
||||
return shader->u.gs.so_desc.element_count;
|
||||
}
|
||||
|
||||
/* Routine common to the draw primitive and draw indexed primitive routines */
|
||||
void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state,
|
||||
int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
|
||||
|
@ -439,6 +447,13 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
|
|||
}
|
||||
gl_info = context->gl_info;
|
||||
|
||||
if (context->transform_feedback_active && !use_transform_feedback(state))
|
||||
{
|
||||
GL_EXTCALL(glEndTransformFeedback());
|
||||
checkGLcall("glEndTransformFeedback");
|
||||
context->transform_feedback_active = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < gl_info->limits.buffers; ++i)
|
||||
{
|
||||
struct wined3d_texture *rt;
|
||||
|
@ -549,6 +564,16 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
|
|||
}
|
||||
}
|
||||
|
||||
if (use_transform_feedback(state) && !context->transform_feedback_active)
|
||||
{
|
||||
const struct wined3d_shader *shader = state->shader[WINED3D_SHADER_TYPE_GEOMETRY];
|
||||
GLenum primitive_mode = gl_primitive_type_from_d3d(shader->u.gs.output_type);
|
||||
|
||||
GL_EXTCALL(glBeginTransformFeedback(primitive_mode));
|
||||
checkGLcall("glBeginTransformFeedback");
|
||||
context->transform_feedback_active = 1;
|
||||
}
|
||||
|
||||
if (context->use_immediate_mode_draw || emulation)
|
||||
draw_primitive_immediate_mode(context, state, stream_info, idx_data,
|
||||
idx_size, base_vertex_idx, start_idx, index_count, instance_count);
|
||||
|
|
|
@ -4982,6 +4982,13 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
|
|||
|
||||
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
|
||||
|
||||
if (context->transform_feedback_active)
|
||||
{
|
||||
GL_EXTCALL(glEndTransformFeedback());
|
||||
checkGLcall("glEndTransformFeedback");
|
||||
context->transform_feedback_active = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i)
|
||||
{
|
||||
if (!(buffer = state->stream_output[i].buffer))
|
||||
|
|
|
@ -1689,7 +1689,8 @@ struct wined3d_context
|
|||
DWORD update_compute_unordered_access_view_bindings : 1;
|
||||
DWORD uses_uavs : 1;
|
||||
DWORD destroy_delayed : 1;
|
||||
DWORD padding : 9;
|
||||
DWORD transform_feedback_active : 1;
|
||||
DWORD padding : 8;
|
||||
DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */
|
||||
DWORD shader_update_mask;
|
||||
DWORD constant_update_mask;
|
||||
|
|
Loading…
Reference in New Issue