wined3d: Introduce an API for creating an identity SRV on a texture.
This commit is contained in:
parent
d8782a9b8e
commit
1698fd40cd
6 changed files with 73 additions and 5 deletions
|
@ -1648,6 +1648,12 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
|
||||||
{
|
{
|
||||||
bool in_cs_thread = GetCurrentThreadId() == texture->resource.device->cs->thread_id;
|
bool in_cs_thread = GetCurrentThreadId() == texture->resource.device->cs->thread_id;
|
||||||
|
|
||||||
|
if (texture->identity_srv)
|
||||||
|
{
|
||||||
|
assert(!in_cs_thread);
|
||||||
|
wined3d_shader_resource_view_destroy(texture->identity_srv);
|
||||||
|
}
|
||||||
|
|
||||||
/* This is called from the CS thread to destroy temporary textures. */
|
/* This is called from the CS thread to destroy temporary textures. */
|
||||||
if (!in_cs_thread)
|
if (!in_cs_thread)
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
|
@ -4667,6 +4673,42 @@ void wined3d_texture_update_sub_resource(struct wined3d_texture *texture, unsign
|
||||||
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
|
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wined3d_shader_resource_view * CDECL wined3d_texture_acquire_identity_srv(struct wined3d_texture *texture)
|
||||||
|
{
|
||||||
|
struct wined3d_view_desc desc;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
TRACE("texture %p.\n", texture);
|
||||||
|
|
||||||
|
if (texture->identity_srv)
|
||||||
|
return texture->identity_srv;
|
||||||
|
|
||||||
|
desc.format_id = texture->resource.format->id;
|
||||||
|
/* The texture owns a reference to the SRV, so we can't have the SRV hold
|
||||||
|
* a reference to the texture.
|
||||||
|
* At the same time, a view must be destroyed before its texture, and we
|
||||||
|
* need a bound SRV to keep the texture alive even if it doesn't have any
|
||||||
|
* other references.
|
||||||
|
* In order to achieve this we have the objects share reference counts.
|
||||||
|
* This means the view doesn't hold a reference to the resource, but any
|
||||||
|
* references to the view are forwarded to the resource instead. The view
|
||||||
|
* is destroyed manually when all references are released. */
|
||||||
|
desc.flags = WINED3D_VIEW_FORWARD_REFERENCE;
|
||||||
|
desc.u.texture.level_idx = 0;
|
||||||
|
desc.u.texture.level_count = texture->level_count;
|
||||||
|
desc.u.texture.layer_idx = 0;
|
||||||
|
desc.u.texture.layer_count = texture->layer_count;
|
||||||
|
if (FAILED(hr = wined3d_shader_resource_view_create(&desc, &texture->resource,
|
||||||
|
NULL, &wined3d_null_parent_ops, &texture->identity_srv)))
|
||||||
|
{
|
||||||
|
ERR("Failed to create shader resource view, hr %#lx.\n", hr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wined3d_shader_resource_view_decref(texture->identity_srv);
|
||||||
|
|
||||||
|
return texture->identity_srv;
|
||||||
|
}
|
||||||
|
|
||||||
static void wined3d_texture_no3d_upload_data(struct wined3d_context *context,
|
static void wined3d_texture_no3d_upload_data(struct wined3d_context *context,
|
||||||
const struct wined3d_const_bo_address *src_bo_addr, const struct wined3d_format *src_format,
|
const struct wined3d_const_bo_address *src_bo_addr, const struct wined3d_format *src_format,
|
||||||
const struct wined3d_box *src_box, unsigned int src_row_pitch, unsigned int src_slice_pitch,
|
const struct wined3d_box *src_box, unsigned int src_row_pitch, unsigned int src_slice_pitch,
|
||||||
|
|
|
@ -4918,6 +4918,7 @@ const char *wined3d_debug_view_desc(const struct wined3d_view_desc *d, const str
|
||||||
VIEW_FLAG_TO_STR(WINED3D_VIEW_TEXTURE_ARRAY);
|
VIEW_FLAG_TO_STR(WINED3D_VIEW_TEXTURE_ARRAY);
|
||||||
VIEW_FLAG_TO_STR(WINED3D_VIEW_READ_ONLY_DEPTH);
|
VIEW_FLAG_TO_STR(WINED3D_VIEW_READ_ONLY_DEPTH);
|
||||||
VIEW_FLAG_TO_STR(WINED3D_VIEW_READ_ONLY_STENCIL);
|
VIEW_FLAG_TO_STR(WINED3D_VIEW_READ_ONLY_STENCIL);
|
||||||
|
VIEW_FLAG_TO_STR(WINED3D_VIEW_FORWARD_REFERENCE);
|
||||||
#undef VIEW_FLAG_TO_STR
|
#undef VIEW_FLAG_TO_STR
|
||||||
if (flags)
|
if (flags)
|
||||||
FIXME("Unrecognised view flag(s) %#x.\n", flags);
|
FIXME("Unrecognised view flag(s) %#x.\n", flags);
|
||||||
|
|
|
@ -959,8 +959,12 @@ HRESULT CDECL wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_
|
||||||
|
|
||||||
ULONG CDECL wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view)
|
ULONG CDECL wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view)
|
||||||
{
|
{
|
||||||
unsigned int refcount = InterlockedIncrement(&view->refcount);
|
unsigned int refcount;
|
||||||
|
|
||||||
|
if (view->desc.flags & WINED3D_VIEW_FORWARD_REFERENCE)
|
||||||
|
return wined3d_resource_incref(view->resource);
|
||||||
|
|
||||||
|
refcount = InterlockedIncrement(&view->refcount);
|
||||||
TRACE("%p increasing refcount to %u.\n", view, refcount);
|
TRACE("%p increasing refcount to %u.\n", view, refcount);
|
||||||
|
|
||||||
return refcount;
|
return refcount;
|
||||||
|
@ -971,10 +975,21 @@ void wined3d_shader_resource_view_cleanup(struct wined3d_shader_resource_view *v
|
||||||
view->parent_ops->wined3d_object_destroyed(view->parent);
|
view->parent_ops->wined3d_object_destroyed(view->parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wined3d_shader_resource_view_destroy(struct wined3d_shader_resource_view *view)
|
||||||
|
{
|
||||||
|
wined3d_mutex_lock();
|
||||||
|
view->resource->device->adapter->adapter_ops->adapter_destroy_shader_resource_view(view);
|
||||||
|
wined3d_mutex_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view)
|
ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view)
|
||||||
{
|
{
|
||||||
unsigned int refcount = InterlockedDecrement(&view->refcount);
|
unsigned int refcount;
|
||||||
|
|
||||||
|
if (view->desc.flags & WINED3D_VIEW_FORWARD_REFERENCE)
|
||||||
|
return wined3d_resource_decref(view->resource);
|
||||||
|
|
||||||
|
refcount = InterlockedDecrement(&view->refcount);
|
||||||
TRACE("%p decreasing refcount to %u.\n", view, refcount);
|
TRACE("%p decreasing refcount to %u.\n", view, refcount);
|
||||||
|
|
||||||
if (!refcount)
|
if (!refcount)
|
||||||
|
@ -986,9 +1001,7 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v
|
||||||
* device, which the resource implicitly provides.
|
* device, which the resource implicitly provides.
|
||||||
* - We shouldn't free buffer resources until after we've removed the
|
* - We shouldn't free buffer resources until after we've removed the
|
||||||
* view from its bo_user list. */
|
* view from its bo_user list. */
|
||||||
wined3d_mutex_lock();
|
wined3d_shader_resource_view_destroy(view);
|
||||||
resource->device->adapter->adapter_ops->adapter_destroy_shader_resource_view(view);
|
|
||||||
wined3d_mutex_unlock();
|
|
||||||
wined3d_resource_decref(resource);
|
wined3d_resource_decref(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1091,6 +1104,10 @@ static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
view->desc = *desc;
|
view->desc = *desc;
|
||||||
|
|
||||||
|
/* If WINED3D_VIEW_FORWARD_REFERENCE, the view shouldn't take a reference
|
||||||
|
* to the resource. However, the reference to the view returned by this
|
||||||
|
* function should translate to a resource reference, so we increment the
|
||||||
|
* resource's reference count anyway. */
|
||||||
wined3d_resource_incref(view->resource = resource);
|
wined3d_resource_incref(view->resource = resource);
|
||||||
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
|
|
|
@ -298,6 +298,7 @@
|
||||||
@ cdecl wined3d_swapchain_state_resize_target(ptr ptr)
|
@ cdecl wined3d_swapchain_state_resize_target(ptr ptr)
|
||||||
@ cdecl wined3d_swapchain_state_set_fullscreen(ptr ptr ptr)
|
@ cdecl wined3d_swapchain_state_set_fullscreen(ptr ptr ptr)
|
||||||
|
|
||||||
|
@ cdecl wined3d_texture_acquire_identity_srv(ptr)
|
||||||
@ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
|
@ cdecl wined3d_texture_add_dirty_region(ptr long ptr)
|
||||||
@ cdecl wined3d_texture_create(ptr ptr long long long ptr ptr ptr ptr)
|
@ cdecl wined3d_texture_create(ptr ptr long long long ptr ptr ptr ptr)
|
||||||
@ cdecl wined3d_texture_decref(ptr)
|
@ cdecl wined3d_texture_decref(ptr)
|
||||||
|
|
|
@ -3335,6 +3335,8 @@ struct wined3d_texture
|
||||||
unsigned int row_pitch;
|
unsigned int row_pitch;
|
||||||
unsigned int slice_pitch;
|
unsigned int slice_pitch;
|
||||||
|
|
||||||
|
struct wined3d_shader_resource_view *identity_srv;
|
||||||
|
|
||||||
/* May only be accessed from the command stream worker thread. */
|
/* May only be accessed from the command stream worker thread. */
|
||||||
struct wined3d_texture_async
|
struct wined3d_texture_async
|
||||||
{
|
{
|
||||||
|
@ -3935,6 +3937,7 @@ struct wined3d_shader_resource_view
|
||||||
};
|
};
|
||||||
|
|
||||||
void wined3d_shader_resource_view_cleanup(struct wined3d_shader_resource_view *view);
|
void wined3d_shader_resource_view_cleanup(struct wined3d_shader_resource_view *view);
|
||||||
|
void wined3d_shader_resource_view_destroy(struct wined3d_shader_resource_view *view);
|
||||||
|
|
||||||
static inline struct wined3d_texture *wined3d_state_get_ffp_texture(const struct wined3d_state *state, unsigned int idx)
|
static inline struct wined3d_texture *wined3d_state_get_ffp_texture(const struct wined3d_state *state, unsigned int idx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1583,6 +1583,9 @@ enum wined3d_memory_segment_group
|
||||||
#define WINED3D_VIEW_TEXTURE_ARRAY 0x00000010
|
#define WINED3D_VIEW_TEXTURE_ARRAY 0x00000010
|
||||||
#define WINED3D_VIEW_READ_ONLY_DEPTH 0x00000020
|
#define WINED3D_VIEW_READ_ONLY_DEPTH 0x00000020
|
||||||
#define WINED3D_VIEW_READ_ONLY_STENCIL 0x00000040
|
#define WINED3D_VIEW_READ_ONLY_STENCIL 0x00000040
|
||||||
|
/* The view shares a reference count with its resource.
|
||||||
|
* See wined3d_texture_acquire_identity_srv(). */
|
||||||
|
#define WINED3D_VIEW_FORWARD_REFERENCE 0x00000080
|
||||||
|
|
||||||
#define WINED3D_MAX_VIEWPORTS 16
|
#define WINED3D_MAX_VIEWPORTS 16
|
||||||
|
|
||||||
|
@ -2866,6 +2869,7 @@ HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_s
|
||||||
HRESULT __cdecl wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_state *state,
|
HRESULT __cdecl wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_state *state,
|
||||||
const struct wined3d_swapchain_desc *desc, const struct wined3d_display_mode *mode);
|
const struct wined3d_swapchain_desc *desc, const struct wined3d_display_mode *mode);
|
||||||
|
|
||||||
|
struct wined3d_shader_resource_view * __cdecl wined3d_texture_acquire_identity_srv(struct wined3d_texture *texture);
|
||||||
HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
|
HRESULT __cdecl wined3d_texture_add_dirty_region(struct wined3d_texture *texture,
|
||||||
UINT layer, const struct wined3d_box *dirty_region);
|
UINT layer, const struct wined3d_box *dirty_region);
|
||||||
HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
|
HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
|
||||||
|
|
Loading…
Add table
Reference in a new issue