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;
|
||||
|
||||
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. */
|
||||
if (!in_cs_thread)
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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,
|
||||
|
|
|
@ -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_READ_ONLY_DEPTH);
|
||||
VIEW_FLAG_TO_STR(WINED3D_VIEW_READ_ONLY_STENCIL);
|
||||
VIEW_FLAG_TO_STR(WINED3D_VIEW_FORWARD_REFERENCE);
|
||||
#undef VIEW_FLAG_TO_STR
|
||||
if (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)
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
if (!refcount)
|
||||
|
@ -986,9 +1001,7 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v
|
|||
* device, which the resource implicitly provides.
|
||||
* - We shouldn't free buffer resources until after we've removed the
|
||||
* view from its bo_user list. */
|
||||
wined3d_mutex_lock();
|
||||
resource->device->adapter->adapter_ops->adapter_destroy_shader_resource_view(view);
|
||||
wined3d_mutex_unlock();
|
||||
wined3d_shader_resource_view_destroy(view);
|
||||
wined3d_resource_decref(resource);
|
||||
}
|
||||
|
||||
|
@ -1091,6 +1104,10 @@ static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_
|
|||
return E_INVALIDARG;
|
||||
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);
|
||||
|
||||
return WINED3D_OK;
|
||||
|
|
|
@ -298,6 +298,7 @@
|
|||
@ cdecl wined3d_swapchain_state_resize_target(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_create(ptr ptr long long long ptr ptr ptr ptr)
|
||||
@ cdecl wined3d_texture_decref(ptr)
|
||||
|
|
|
@ -3335,6 +3335,8 @@ struct wined3d_texture
|
|||
unsigned int row_pitch;
|
||||
unsigned int slice_pitch;
|
||||
|
||||
struct wined3d_shader_resource_view *identity_srv;
|
||||
|
||||
/* May only be accessed from the command stream worker thread. */
|
||||
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_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)
|
||||
{
|
||||
|
|
|
@ -1583,6 +1583,9 @@ enum wined3d_memory_segment_group
|
|||
#define WINED3D_VIEW_TEXTURE_ARRAY 0x00000010
|
||||
#define WINED3D_VIEW_READ_ONLY_DEPTH 0x00000020
|
||||
#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
|
||||
|
||||
|
@ -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,
|
||||
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,
|
||||
UINT layer, const struct wined3d_box *dirty_region);
|
||||
HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
|
||||
|
|
Loading…
Add table
Reference in a new issue