[PATCH 4/7] wined3d: Add initial support for shader buffer views.
Józef Kucia
jkucia at codeweavers.com
Thu Mar 24 07:54:40 CDT 2016
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
Tests can still be run with forced SM4.
---
dlls/d3d10core/tests/device.c | 32 +++++++++++++++++-
dlls/d3d11/tests/d3d11.c | 8 +++++
dlls/wined3d/context.c | 18 +++++-----
dlls/wined3d/view.c | 76 +++++++++++++++++++++++++++++++++++++++---
dlls/wined3d/wined3d_private.h | 3 ++
5 files changed, 123 insertions(+), 14 deletions(-)
diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c
index ba6f22e..9a87945 100644
--- a/dlls/d3d10core/tests/device.c
+++ b/dlls/d3d10core/tests/device.c
@@ -1394,6 +1394,13 @@ static void test_create_shader_resource_view(void)
expected_refcount = get_refcount((IUnknown *)device) + 1;
hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)buffer, &srv_desc, &srview);
+ /* FIXME: Remove the following if statement once core contexts are supported. */
+ if (hr == E_NOTIMPL)
+ {
+ skip("Buffer resource views are not supported.\n");
+ }
+ else
+ {
ok(SUCCEEDED(hr), "Failed to create a shader resource view, hr %#x\n", hr);
refcount = get_refcount((IUnknown *)device);
ok(refcount >= expected_refcount, "Got unexpected refcount %u, expected >= %u.\n", refcount, expected_refcount);
@@ -1415,6 +1422,7 @@ static void test_create_shader_resource_view(void)
if (SUCCEEDED(hr)) IUnknown_Release(iface);
ID3D10ShaderResourceView_Release(srview);
+ }
ID3D10Buffer_Release(buffer);
texture_desc.Width = 512;
@@ -2551,7 +2559,6 @@ float4 main(float4 color : COLOR) : SV_TARGET
ID3D10BlendState *tmp_blend_state, *blend_state;
ID3D10RasterizerState *tmp_rs_state, *rs_state;
ID3D10Predicate *tmp_predicate, *predicate;
- D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
ID3D10DepthStencilView *tmp_dsv, *dsv;
D3D10_PRIMITIVE_TOPOLOGY topology;
D3D10_TEXTURE2D_DESC texture_desc;
@@ -2563,6 +2570,7 @@ float4 main(float4 color : COLOR) : SV_TARGET
ID3D10PixelShader *tmp_ps, *ps;
D3D10_RASTERIZER_DESC rs_desc;
D3D10_BUFFER_DESC buffer_desc;
+ ID3D10Texture2D *srv_texture;
D3D10_BLEND_DESC blend_desc;
ID3D10Texture2D *ds_texture;
float tmp_blend_factor[4];
@@ -2742,6 +2750,7 @@ float4 main(float4 color : COLOR) : SV_TARGET
ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
}
+ /* FIXME: Revert back to buffer views once core contexts are supported.
srv_desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_BUFFER;
U(srv_desc).Buffer.ElementOffset = 0;
@@ -2753,6 +2762,25 @@ float4 main(float4 color : COLOR) : SV_TARGET
(ID3D10Resource *)buffer[i % D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT], &srv_desc, &srv[i]);
ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x.\n", hr);
}
+ */
+ texture_desc.Width = 512;
+ texture_desc.Height = 512;
+ texture_desc.MipLevels = 1;
+ texture_desc.ArraySize = 1;
+ texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ texture_desc.SampleDesc.Count = 1;
+ texture_desc.SampleDesc.Quality = 0;
+ texture_desc.Usage = D3D10_USAGE_DEFAULT;
+ texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
+ texture_desc.CPUAccessFlags = 0;
+ texture_desc.MiscFlags = 0;
+ hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &srv_texture);
+ ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
+ for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i)
+ {
+ hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)srv_texture, NULL, &srv[i]);
+ ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x.\n", hr);
+ }
sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
sampler_desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
@@ -3292,6 +3320,8 @@ float4 main(float4 color : COLOR) : SV_TARGET
ID3D10GeometryShader_Release(gs);
ID3D10PixelShader_Release(ps);
+ ID3D10Texture2D_Release(srv_texture);
+
for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
{
ID3D10SamplerState_Release(sampler[i]);
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 9348aff..713496b 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -1858,6 +1858,13 @@ static void test_create_shader_resource_view(void)
expected_refcount = get_refcount((IUnknown *)device) + 1;
hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)buffer, &srv_desc, &srview);
+ /* FIXME: Remove the following if statement once core contexts are supported. */
+ if (hr == E_NOTIMPL)
+ {
+ skip("Buffer resource views are not supported.\n");
+ }
+ else
+ {
ok(SUCCEEDED(hr), "Failed to create a shader resource view, hr %#x.\n", hr);
refcount = get_refcount((IUnknown *)device);
ok(refcount >= expected_refcount, "Got unexpected refcount %u, expected >= %u.\n", refcount, expected_refcount);
@@ -1879,6 +1886,7 @@ static void test_create_shader_resource_view(void)
if (SUCCEEDED(hr)) IUnknown_Release(iface);
ID3D11ShaderResourceView_Release(srview);
+ }
ID3D11Buffer_Release(buffer);
texture_desc.Width = 512;
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 8ae3e32..29f109e 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -3303,12 +3303,6 @@ static void context_bind_shader_resources(struct wined3d_context *context, const
continue;
}
- if (view->resource->type == WINED3D_RTYPE_BUFFER)
- {
- FIXME("Buffer shader resources not supported.\n");
- continue;
- }
-
if (entry->sampler_idx == WINED3D_SAMPLER_DEFAULT)
{
sampler_name = device->default_sampler;
@@ -3323,9 +3317,17 @@ static void context_bind_shader_resources(struct wined3d_context *context, const
continue;
}
- texture = wined3d_texture_from_resource(view->resource);
context_active_texture(context, gl_info, shader_types[i].base_idx + entry->bind_idx);
- wined3d_texture_bind(texture, context, FALSE);
+
+ if (view->resource->type == WINED3D_RTYPE_BUFFER)
+ {
+ context_bind_texture(context, view->target, view->object);
+ }
+ else
+ {
+ texture = wined3d_texture_from_resource(view->resource);
+ wined3d_texture_bind(texture, context, FALSE);
+ }
GL_EXTCALL(glBindSampler(shader_types[i].base_idx + entry->bind_idx, sampler_name));
checkGLcall("glBindSampler");
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 246d8cd..73baf61 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -182,6 +182,12 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v
/* Call wined3d_object_destroyed() before releasing the resource,
* since releasing the resource may end up destroying the parent. */
view->parent_ops->wined3d_object_destroyed(view->parent);
+ if (view->object)
+ {
+ struct wined3d_context *context = context_acquire(view->resource->device, NULL);
+ context->gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->object);
+ context_release(context);
+ }
wined3d_resource_decref(view->resource);
HeapFree(GetProcessHeap(), 0, view);
}
@@ -196,11 +202,71 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader
return view->parent;
}
+static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_view *view,
+ const struct wined3d_shader_resource_view_desc *desc, struct wined3d_resource *resource,
+ void *parent, const struct wined3d_parent_ops *parent_ops)
+{
+ view->refcount = 1;
+ view->resource = resource;
+ view->parent = parent;
+ view->parent_ops = parent_ops;
+
+ if (resource->type == WINED3D_RTYPE_BUFFER)
+ {
+ struct wined3d_context *context = context_acquire(resource->device, NULL);
+ struct wined3d_buffer *buffer = buffer_from_resource(resource);
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ const struct wined3d_format *format;
+ struct wined3d_bo_address bo;
+
+ if (!gl_info->supported[ARB_TEXTURE_BUFFER_OBJECT])
+ {
+ FIXME("No hardware support for buffer textures.\n");
+ context_release(context);
+ return E_NOTIMPL;
+ }
+
+ format = wined3d_get_format(gl_info, desc->format_id);
+
+ buffer_get_memory(buffer, context, &bo);
+ if (!bo.buffer_object)
+ {
+ FIXME("Could not get buffer object for buffer %p.\n", buffer);
+ context_release(context);
+ return E_NOTIMPL;
+ }
+ /* Support for buffer offsets can be implemented using ARB_texture_buffer_range. */
+ if (bo.addr)
+ FIXME("Ignoring buffer offset %p.\n", bo.addr);
+
+ view->target = GL_TEXTURE_BUFFER;
+ gl_info->gl_ops.gl.p_glGenTextures(1, &view->object);
+ checkGLcall("glGenTextures");
+
+ context_bind_texture(context, GL_TEXTURE_BUFFER, view->object);
+ GL_EXTCALL(glTexBuffer(GL_TEXTURE_BUFFER, format->glInternal, bo.buffer_object));
+ checkGLcall("glTexBuffer");
+
+ context_invalidate_state(context, STATE_SHADER_RESOURCE_BINDING);
+
+ context_release(context);
+ }
+ else
+ {
+ view->target = GL_NONE;
+ view->object = 0;
+ }
+
+ wined3d_resource_incref(resource);
+ return WINED3D_OK;
+}
+
HRESULT CDECL wined3d_shader_resource_view_create(const struct wined3d_shader_resource_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_shader_resource_view **view)
{
struct wined3d_shader_resource_view *object;
+ HRESULT hr;
TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n",
desc, resource, parent, parent_ops, view);
@@ -208,11 +274,11 @@ HRESULT CDECL wined3d_shader_resource_view_create(const struct wined3d_shader_re
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
return E_OUTOFMEMORY;
- object->refcount = 1;
- object->resource = resource;
- wined3d_resource_incref(resource);
- object->parent = parent;
- object->parent_ops = parent_ops;
+ if (FAILED(hr = wined3d_shader_resource_view_init(object, desc, resource, parent, parent_ops)))
+ {
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
TRACE("Created shader resource view %p.\n", object);
*view = object;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index dc4330f..4a96ce8 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2944,6 +2944,9 @@ struct wined3d_shader_resource_view
struct wined3d_resource *resource;
void *parent;
const struct wined3d_parent_ops *parent_ops;
+
+ GLenum target;
+ GLuint object;
};
struct wined3d_swapchain_ops
--
2.4.10
More information about the wine-patches
mailing list