wined3d: Do not convert SO declaration entries.
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
04ed44a52c
commit
c74c8800b3
|
@ -24,21 +24,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
|
WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
|
||||||
|
|
||||||
static HRESULT osgn_handler(const char *data, DWORD data_size, DWORD tag, void *context)
|
|
||||||
{
|
|
||||||
struct wined3d_shader_signature *signature = context;
|
|
||||||
|
|
||||||
if (tag != TAG_OSGN && tag != TAG_OSG5)
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
if (signature->elements)
|
|
||||||
{
|
|
||||||
FIXME("Multiple input signatures.\n");
|
|
||||||
shader_free_signature(signature);
|
|
||||||
}
|
|
||||||
return shader_parse_signature(tag, data, data_size, signature);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *shader_get_string(const char *data, size_t data_size, DWORD offset)
|
static const char *shader_get_string(const char *data, size_t data_size, DWORD offset)
|
||||||
{
|
{
|
||||||
size_t len, max_len;
|
size_t len, max_len;
|
||||||
|
@ -1073,18 +1058,14 @@ static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops =
|
||||||
d3d_geometry_shader_wined3d_object_destroyed,
|
d3d_geometry_shader_wined3d_object_destroyed,
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_output_element *elements,
|
static HRESULT validate_stream_output_entries(const D3D11_SO_DECLARATION_ENTRY *entries, unsigned int entry_count,
|
||||||
const D3D11_SO_DECLARATION_ENTRY *entries, unsigned int entry_count,
|
const unsigned int *buffer_strides, unsigned int buffer_stride_count, D3D_FEATURE_LEVEL feature_level)
|
||||||
const unsigned int *buffer_strides, unsigned int buffer_stride_count,
|
|
||||||
const struct wined3d_shader_signature *os, D3D_FEATURE_LEVEL feature_level)
|
|
||||||
{
|
{
|
||||||
unsigned int i, j, mask;
|
unsigned int i, j;
|
||||||
|
|
||||||
for (i = 0; i < entry_count; ++i)
|
for (i = 0; i < entry_count; ++i)
|
||||||
{
|
{
|
||||||
struct wined3d_stream_output_element *e = &elements[i];
|
|
||||||
const D3D11_SO_DECLARATION_ENTRY *f = &entries[i];
|
const D3D11_SO_DECLARATION_ENTRY *f = &entries[i];
|
||||||
struct wined3d_shader_signature_element *output;
|
|
||||||
|
|
||||||
TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
|
TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
|
||||||
"component count %u, output slot %u.\n",
|
"component count %u, output slot %u.\n",
|
||||||
|
@ -1112,11 +1093,6 @@ static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_o
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->stream_idx = f->Stream;
|
|
||||||
e->component_idx = f->StartComponent;
|
|
||||||
e->component_count = f->ComponentCount;
|
|
||||||
e->output_slot = f->OutputSlot;
|
|
||||||
|
|
||||||
if (!f->SemanticName)
|
if (!f->SemanticName)
|
||||||
{
|
{
|
||||||
if (f->SemanticIndex)
|
if (f->SemanticIndex)
|
||||||
|
@ -1129,10 +1105,8 @@ static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_o
|
||||||
WARN("Invalid stream output gap %u-%u.\n", f->StartComponent, f->ComponentCount);
|
WARN("Invalid stream output gap %u-%u.\n", f->StartComponent, f->ComponentCount);
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->register_idx = WINED3D_STREAM_OUTPUT_GAP;
|
|
||||||
}
|
}
|
||||||
else if ((output = shader_find_signature_element(os, f->SemanticName, f->SemanticIndex, f->Stream)))
|
else
|
||||||
{
|
{
|
||||||
if (f->StartComponent > 3 || f->ComponentCount > 4 || !f->ComponentCount
|
if (f->StartComponent > 3 || f->ComponentCount > 4 || !f->ComponentCount
|
||||||
|| f->StartComponent + f->ComponentCount > 4)
|
|| f->StartComponent + f->ComponentCount > 4)
|
||||||
|
@ -1140,29 +1114,6 @@ static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_o
|
||||||
WARN("Invalid component range %u-%u.\n", f->StartComponent, f->ComponentCount);
|
WARN("Invalid component range %u-%u.\n", f->StartComponent, f->ComponentCount);
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < 4; ++j)
|
|
||||||
{
|
|
||||||
if ((1u << j) & output->mask)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
e->component_idx += j;
|
|
||||||
mask = ((1u << e->component_count) - 1) << e->component_idx;
|
|
||||||
if ((output->mask & 0xff & mask) != mask)
|
|
||||||
{
|
|
||||||
WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n",
|
|
||||||
e->component_idx, e->component_count, mask, output->mask & 0xff);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
e->register_idx = output->register_idx;
|
|
||||||
TRACE("Register idx: %u, register component idx %u, register mask %#x.\n",
|
|
||||||
e->register_idx, e->component_idx, mask);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WARN("Failed to find output signature element for stream output entry.\n");
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1255,7 +1206,6 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
|
||||||
unsigned int rasterizer_stream)
|
unsigned int rasterizer_stream)
|
||||||
{
|
{
|
||||||
struct wined3d_stream_output_desc so_desc;
|
struct wined3d_stream_output_desc so_desc;
|
||||||
struct wined3d_shader_signature signature;
|
|
||||||
struct wined3d_shader_desc desc;
|
struct wined3d_shader_desc desc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -1292,40 +1242,22 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr = validate_stream_output_entries(so_entries, so_entry_count,
|
||||||
|
buffer_strides, buffer_stride_count, device->feature_level)))
|
||||||
|
return hr;
|
||||||
|
|
||||||
desc.byte_code = byte_code;
|
desc.byte_code = byte_code;
|
||||||
desc.byte_code_size = byte_code_length;
|
desc.byte_code_size = byte_code_length;
|
||||||
|
|
||||||
memset(&so_desc, 0, sizeof(so_desc));
|
memset(&so_desc, 0, sizeof(so_desc));
|
||||||
if (so_entries)
|
if (so_entries)
|
||||||
{
|
{
|
||||||
|
so_desc.elements = (const struct wined3d_stream_output_element *)so_entries;
|
||||||
so_desc.element_count = so_entry_count;
|
so_desc.element_count = so_entry_count;
|
||||||
for (i = 0; i < min(buffer_stride_count, ARRAY_SIZE(so_desc.buffer_strides)); ++i)
|
for (i = 0; i < min(buffer_stride_count, ARRAY_SIZE(so_desc.buffer_strides)); ++i)
|
||||||
so_desc.buffer_strides[i] = buffer_strides[i];
|
so_desc.buffer_strides[i] = buffer_strides[i];
|
||||||
so_desc.buffer_stride_count = buffer_stride_count;
|
so_desc.buffer_stride_count = buffer_stride_count;
|
||||||
so_desc.rasterizer_stream_idx = rasterizer_stream;
|
so_desc.rasterizer_stream_idx = rasterizer_stream;
|
||||||
|
|
||||||
if (!(so_desc.elements = heap_calloc(so_entry_count, sizeof(*so_desc.elements))))
|
|
||||||
{
|
|
||||||
ERR("Failed to allocate wined3d stream output element array memory.\n");
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&signature, 0, sizeof(signature));
|
|
||||||
if (FAILED(hr = parse_dxbc(byte_code, byte_code_length, osgn_handler, &signature)))
|
|
||||||
{
|
|
||||||
ERR("Failed to parse input signature.\n");
|
|
||||||
heap_free(so_desc.elements);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
hr = wined3d_so_elements_from_d3d11_so_entries(so_desc.elements,
|
|
||||||
so_entries, so_entry_count, buffer_strides, buffer_stride_count,
|
|
||||||
&signature, device->feature_level);
|
|
||||||
shader_free_signature(&signature);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
heap_free(so_desc.elements);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
|
shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
|
||||||
|
@ -1334,10 +1266,8 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
wined3d_private_store_init(&shader->private_store);
|
wined3d_private_store_init(&shader->private_store);
|
||||||
|
|
||||||
hr = wined3d_shader_create_gs(device->wined3d_device, &desc, so_entries ? &so_desc : NULL,
|
if (FAILED(hr = wined3d_shader_create_gs(device->wined3d_device, &desc, so_entries ? &so_desc : NULL,
|
||||||
shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
|
shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader)))
|
||||||
heap_free(so_desc.elements);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
{
|
||||||
WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
|
WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
|
||||||
wined3d_private_store_cleanup(&shader->private_store);
|
wined3d_private_store_cleanup(&shader->private_store);
|
||||||
|
|
|
@ -818,9 +818,10 @@ static void append_transform_feedback_skip_components(const char **varyings,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3d_stream_output_desc *so_desc,
|
static BOOL shader_glsl_generate_transform_feedback_varyings(struct wined3d_string_buffer *buffer,
|
||||||
struct wined3d_string_buffer *buffer, const char **varyings, unsigned int *varying_count,
|
const char **varyings, unsigned int *varying_count,
|
||||||
char *strings, unsigned int *strings_length, GLenum buffer_mode)
|
char *strings, unsigned int *strings_length, GLenum buffer_mode,
|
||||||
|
const struct wined3d_stream_output_desc *so_desc, const unsigned int *output_register_idx)
|
||||||
{
|
{
|
||||||
unsigned int i, buffer_idx, count, length, highest_output_slot, stride;
|
unsigned int i, buffer_idx, count, length, highest_output_slot, stride;
|
||||||
BOOL have_varyings_to_record = FALSE;
|
BOOL have_varyings_to_record = FALSE;
|
||||||
|
@ -847,7 +848,7 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3
|
||||||
|
|
||||||
stride += e->component_count;
|
stride += e->component_count;
|
||||||
|
|
||||||
if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP)
|
if (!e->semantic_name)
|
||||||
{
|
{
|
||||||
append_transform_feedback_skip_components(varyings, &count,
|
append_transform_feedback_skip_components(varyings, &count,
|
||||||
&strings, &length, buffer, e->component_count);
|
&strings, &length, buffer, e->component_count);
|
||||||
|
@ -865,12 +866,12 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3
|
||||||
}
|
}
|
||||||
|
|
||||||
string_buffer_sprintf(buffer, "shader_in_out.reg%u_%u_%u",
|
string_buffer_sprintf(buffer, "shader_in_out.reg%u_%u_%u",
|
||||||
e->register_idx, e->component_idx, e->component_idx + e->component_count - 1);
|
output_register_idx[i], e->component_idx, e->component_idx + e->component_count - 1);
|
||||||
append_transform_feedback_varying(varyings, &count, &strings, &length, buffer);
|
append_transform_feedback_varying(varyings, &count, &strings, &length, buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string_buffer_sprintf(buffer, "shader_in_out.reg%u", e->register_idx);
|
string_buffer_sprintf(buffer, "shader_in_out.reg%u", output_register_idx[i]);
|
||||||
append_transform_feedback_varying(varyings, &count, &strings, &length, buffer);
|
append_transform_feedback_varying(varyings, &count, &strings, &length, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,6 +907,7 @@ static BOOL shader_glsl_generate_transform_feedback_varyings(const struct wined3
|
||||||
static void shader_glsl_init_transform_feedback(const struct wined3d_context *context,
|
static void shader_glsl_init_transform_feedback(const struct wined3d_context *context,
|
||||||
struct shader_glsl_priv *priv, GLuint program_id, struct wined3d_shader *shader)
|
struct shader_glsl_priv *priv, GLuint program_id, struct wined3d_shader *shader)
|
||||||
{
|
{
|
||||||
|
const unsigned int *output_register_idx = shader->u.gs.output_register_idx;
|
||||||
const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc;
|
const struct wined3d_stream_output_desc *so_desc = &shader->u.gs.so_desc;
|
||||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||||
struct wined3d_string_buffer *buffer;
|
struct wined3d_string_buffer *buffer;
|
||||||
|
@ -927,7 +929,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co
|
||||||
|
|
||||||
for (i = 0; i < so_desc->element_count; ++i)
|
for (i = 0; i < so_desc->element_count; ++i)
|
||||||
{
|
{
|
||||||
if (so_desc->elements[i].register_idx == WINED3D_STREAM_OUTPUT_GAP)
|
if (!so_desc->elements[i].semantic_name)
|
||||||
{
|
{
|
||||||
FIXME("ARB_transform_feedback3 is needed for stream output gaps.\n");
|
FIXME("ARB_transform_feedback3 is needed for stream output gaps.\n");
|
||||||
return;
|
return;
|
||||||
|
@ -960,7 +962,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co
|
||||||
|
|
||||||
buffer = string_buffer_get(&priv->string_buffers);
|
buffer = string_buffer_get(&priv->string_buffers);
|
||||||
|
|
||||||
if (!shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, NULL, &count, NULL, &length, mode))
|
if (!shader_glsl_generate_transform_feedback_varyings(buffer, NULL, &count, NULL, &length, mode, so_desc, output_register_idx))
|
||||||
{
|
{
|
||||||
FIXME("No varyings to record, disabling transform feedback.\n");
|
FIXME("No varyings to record, disabling transform feedback.\n");
|
||||||
shader->u.gs.so_desc.element_count = 0;
|
shader->u.gs.so_desc.element_count = 0;
|
||||||
|
@ -982,7 +984,7 @@ static void shader_glsl_init_transform_feedback(const struct wined3d_context *co
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_glsl_generate_transform_feedback_varyings(so_desc, buffer, varyings, NULL, strings, NULL, mode);
|
shader_glsl_generate_transform_feedback_varyings(buffer, varyings, NULL, strings, NULL, mode, so_desc, output_register_idx);
|
||||||
GL_EXTCALL(glTransformFeedbackVaryings(program_id, count, varyings, mode));
|
GL_EXTCALL(glTransformFeedbackVaryings(program_id, count, varyings, mode));
|
||||||
checkGLcall("glTransformFeedbackVaryings");
|
checkGLcall("glTransformFeedbackVaryings");
|
||||||
|
|
||||||
|
@ -7421,7 +7423,8 @@ static GLuint shader_glsl_generate_vs3_rasterizer_input_setup(struct shader_glsl
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *priv,
|
static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *priv,
|
||||||
const struct wined3d_shader *shader, const struct wined3d_stream_output_desc *so_desc)
|
const struct wined3d_shader *shader, const struct wined3d_stream_output_desc *so_desc,
|
||||||
|
const unsigned int *output_register_idx)
|
||||||
{
|
{
|
||||||
struct wined3d_string_buffer *buffer = &priv->shader_buffer;
|
struct wined3d_string_buffer *buffer = &priv->shader_buffer;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -7436,7 +7439,7 @@ static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *pr
|
||||||
FIXME("Unhandled stream %u.\n", e->stream_idx);
|
FIXME("Unhandled stream %u.\n", e->stream_idx);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP)
|
if (!e->semantic_name)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (e->component_idx || e->component_count != 4)
|
if (e->component_idx || e->component_count != 4)
|
||||||
|
@ -7446,11 +7449,11 @@ static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *pr
|
||||||
else
|
else
|
||||||
shader_addline(buffer, "vec%u", e->component_count);
|
shader_addline(buffer, "vec%u", e->component_count);
|
||||||
shader_addline(buffer, " reg%u_%u_%u;\n",
|
shader_addline(buffer, " reg%u_%u_%u;\n",
|
||||||
e->register_idx, e->component_idx, e->component_idx + e->component_count - 1);
|
output_register_idx[i], e->component_idx, e->component_idx + e->component_count - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shader_addline(buffer, "vec4 reg%u;\n", e->register_idx);
|
shader_addline(buffer, "vec4 reg%u;\n", output_register_idx[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shader_addline(buffer, "} shader_out;\n");
|
shader_addline(buffer, "} shader_out;\n");
|
||||||
|
@ -7466,7 +7469,7 @@ static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *pr
|
||||||
FIXME("Unhandled stream %u.\n", e->stream_idx);
|
FIXME("Unhandled stream %u.\n", e->stream_idx);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP)
|
if (!e->semantic_name)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (e->component_idx || e->component_count != 4)
|
if (e->component_idx || e->component_count != 4)
|
||||||
|
@ -7477,13 +7480,13 @@ static void shader_glsl_generate_stream_output_setup(struct shader_glsl_priv *pr
|
||||||
write_mask = ((1u << e->component_count) - 1) << e->component_idx;
|
write_mask = ((1u << e->component_count) - 1) << e->component_idx;
|
||||||
shader_glsl_write_mask_to_str(write_mask, str_mask);
|
shader_glsl_write_mask_to_str(write_mask, str_mask);
|
||||||
shader_addline(buffer, "shader_out.reg%u_%u_%u = outputs[%u]%s;\n",
|
shader_addline(buffer, "shader_out.reg%u_%u_%u = outputs[%u]%s;\n",
|
||||||
e->register_idx, e->component_idx, e->component_idx + e->component_count - 1,
|
output_register_idx[i], e->component_idx, e->component_idx + e->component_count - 1,
|
||||||
e->register_idx, str_mask);
|
output_register_idx[i], str_mask);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shader_addline(buffer, "shader_out.reg%u = outputs[%u];\n",
|
shader_addline(buffer, "shader_out.reg%u = outputs[%u];\n",
|
||||||
e->register_idx, e->register_idx);
|
output_register_idx[i], output_register_idx[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shader_addline(buffer, "}\n");
|
shader_addline(buffer, "}\n");
|
||||||
|
@ -8529,7 +8532,8 @@ static GLuint shader_glsl_generate_geometry_shader(const struct wined3d_context
|
||||||
|
|
||||||
if (is_rasterization_disabled(shader))
|
if (is_rasterization_disabled(shader))
|
||||||
{
|
{
|
||||||
shader_glsl_generate_stream_output_setup(priv, shader, &shader->u.gs.so_desc);
|
shader_glsl_generate_stream_output_setup(priv, shader,
|
||||||
|
&shader->u.gs.so_desc, shader->u.gs.output_register_idx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -3144,7 +3144,8 @@ static void shader_cleanup(struct wined3d_shader *shader)
|
||||||
}
|
}
|
||||||
else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
|
else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
|
||||||
{
|
{
|
||||||
heap_free(shader->u.gs.so_desc.elements);
|
heap_free((void *)shader->u.gs.so_desc.elements);
|
||||||
|
heap_free(shader->u.gs.output_register_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_free(shader->patch_constant_signature.elements);
|
heap_free(shader->patch_constant_signature.elements);
|
||||||
|
@ -3728,12 +3729,31 @@ static HRESULT vertex_shader_init(struct wined3d_shader *shader, struct wined3d_
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s,
|
||||||
|
unsigned int stream_idx, const char *semantic_name, unsigned int semantic_idx)
|
||||||
|
{
|
||||||
|
struct wined3d_shader_signature_element *e = s->elements;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < s->element_count; ++i)
|
||||||
|
{
|
||||||
|
if (e[i].stream_idx == stream_idx
|
||||||
|
&& !strcasecmp(e[i].semantic_name, semantic_name)
|
||||||
|
&& e[i].semantic_idx == semantic_idx)
|
||||||
|
return &e[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader,
|
static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader,
|
||||||
const struct wined3d_stream_output_desc *so_desc)
|
const struct wined3d_stream_output_desc *so_desc)
|
||||||
{
|
{
|
||||||
const struct wined3d_shader_frontend *fe = shader->frontend;
|
const struct wined3d_shader_frontend *fe = shader->frontend;
|
||||||
|
const struct wined3d_shader_signature_element *output;
|
||||||
struct wined3d_stream_output_element *elements;
|
struct wined3d_stream_output_element *elements;
|
||||||
struct wined3d_shader_version shader_version;
|
struct wined3d_shader_version shader_version;
|
||||||
|
unsigned int i, j, mask;
|
||||||
const DWORD *ptr;
|
const DWORD *ptr;
|
||||||
void *fe_data;
|
void *fe_data;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -3772,6 +3792,9 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader,
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(shader->u.gs.output_register_idx = heap_calloc(so_desc->element_count, sizeof(*shader->u.gs.output_register_idx))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (!(elements = heap_calloc(so_desc->element_count, sizeof(*elements))))
|
if (!(elements = heap_calloc(so_desc->element_count, sizeof(*elements))))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
@ -3779,6 +3802,38 @@ static HRESULT geometry_shader_init_stream_output(struct wined3d_shader *shader,
|
||||||
shader->u.gs.so_desc.elements = elements;
|
shader->u.gs.so_desc.elements = elements;
|
||||||
memcpy(elements, so_desc->elements, so_desc->element_count * sizeof(*elements));
|
memcpy(elements, so_desc->elements, so_desc->element_count * sizeof(*elements));
|
||||||
|
|
||||||
|
for (i = 0; i < so_desc->element_count; ++i)
|
||||||
|
{
|
||||||
|
struct wined3d_stream_output_element *e = &elements[i];
|
||||||
|
|
||||||
|
if (!e->semantic_name)
|
||||||
|
continue;
|
||||||
|
if (!(output = shader_find_signature_element(&shader->output_signature,
|
||||||
|
e->stream_idx, e->semantic_name, e->semantic_idx)))
|
||||||
|
{
|
||||||
|
WARN("Failed to find output signature element for stream output entry.\n");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
e->semantic_name = output->semantic_name;
|
||||||
|
shader->u.gs.output_register_idx[i] = output->register_idx;
|
||||||
|
|
||||||
|
for (j = 0; j < 4; ++j)
|
||||||
|
{
|
||||||
|
if ((1u << j) & output->mask)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
e->component_idx += j;
|
||||||
|
|
||||||
|
mask = ((1u << e->component_count) - 1) << e->component_idx;
|
||||||
|
if ((output->mask & 0xff & mask) != mask)
|
||||||
|
{
|
||||||
|
WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n",
|
||||||
|
e->component_idx, e->component_count, mask, output->mask & 0xff);
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4198,6 +4198,7 @@ struct wined3d_geometry_shader
|
||||||
unsigned int instance_count;
|
unsigned int instance_count;
|
||||||
|
|
||||||
struct wined3d_stream_output_desc so_desc;
|
struct wined3d_stream_output_desc so_desc;
|
||||||
|
unsigned int *output_register_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wined3d_pixel_shader
|
struct wined3d_pixel_shader
|
||||||
|
|
|
@ -1574,7 +1574,6 @@ enum wined3d_shader_type
|
||||||
#define WINED3D_OUTPUT_SLOT_UNUSED 0xfffffffe
|
#define WINED3D_OUTPUT_SLOT_UNUSED 0xfffffffe
|
||||||
|
|
||||||
#define WINED3D_MAX_STREAM_OUTPUT_BUFFERS 4
|
#define WINED3D_MAX_STREAM_OUTPUT_BUFFERS 4
|
||||||
#define WINED3D_STREAM_OUTPUT_GAP 0xffffffff
|
|
||||||
#define WINED3D_NO_RASTERIZER_STREAM 0xffffffff
|
#define WINED3D_NO_RASTERIZER_STREAM 0xffffffff
|
||||||
|
|
||||||
#define WINED3D_VIEW_BUFFER_RAW 0x00000001
|
#define WINED3D_VIEW_BUFFER_RAW 0x00000001
|
||||||
|
@ -2060,7 +2059,8 @@ struct wined3d_shader_desc
|
||||||
struct wined3d_stream_output_element
|
struct wined3d_stream_output_element
|
||||||
{
|
{
|
||||||
unsigned int stream_idx;
|
unsigned int stream_idx;
|
||||||
unsigned int register_idx;
|
const char *semantic_name;
|
||||||
|
unsigned int semantic_idx;
|
||||||
BYTE component_idx;
|
BYTE component_idx;
|
||||||
BYTE component_count;
|
BYTE component_count;
|
||||||
BYTE output_slot;
|
BYTE output_slot;
|
||||||
|
@ -2068,7 +2068,7 @@ struct wined3d_stream_output_element
|
||||||
|
|
||||||
struct wined3d_stream_output_desc
|
struct wined3d_stream_output_desc
|
||||||
{
|
{
|
||||||
struct wined3d_stream_output_element *elements;
|
const struct wined3d_stream_output_element *elements;
|
||||||
unsigned int element_count;
|
unsigned int element_count;
|
||||||
unsigned int buffer_strides[WINED3D_MAX_STREAM_OUTPUT_BUFFERS];
|
unsigned int buffer_strides[WINED3D_MAX_STREAM_OUTPUT_BUFFERS];
|
||||||
unsigned int buffer_stride_count;
|
unsigned int buffer_stride_count;
|
||||||
|
|
Loading…
Reference in New Issue