d3d11: Implement d3d11_device_CreateGeometryShaderWithStreamOutput().
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
7583bcfc22
commit
acd7d2e09a
@ -37,6 +37,10 @@
|
||||
#include "wine/winedxgi.h"
|
||||
#include "wine/rbtree.h"
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#endif
|
||||
|
||||
#define MAKE_TAG(ch0, ch1, ch2, ch3) \
|
||||
((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \
|
||||
((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 ))
|
||||
@ -316,6 +320,8 @@ struct d3d_geometry_shader
|
||||
};
|
||||
|
||||
HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
|
||||
const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count,
|
||||
const unsigned int *buffer_strides, unsigned int buffer_stride_count, unsigned int rasterizer_stream,
|
||||
struct d3d_geometry_shader **shader) DECLSPEC_HIDDEN;
|
||||
struct d3d_geometry_shader *unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface) DECLSPEC_HIDDEN;
|
||||
struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface) DECLSPEC_HIDDEN;
|
||||
|
@ -2476,7 +2476,8 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateGeometryShader(ID3D11Device
|
||||
if (class_linkage)
|
||||
FIXME("Class linkage is not implemented yet.\n");
|
||||
|
||||
if (FAILED(hr = d3d_geometry_shader_create(device, byte_code, byte_code_length, &object)))
|
||||
if (FAILED(hr = d3d_geometry_shader_create(device, byte_code, byte_code_length,
|
||||
NULL, 0, NULL, 0, 0, &object)))
|
||||
return hr;
|
||||
|
||||
*shader = &object->ID3D11GeometryShader_iface;
|
||||
@ -2486,15 +2487,28 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateGeometryShader(ID3D11Device
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d3d11_device_CreateGeometryShaderWithStreamOutput(ID3D11Device *iface,
|
||||
const void *byte_code, SIZE_T byte_code_length, const D3D11_SO_DECLARATION_ENTRY *so_entries,
|
||||
UINT entry_count, const UINT *buffer_strides, UINT strides_count, UINT rasterized_stream,
|
||||
UINT entry_count, const UINT *buffer_strides, UINT strides_count, UINT rasterizer_stream,
|
||||
ID3D11ClassLinkage *class_linkage, ID3D11GeometryShader **shader)
|
||||
{
|
||||
FIXME("iface %p, byte_code %p, byte_code_length %lu, so_entries %p, entry_count %u, "
|
||||
"buffer_strides %p, strides_count %u, rasterized_stream %u, class_linkage %p, shader %p stub!\n",
|
||||
iface, byte_code, byte_code_length, so_entries, entry_count, buffer_strides, strides_count,
|
||||
rasterized_stream, class_linkage, shader);
|
||||
struct d3d_device *device = impl_from_ID3D11Device(iface);
|
||||
struct d3d_geometry_shader *object;
|
||||
HRESULT hr;
|
||||
|
||||
return E_NOTIMPL;
|
||||
TRACE("iface %p, byte_code %p, byte_code_length %lu, so_entries %p, entry_count %u, "
|
||||
"buffer_strides %p, strides_count %u, rasterizer_stream %u, class_linkage %p, shader %p.\n",
|
||||
iface, byte_code, byte_code_length, so_entries, entry_count, buffer_strides, strides_count,
|
||||
rasterizer_stream, class_linkage, shader);
|
||||
|
||||
if (class_linkage)
|
||||
FIXME("Class linkage is not implemented yet.\n");
|
||||
|
||||
if (FAILED(hr = d3d_geometry_shader_create(device, byte_code, byte_code_length,
|
||||
so_entries, entry_count, buffer_strides, strides_count, rasterizer_stream, &object)))
|
||||
return hr;
|
||||
|
||||
*shader = &object->ID3D11GeometryShader_iface;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d3d11_device_CreatePixelShader(ID3D11Device *iface, const void *byte_code,
|
||||
@ -4892,7 +4906,8 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShader(ID3D10Device1
|
||||
TRACE("iface %p, byte_code %p, byte_code_length %lu, shader %p.\n",
|
||||
iface, byte_code, byte_code_length, shader);
|
||||
|
||||
if (FAILED(hr = d3d_geometry_shader_create(device, byte_code, byte_code_length, &object)))
|
||||
if (FAILED(hr = d3d_geometry_shader_create(device, byte_code, byte_code_length,
|
||||
NULL, 0, NULL, 0, 0, &object)))
|
||||
return hr;
|
||||
|
||||
*shader = &object->ID3D10GeometryShader_iface;
|
||||
|
@ -1188,29 +1188,107 @@ static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops =
|
||||
d3d_geometry_shader_wined3d_object_destroyed,
|
||||
};
|
||||
|
||||
static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, struct d3d_device *device,
|
||||
const void *byte_code, SIZE_T byte_code_length)
|
||||
static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_output_element *elements,
|
||||
const D3D11_SO_DECLARATION_ENTRY *entries, unsigned int entry_count,
|
||||
const struct wined3d_shader_signature *os)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < entry_count; ++i)
|
||||
{
|
||||
struct wined3d_stream_output_element *e = &elements[i];
|
||||
const D3D11_SO_DECLARATION_ENTRY *f = &entries[i];
|
||||
struct wined3d_shader_signature_element *element;
|
||||
|
||||
TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
|
||||
"component count %u, output slot %u.\n",
|
||||
f->Stream, debugstr_a(f->SemanticName), f->SemanticIndex,
|
||||
f->StartComponent, f->ComponentCount, f->OutputSlot);
|
||||
|
||||
e->stream_idx = f->Stream;
|
||||
e->component_idx = f->StartComponent;
|
||||
e->component_count = f->ComponentCount;
|
||||
e->output_slot = f->OutputSlot;
|
||||
|
||||
if (!f->SemanticName)
|
||||
{
|
||||
e->register_idx = WINED3D_STREAM_OUTPUT_GAP;
|
||||
}
|
||||
else if ((element = shader_find_signature_element(os, f->SemanticName, f->SemanticIndex)))
|
||||
{
|
||||
e->register_idx = element->register_idx;
|
||||
TRACE("Register idx: %u.\n", e->register_idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("Failed to find output signature element for stream output entry.\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
|
||||
struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
|
||||
const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count,
|
||||
const unsigned int *buffer_strides, unsigned int buffer_stride_count,
|
||||
unsigned int rasterizer_stream)
|
||||
{
|
||||
struct wined3d_stream_output_desc so_desc;
|
||||
struct wined3d_shader_desc desc;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
if (so_entry_count > D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT)
|
||||
{
|
||||
WARN("Entry count %u is greater than %u.\n",
|
||||
so_entry_count, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
|
||||
{
|
||||
WARN("Failed to extract shader, hr %#x.\n", hr);
|
||||
return hr;
|
||||
}
|
||||
desc.max_version = d3d_sm_from_feature_level(device->feature_level);
|
||||
|
||||
memset(&so_desc, 0, sizeof(so_desc));
|
||||
if (so_entries)
|
||||
{
|
||||
so_desc.element_count = so_entry_count;
|
||||
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_stride_count = buffer_stride_count;
|
||||
so_desc.rasterizer_stream_idx = rasterizer_stream;
|
||||
|
||||
if (!(so_desc.elements = d3d11_calloc(so_entry_count, sizeof(*so_desc.elements))))
|
||||
{
|
||||
ERR("Failed to allocate wined3d stream output element array memory.\n");
|
||||
shader_free_signature(&desc.input_signature);
|
||||
shader_free_signature(&desc.output_signature);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (FAILED(hr = wined3d_so_elements_from_d3d11_so_entries(so_desc.elements,
|
||||
so_entries, so_entry_count, &desc.output_signature)))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, so_desc.elements);
|
||||
shader_free_signature(&desc.input_signature);
|
||||
shader_free_signature(&desc.output_signature);
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
|
||||
shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl;
|
||||
shader->refcount = 1;
|
||||
wined3d_mutex_lock();
|
||||
wined3d_private_store_init(&shader->private_store);
|
||||
|
||||
if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
|
||||
{
|
||||
WARN("Failed to extract shader, hr %#x.\n", hr);
|
||||
wined3d_private_store_cleanup(&shader->private_store);
|
||||
wined3d_mutex_unlock();
|
||||
return hr;
|
||||
}
|
||||
desc.max_version = d3d_sm_from_feature_level(device->feature_level);
|
||||
|
||||
hr = wined3d_shader_create_gs(device->wined3d_device, &desc, NULL, shader,
|
||||
&d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
|
||||
hr = wined3d_shader_create_gs(device->wined3d_device, &desc, so_entries ? &so_desc : NULL,
|
||||
shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
|
||||
HeapFree(GetProcessHeap(), 0, so_desc.elements);
|
||||
shader_free_signature(&desc.input_signature);
|
||||
shader_free_signature(&desc.output_signature);
|
||||
if (FAILED(hr))
|
||||
@ -1229,6 +1307,8 @@ static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, stru
|
||||
}
|
||||
|
||||
HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
|
||||
const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count,
|
||||
const unsigned int *buffer_strides, unsigned int buffer_stride_count, unsigned int rasterizer_stream,
|
||||
struct d3d_geometry_shader **shader)
|
||||
{
|
||||
struct d3d_geometry_shader *object;
|
||||
@ -1237,7 +1317,8 @@ HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_c
|
||||
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length)))
|
||||
if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length,
|
||||
so_entries, so_entry_count, buffer_strides, buffer_stride_count, rasterizer_stream)))
|
||||
{
|
||||
WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
|
||||
HeapFree(GetProcessHeap(), 0, object);
|
||||
|
@ -11448,8 +11448,7 @@ static void test_index_buffer_offset(void)
|
||||
hr = ID3D11Device_CreateGeometryShaderWithStreamOutput(device, gs_code, sizeof(gs_code),
|
||||
so_declaration, sizeof(so_declaration) / sizeof(*so_declaration),
|
||||
&stride, 1, D3D11_SO_NO_RASTERIZED_STREAM, NULL, &gs);
|
||||
todo_wine ok(SUCCEEDED(hr), "Failed to create geometry shader with stream output, hr %#x.\n", hr);
|
||||
if (FAILED(hr)) goto cleanup;
|
||||
ok(SUCCEEDED(hr), "Failed to create geometry shader with stream output, hr %#x.\n", hr);
|
||||
|
||||
hr = ID3D11Device_CreateVertexShader(device, vs_code, sizeof(vs_code), NULL, &vs);
|
||||
ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
|
||||
@ -11483,6 +11482,7 @@ static void test_index_buffer_offset(void)
|
||||
for (i = 0; i < sizeof(expected_data) / sizeof(*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",
|
||||
@ -11495,7 +11495,6 @@ static void test_index_buffer_offset(void)
|
||||
ID3D11Buffer_Release(vb);
|
||||
ID3D11VertexShader_Release(vs);
|
||||
ID3D11GeometryShader_Release(gs);
|
||||
cleanup:
|
||||
ID3D11InputLayout_Release(input_layout);
|
||||
release_test_context(&test_context);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user