wined3d: Create texture views for shader resource views.

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:
Józef Kucia 2016-06-07 13:24:39 +02:00 committed by Alexandre Julliard
parent 2a5b4fd884
commit e86693f956
4 changed files with 168 additions and 15 deletions

View File

@ -3292,7 +3292,6 @@ static void context_bind_shader_resources(struct wined3d_context *context, const
struct wined3d_shader_sampler_map_entry *entry;
struct wined3d_shader_resource_view *view;
struct wined3d_sampler *sampler;
struct wined3d_texture *texture;
struct wined3d_shader *shader;
unsigned int i, j, count;
GLuint sampler_name;
@ -3332,12 +3331,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;
else if ((sampler = state->sampler[shader_types[i].type][entry->sampler_idx]))
@ -3345,12 +3338,10 @@ static void context_bind_shader_resources(struct wined3d_context *context, const
else
sampler_name = device->null_sampler;
texture = 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);
GL_EXTCALL(glBindSampler(shader_types[i].base_idx + entry->bind_idx, sampler_name));
checkGLcall("glBindSampler");
wined3d_shader_resource_view_bind(view, context);
}
}
}

View File

@ -1667,6 +1667,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
format->block_width = typeless_format->block_width;
format->block_height = typeless_format->block_height;
format->block_byte_count = typeless_format->block_byte_count;
format->typeless_id = typeless_format->id;
for (j = 0; j < strlen(typed_formats[i].channels); ++j)
{

View File

@ -185,6 +185,17 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v
if (!refcount)
{
if (view->object)
{
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
context = context_acquire(view->resource->device, NULL);
gl_info = context->gl_info;
gl_info->gl_ops.gl.p_glDeleteTextures(1, &view->object);
checkGLcall("glDeleteTextures");
context_release(context);
}
/* 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);
@ -202,11 +213,132 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader
return view->parent;
}
static void wined3d_shader_resource_view_create_texture_view(struct wined3d_shader_resource_view *view,
const struct wined3d_shader_resource_view_desc *desc, struct wined3d_texture *texture,
const struct wined3d_format *view_format)
{
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
struct gl_texture *gl_texture;
context = context_acquire(texture->resource.device, NULL);
gl_info = context->gl_info;
if (!gl_info->supported[ARB_TEXTURE_VIEW])
{
context_release(context);
FIXME("OpenGL implementation does not support texture views.\n");
return;
}
wined3d_texture_prepare_texture(texture, context, FALSE);
gl_texture = wined3d_texture_get_gl_texture(texture, FALSE);
gl_info->gl_ops.gl.p_glGenTextures(1, &view->object);
GL_EXTCALL(glTextureView(view->object, view->target, gl_texture->name, view_format->glInternal,
desc->u.texture.level_idx, desc->u.texture.level_count,
desc->u.texture.layer_idx, desc->u.texture.layer_count));
checkGLcall("Create texture view");
context_release(context);
}
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)
{
static const struct
{
GLenum texture_target;
unsigned int view_flags;
GLenum view_target;
}
view_types[] =
{
{GL_TEXTURE_2D, 0, GL_TEXTURE_2D},
{GL_TEXTURE_2D, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY},
{GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_2D},
{GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_TEXTURE_ARRAY, GL_TEXTURE_2D_ARRAY},
{GL_TEXTURE_2D_ARRAY, WINED3D_VIEW_TEXTURE_CUBE, GL_TEXTURE_CUBE_MAP},
{GL_TEXTURE_3D, 0, GL_TEXTURE_3D},
};
const struct wined3d_gl_info *gl_info = &resource->device->adapter->gl_info;
const struct wined3d_format *view_format;
view_format = wined3d_get_format(gl_info, desc->format_id);
if (view_format->id == view_format->typeless_id)
{
WARN("Trying to create view for typeless format %s.\n", debug_d3dformat(view_format->id));
return E_FAIL;
}
view->refcount = 1;
view->parent = parent;
view->parent_ops = parent_ops;
view->target = GL_NONE;
view->object = 0;
if (resource->type == WINED3D_RTYPE_BUFFER)
{
FIXME("Buffer shader resource views not supported.\n");
}
else
{
struct wined3d_texture *texture = texture_from_resource(resource);
unsigned int i;
if (desc->u.texture.level_idx >= texture->level_count
|| desc->u.texture.level_count > texture->level_count - desc->u.texture.level_idx
|| desc->u.texture.layer_idx >= texture->layer_count
|| desc->u.texture.layer_count > texture->layer_count - desc->u.texture.layer_idx)
return E_FAIL;
view->target = texture->target;
for (i = 0; i < ARRAY_SIZE(view_types); ++i)
{
if (view_types[i].texture_target == texture->target && view_types[i].view_flags == desc->flags)
{
view->target = view_types[i].view_target;
break;
}
}
if (i == ARRAY_SIZE(view_types))
FIXME("Unhandled view flags %#x for texture target %#x.\n", desc->flags, texture->target);
if (resource->format->id == view_format->id && texture->target == view->target
&& !desc->u.texture.level_idx && desc->u.texture.level_count == texture->level_count
&& !desc->u.texture.layer_idx && desc->u.texture.layer_count == texture->layer_count)
{
TRACE("Creating identity shader resource view.\n");
}
else if (texture->swapchain && texture->swapchain->desc.backbuffer_count > 1)
{
FIXME("Swapchain shader resource views not supported.\n");
}
else if (resource->format->typeless_id == view_format->typeless_id
&& resource->format->gl_view_class == view_format->gl_view_class)
{
wined3d_shader_resource_view_create_texture_view(view, desc, texture, view_format);
}
else
{
FIXME("Shader resource view not supported, resource format %s, view format %s.\n",
debug_d3dformat(resource->format->id), debug_d3dformat(view_format->id));
}
}
wined3d_resource_incref(view->resource = 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);
@ -214,14 +346,36 @@ 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);
WARN("Failed to initialise view, hr %#x.\n", hr);
return hr;
}
TRACE("Created shader resource view %p.\n", object);
*view = object;
return WINED3D_OK;
}
void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view *view,
struct wined3d_context *context)
{
struct wined3d_texture *texture;
if (view->object)
{
context_bind_texture(context, view->target, view->object);
return;
}
if (view->resource->type == WINED3D_RTYPE_BUFFER)
{
FIXME("Buffer shader resources not supported.\n");
return;
}
texture = wined3d_texture_from_resource(view->resource);
wined3d_texture_bind(texture, context, FALSE);
}

View File

@ -3082,8 +3082,14 @@ struct wined3d_shader_resource_view
struct wined3d_resource *resource;
void *parent;
const struct wined3d_parent_ops *parent_ops;
GLenum target;
GLuint object;
};
void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view *view,
struct wined3d_context *context) DECLSPEC_HIDDEN;
struct wined3d_swapchain_ops
{
void (*swapchain_present)(struct wined3d_swapchain *swapchain,
@ -3538,6 +3544,7 @@ struct wined3d_format
void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth);
enum wined3d_format_id typeless_id;
GLenum gl_view_class;
};