=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: d3d11: Validate stream output description.
Alexandre Julliard
julliard at winehq.org
Tue Mar 28 15:38:42 CDT 2017
Module: wine
Branch: master
Commit: 958f2d634d3abc6b40589349b1845d5c7895de49
URL: http://source.winehq.org/git/wine.git/?a=commit;h=958f2d634d3abc6b40589349b1845d5c7895de49
Author: Józef Kucia <jkucia at codeweavers.com>
Date: Tue Mar 28 12:00:03 2017 +0200
d3d11: Validate stream output description.
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/d3d11/device.c | 3 ++
dlls/d3d11/shader.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 87 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 515da0e..6d230ee 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -2498,7 +2498,10 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateGeometryShaderWithStreamOutp
if (FAILED(hr = d3d_geometry_shader_create(device, byte_code, byte_code_length,
so_entries, entry_count, buffer_strides, strides_count, rasterizer_stream, &object)))
+ {
+ *shader = NULL;
return hr;
+ }
*shader = &object->ID3D11GeometryShader_iface;
diff --git a/dlls/d3d11/shader.c b/dlls/d3d11/shader.c
index 3025a1c..4105fd3 100644
--- a/dlls/d3d11/shader.c
+++ b/dlls/d3d11/shader.c
@@ -1205,6 +1205,22 @@ static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_o
f->Stream, debugstr_a(f->SemanticName), f->SemanticIndex,
f->StartComponent, f->ComponentCount, f->OutputSlot);
+ if (f->Stream >= D3D11_SO_STREAM_COUNT)
+ {
+ WARN("Invalid stream %u.\n", f->Stream);
+ return E_INVALIDARG;
+ }
+ if (f->Stream)
+ {
+ FIXME("Streams not implemented yet.\n");
+ return E_INVALIDARG;
+ }
+ if (f->OutputSlot >= D3D11_SO_BUFFER_SLOT_COUNT)
+ {
+ WARN("Invalid output slot %u.\n", f->OutputSlot);
+ return E_INVALIDARG;
+ }
+
e->stream_idx = f->Stream;
e->component_idx = f->StartComponent;
e->component_count = f->ComponentCount;
@@ -1212,11 +1228,22 @@ static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_o
if (!f->SemanticName)
{
+ if (f->SemanticIndex)
+ {
+ WARN("Invalid semantic idx %u for stream output gap.\n", f->SemanticIndex);
+ return E_INVALIDARG;
+ }
+ if (e->component_idx || !e->component_count)
+ {
+ WARN("Invalid stream output gap %u-%u.\n", e->component_idx, e->component_count);
+ return E_INVALIDARG;
+ }
+
e->register_idx = WINED3D_STREAM_OUTPUT_GAP;
}
else if ((output = shader_find_signature_element(os, f->SemanticName, f->SemanticIndex)))
{
- if (e->component_idx > 3 || e->component_count > 4
+ if (e->component_idx > 3 || e->component_count > 4 || !e->component_count
|| e->component_idx + e->component_count > 4)
{
WARN("Invalid component range %u-%u.\n", e->component_idx, e->component_count);
@@ -1248,6 +1275,52 @@ static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_o
}
}
+ for (i = 0; i < entry_count; ++i)
+ {
+ const struct wined3d_stream_output_element *e1 = &elements[i];
+ if (e1->register_idx == WINED3D_STREAM_OUTPUT_GAP)
+ continue;
+
+ for (j = i + 1; j < entry_count; ++j)
+ {
+ const struct wined3d_stream_output_element *e2 = &elements[j];
+
+ if (e1->register_idx == e2->register_idx
+ && e1->component_idx < e2->component_idx + e2->component_count
+ && e1->component_idx + e1->component_count > e2->component_idx)
+ {
+ WARN("Stream output elements %u and %u overlap.\n", i, j);
+ return E_INVALIDARG;
+ }
+ }
+ }
+
+ for (i = 0; i < D3D11_SO_STREAM_COUNT; ++i)
+ {
+ BOOL has_element[D3D11_SO_BUFFER_SLOT_COUNT] = {FALSE};
+ BOOL is_used[D3D11_SO_BUFFER_SLOT_COUNT] = {FALSE};
+
+ for (j = 0; j < entry_count; ++j)
+ {
+ const struct wined3d_stream_output_element *e = &elements[j];
+
+ if (e->stream_idx != i)
+ continue;
+ is_used[e->output_slot] = TRUE;
+ if (e->register_idx != WINED3D_STREAM_OUTPUT_GAP)
+ has_element[e->output_slot] = TRUE;
+ }
+
+ for (j = 0; j < D3D11_SO_BUFFER_SLOT_COUNT; ++j)
+ {
+ if (is_used[j] && !has_element[j])
+ {
+ WARN("Stream %u, output slot %u contains only gaps.\n", i, j);
+ return E_INVALIDARG;
+ }
+ }
+ }
+
return S_OK;
}
@@ -1268,6 +1341,16 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
so_entry_count, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT);
return E_INVALIDARG;
}
+ if (so_entries && !so_entry_count)
+ {
+ WARN("Invalid SO entry count %u.\n", so_entry_count);
+ return E_INVALIDARG;
+ }
+ if (rasterizer_stream != D3D11_SO_NO_RASTERIZED_STREAM && rasterizer_stream >= D3D11_SO_STREAM_COUNT)
+ {
+ WARN("Invalid rasterizer stream %u.\n", rasterizer_stream);
+ return E_INVALIDARG;
+ }
if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
{
More information about the wine-cvs
mailing list