Commit e3e9bdee authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Make the adapter responsible for texture creation and destruction.

parent 27890cfb
......@@ -4745,6 +4745,90 @@ static void adapter_gl_destroy_buffer(struct wined3d_buffer *buffer)
wined3d_device_decref(device);
}
static HRESULT adapter_gl_create_texture(struct wined3d_device *device,
const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
{
struct wined3d_texture_gl *texture_gl;
HRESULT hr;
TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, parent %p, parent_ops %p, texture %p.\n",
device, desc, layer_count, level_count, flags, parent, parent_ops, texture);
if (!(texture_gl = wined3d_texture_allocate_object_memory(sizeof(*texture_gl), level_count, layer_count)))
return E_OUTOFMEMORY;
if (FAILED(hr = wined3d_texture_gl_init(texture_gl, device, desc,
layer_count, level_count, flags, parent, parent_ops)))
{
WARN("Failed to initialise texture, hr %#x.\n", hr);
heap_free(texture_gl);
return hr;
}
TRACE("Created texture %p.\n", texture_gl);
*texture = &texture_gl->t;
return hr;
}
static void wined3d_texture_gl_destroy_object(void *object)
{
struct wined3d_renderbuffer_entry *entry, *entry2;
struct wined3d_texture_gl *texture_gl = object;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
struct wined3d_device *device;
TRACE("texture_gl %p.\n", texture_gl);
if (!list_empty(&texture_gl->renderbuffers))
{
device = texture_gl->t.resource.device;
context = context_acquire(device, NULL, 0);
gl_info = wined3d_context_gl(context)->gl_info;
LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry)
{
TRACE("Deleting renderbuffer %u.\n", entry->id);
context_gl_resource_released(device, entry->id, TRUE);
gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
heap_free(entry);
}
context_release(context);
}
wined3d_texture_gl_unload_texture(texture_gl);
heap_free(texture_gl);
}
static void adapter_gl_destroy_texture(struct wined3d_texture *texture)
{
struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture);
struct wined3d_device *device = texture_gl->t.resource.device;
unsigned int swapchain_count = device->swapchain_count;
TRACE("texture_gl %p.\n", texture_gl);
/* Take a reference to the device, in case releasing the texture would
* cause the device to be destroyed. However, swapchain resources don't
* take a reference to the device, and we wouldn't want to increment the
* refcount on a device that's in the process of being destroyed. */
if (swapchain_count)
wined3d_device_incref(device);
wined3d_texture_sub_resources_destroyed(texture);
texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
wined3d_texture_cleanup(&texture_gl->t);
wined3d_cs_destroy_object(device->cs, wined3d_texture_gl_destroy_object, texture_gl);
if (swapchain_count)
wined3d_device_decref(device);
}
static HRESULT adapter_gl_create_rendertarget_view(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_rendertarget_view **view)
......@@ -4953,6 +5037,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
adapter_gl_destroy_swapchain,
adapter_gl_create_buffer,
adapter_gl_destroy_buffer,
adapter_gl_create_texture,
adapter_gl_destroy_texture,
adapter_gl_create_rendertarget_view,
adapter_gl_destroy_rendertarget_view,
adapter_gl_create_shader_resource_view,
......
......@@ -543,6 +543,58 @@ static void adapter_vk_destroy_buffer(struct wined3d_buffer *buffer)
wined3d_device_decref(device);
}
static HRESULT adapter_vk_create_texture(struct wined3d_device *device,
const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
{
struct wined3d_texture_vk *texture_vk;
HRESULT hr;
TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, parent %p, parent_ops %p, texture %p.\n",
device, desc, layer_count, level_count, flags, parent, parent_ops, texture);
if (!(texture_vk = wined3d_texture_allocate_object_memory(sizeof(*texture_vk), level_count, layer_count)))
return E_OUTOFMEMORY;
if (FAILED(hr = wined3d_texture_vk_init(texture_vk, device, desc,
layer_count, level_count, flags, parent, parent_ops)))
{
WARN("Failed to initialise texture, hr %#x.\n", hr);
heap_free(texture_vk);
return hr;
}
TRACE("Created texture %p.\n", texture_vk);
*texture = &texture_vk->t;
return hr;
}
static void adapter_vk_destroy_texture(struct wined3d_texture *texture)
{
struct wined3d_texture_vk *texture_vk = wined3d_texture_vk(texture);
struct wined3d_device *device = texture_vk->t.resource.device;
unsigned int swapchain_count = device->swapchain_count;
TRACE("texture_vk %p.\n", texture_vk);
/* Take a reference to the device, in case releasing the texture would
* cause the device to be destroyed. However, swapchain resources don't
* take a reference to the device, and we wouldn't want to increment the
* refcount on a device that's in the process of being destroyed. */
if (swapchain_count)
wined3d_device_incref(device);
wined3d_texture_sub_resources_destroyed(texture);
texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
wined3d_texture_cleanup(&texture_vk->t);
wined3d_cs_destroy_object(device->cs, heap_free, texture_vk);
if (swapchain_count)
wined3d_device_decref(device);
}
static HRESULT adapter_vk_create_rendertarget_view(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_rendertarget_view **view)
......@@ -696,6 +748,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
adapter_vk_destroy_swapchain,
adapter_vk_create_buffer,
adapter_vk_destroy_buffer,
adapter_vk_create_texture,
adapter_vk_destroy_texture,
adapter_vk_create_rendertarget_view,
adapter_vk_destroy_rendertarget_view,
adapter_vk_create_shader_resource_view,
......
......@@ -2428,6 +2428,57 @@ static void adapter_no3d_destroy_buffer(struct wined3d_buffer *buffer)
wined3d_device_decref(device);
}
static HRESULT adapter_no3d_create_texture(struct wined3d_device *device,
const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
{
struct wined3d_texture *texture_no3d;
HRESULT hr;
TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, parent %p, parent_ops %p, texture %p.\n",
device, desc, layer_count, level_count, flags, parent, parent_ops, texture);
if (!(texture_no3d = wined3d_texture_allocate_object_memory(sizeof(*texture_no3d), level_count, layer_count)))
return E_OUTOFMEMORY;
if (FAILED(hr = wined3d_texture_no3d_init(texture_no3d, device, desc,
layer_count, level_count, flags, parent, parent_ops)))
{
WARN("Failed to initialise texture, hr %#x.\n", hr);
heap_free(texture_no3d);
return hr;
}
TRACE("Created texture %p.\n", texture_no3d);
*texture = texture_no3d;
return hr;
}
static void adapter_no3d_destroy_texture(struct wined3d_texture *texture)
{
struct wined3d_device *device = texture->resource.device;
unsigned int swapchain_count = device->swapchain_count;
TRACE("texture %p.\n", texture);
/* Take a reference to the device, in case releasing the texture would
* cause the device to be destroyed. However, swapchain resources don't
* take a reference to the device, and we wouldn't want to increment the
* refcount on a device that's in the process of being destroyed. */
if (swapchain_count)
wined3d_device_incref(device);
wined3d_texture_sub_resources_destroyed(texture);
texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
wined3d_texture_cleanup(texture);
wined3d_cs_destroy_object(device->cs, heap_free, texture);
if (swapchain_count)
wined3d_device_decref(device);
}
static HRESULT adapter_no3d_create_rendertarget_view(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_rendertarget_view **view)
......@@ -2518,6 +2569,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
adapter_no3d_destroy_swapchain,
adapter_no3d_create_buffer,
adapter_no3d_destroy_buffer,
adapter_no3d_create_texture,
adapter_no3d_destroy_texture,
adapter_no3d_create_rendertarget_view,
adapter_no3d_destroy_rendertarget_view,
adapter_no3d_create_shader_resource_view,
......
......@@ -2788,6 +2788,10 @@ struct wined3d_adapter_ops
const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_buffer **buffer);
void (*adapter_destroy_buffer)(struct wined3d_buffer *buffer);
HRESULT (*adapter_create_texture)(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
unsigned int layer_count, unsigned int level_count, uint32_t flags, void *parent,
const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture);
void (*adapter_destroy_texture)(struct wined3d_texture *texture);
HRESULT (*adapter_create_rendertarget_view)(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_rendertarget_view **view);
......@@ -3551,6 +3555,16 @@ struct wined3d_texture
} *sub_resources;
};
static inline void *wined3d_texture_allocate_object_memory(SIZE_T s, SIZE_T level_count, SIZE_T layer_count)
{
struct wined3d_texture *t;
if (level_count > ((~(SIZE_T)0 - s) / sizeof(*t->sub_resources)) / layer_count)
return NULL;
return heap_alloc_zero(s + level_count * layer_count * sizeof(*t->sub_resources));
}
static inline struct wined3d_texture *texture_from_resource(struct wined3d_resource *resource)
{
return CONTAINING_RECORD(resource, struct wined3d_texture, resource);
......@@ -3613,6 +3627,7 @@ void texture2d_read_from_framebuffer(struct wined3d_texture *texture, unsigned i
HRESULT wined3d_texture_check_box_dimensions(const struct wined3d_texture *texture,
unsigned int level, const struct wined3d_box *box) DECLSPEC_HIDDEN;
void wined3d_texture_cleanup(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx) DECLSPEC_HIDDEN;
GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture) DECLSPEC_HIDDEN;
......@@ -3629,6 +3644,7 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned
void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding) DECLSPEC_HIDDEN;
void wined3d_texture_set_swapchain(struct wined3d_texture *texture,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture) DECLSPEC_HIDDEN;
void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture,
HWND window, RECT *rect) DECLSPEC_HIDDEN;
void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
......@@ -3641,6 +3657,10 @@ void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, un
void wined3d_texture_validate_location(struct wined3d_texture *texture,
unsigned int sub_resource_idx, DWORD location) DECLSPEC_HIDDEN;
HRESULT wined3d_texture_no3d_init(struct wined3d_texture *texture_no3d, struct wined3d_device *device,
const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
void wined3d_gl_texture_swizzle_from_color_fixup(GLint swizzle[4], struct color_fixup_desc fixup) DECLSPEC_HIDDEN;
struct gl_texture
......@@ -3709,11 +3729,29 @@ void wined3d_texture_gl_bind(struct wined3d_texture_gl *texture_gl,
struct wined3d_context_gl *context_gl, BOOL srgb) DECLSPEC_HIDDEN;
void wined3d_texture_gl_bind_and_dirtify(struct wined3d_texture_gl *texture_gl,
struct wined3d_context_gl *context_gl, BOOL srgb) DECLSPEC_HIDDEN;
HRESULT wined3d_texture_gl_init(struct wined3d_texture_gl *texture_gl, struct wined3d_device *device,
const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
void wined3d_texture_gl_prepare_texture(struct wined3d_texture_gl *texture_gl,
struct wined3d_context_gl *context_gl, BOOL srgb) DECLSPEC_HIDDEN;
void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *texture_gl,
struct wined3d_context_gl *context_gl, unsigned int level,
const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl) DECLSPEC_HIDDEN;
struct wined3d_texture_vk
{
struct wined3d_texture t;
};
static inline struct wined3d_texture_vk *wined3d_texture_vk(struct wined3d_texture *texture)
{
return CONTAINING_RECORD(texture, struct wined3d_texture_vk, t);
}
HRESULT wined3d_texture_vk_init(struct wined3d_texture_vk *texture_vk, struct wined3d_device *device,
const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
struct wined3d_renderbuffer_entry
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment