Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/adapter_gl.c | 86 +++++++++++ dlls/wined3d/adapter_vk.c | 54 +++++++ dlls/wined3d/directx.c | 53 +++++++ dlls/wined3d/texture.c | 336 ++++++++++++++++++++++++----------------- dlls/wined3d/wined3d_private.h | 38 +++++ 5 files changed, 425 insertions(+), 142 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index d32b66480a6..cf54468a76b 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -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, diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index c3a1832e353..f203e0f52e1 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -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, diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 201a5cf7a09..3c18e0e402e 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -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, diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 467dd093a45..4d411bf33f2 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -32,6 +32,7 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
static const uint32_t wined3d_texture_sysmem_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY | WINED3D_LOCATION_BUFFER; +static const struct wined3d_texture_ops texture_gl_ops;
struct wined3d_texture_idx { @@ -633,7 +634,7 @@ static void wined3d_texture_gl_allocate_immutable_storage(struct wined3d_texture checkGLcall("allocate immutable storage"); }
-static void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl) +void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl) { struct wined3d_device *device = texture_gl->t.resource.device; const struct wined3d_gl_info *gl_info = NULL; @@ -678,7 +679,7 @@ static void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture resource_unload(&texture_gl->t.resource); }
-static void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture) +void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture) { unsigned int sub_count = texture->level_count * texture->layer_count; struct wined3d_texture_sub_resource *sub_resource; @@ -821,97 +822,6 @@ static void wined3d_texture_destroy_dc(void *object) context_release(context); }
-static void wined3d_texture_cleanup(struct wined3d_texture *texture) -{ - unsigned int sub_count = texture->level_count * texture->layer_count; - struct wined3d_device *device = texture->resource.device; - const struct wined3d_gl_info *gl_info = NULL; - struct wined3d_context *context = NULL; - struct wined3d_dc_info *dc_info; - GLuint buffer_object; - unsigned int i; - - TRACE("texture %p.\n", texture); - - for (i = 0; i < sub_count; ++i) - { - if (!(buffer_object = texture->sub_resources[i].buffer_object)) - continue; - - TRACE("Deleting buffer object %u.\n", buffer_object); - - /* We may not be able to get a context in wined3d_texture_cleanup() in - * general, but if a buffer object was previously created we can. */ - if (!context) - { - context = context_acquire(device, NULL, 0); - gl_info = wined3d_context_gl(context)->gl_info; - } - - GL_EXTCALL(glDeleteBuffers(1, &buffer_object)); - } - - if (context) - context_release(context); - - if ((dc_info = texture->dc_info)) - { - for (i = 0; i < sub_count; ++i) - { - if (dc_info[i].dc) - { - struct wined3d_texture_idx texture_idx = {texture, i}; - - wined3d_texture_destroy_dc(&texture_idx); - } - } - heap_free(dc_info); - } - - if (texture->overlay_info) - { - for (i = 0; i < sub_count; ++i) - { - struct wined3d_overlay_info *info = &texture->overlay_info[i]; - struct wined3d_overlay_info *overlay, *cur; - - list_remove(&info->entry); - LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &info->overlays, struct wined3d_overlay_info, entry) - { - list_remove(&overlay->entry); - } - } - heap_free(texture->overlay_info); - } -} - -static void wined3d_texture_gl_cleanup(struct wined3d_texture_gl *texture_gl) -{ - struct wined3d_device *device = texture_gl->t.resource.device; - struct wined3d_renderbuffer_entry *entry, *entry2; - const struct wined3d_gl_info *gl_info; - struct wined3d_context *context; - - if (!list_empty(&texture_gl->renderbuffers)) - { - 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_cleanup(&texture_gl->t); - wined3d_texture_gl_unload_texture(texture_gl); -} - void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain) { texture->swapchain = swapchain; @@ -1201,20 +1111,83 @@ ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture) return refcount; }
-static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture) +static void wined3d_texture_destroy_object(void *object) { - wined3d_texture_sub_resources_destroyed(texture); - resource_cleanup(&texture->resource); - wined3d_resource_wait_idle(&texture->resource); - wined3d_texture_cleanup(texture); + const struct wined3d_gl_info *gl_info = NULL; + struct wined3d_texture *texture = object; + struct wined3d_context *context = NULL; + struct wined3d_dc_info *dc_info; + unsigned int sub_count; + GLuint buffer_object; + unsigned int i; + + TRACE("texture %p.\n", texture); + + sub_count = texture->level_count * texture->layer_count; + for (i = 0; i < sub_count; ++i) + { + if (!(buffer_object = texture->sub_resources[i].buffer_object)) + continue; + + TRACE("Deleting buffer object %u.\n", buffer_object); + + /* We may not be able to get a context in + * wined3d_texture_destroy_object() in general, but if a buffer object + * was previously created we can. */ + if (!context) + { + context = context_acquire(texture->resource.device, NULL, 0); + gl_info = wined3d_context_gl(context)->gl_info; + } + + GL_EXTCALL(glDeleteBuffers(1, &buffer_object)); + } + + if (context) + context_release(context); + + if ((dc_info = texture->dc_info)) + { + for (i = 0; i < sub_count; ++i) + { + if (dc_info[i].dc) + { + struct wined3d_texture_idx texture_idx = {texture, i}; + + wined3d_texture_destroy_dc(&texture_idx); + } + } + heap_free(dc_info); + } + + if (texture->overlay_info) + { + for (i = 0; i < sub_count; ++i) + { + struct wined3d_overlay_info *info = &texture->overlay_info[i]; + struct wined3d_overlay_info *overlay, *cur; + + list_remove(&info->entry); + LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &info->overlays, struct wined3d_overlay_info, entry) + { + list_remove(&overlay->entry); + } + } + heap_free(texture->overlay_info); + } }
-static void wined3d_texture_destroy_object(void *object) +void wined3d_texture_cleanup(struct wined3d_texture *texture) { - struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(object); + resource_cleanup(&texture->resource); + wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture); +}
- wined3d_texture_gl_cleanup(texture_gl); - heap_free(texture_gl); +static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture) +{ + wined3d_texture_sub_resources_destroyed(texture); + wined3d_texture_cleanup(texture); + wined3d_resource_wait_idle(&texture->resource); }
ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) @@ -1234,13 +1207,10 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture) /* Wait for the texture to become idle if it's using user memory, * since the application is allowed to free that memory once the * texture is destroyed. Note that this implies that - * wined3d_texture_destroy_object() can't access that memory either. */ + * the destroy handler can't access that memory either. */ if (texture->user_memory) wined3d_resource_wait_idle(&texture->resource); - wined3d_texture_sub_resources_destroyed(texture); - texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent); - resource_cleanup(&texture->resource); - wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture); + texture->resource.device->adapter->adapter_ops->adapter_destroy_texture(texture); }
return refcount; @@ -1636,10 +1606,13 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT sub_resource->size = texture->slice_pitch; sub_resource->locations = WINED3D_LOCATION_DISCARDED;
- if (multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) - wined3d_texture_gl(texture)->target = GL_TEXTURE_2D_MULTISAMPLE; - else - wined3d_texture_gl(texture)->target = GL_TEXTURE_2D; + if (texture->texture_ops == &texture_gl_ops) + { + if (multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE]) + wined3d_texture_gl(texture)->target = GL_TEXTURE_2D_MULTISAMPLE; + else + wined3d_texture_gl(texture)->target = GL_TEXTURE_2D; + }
if (((width & (width - 1)) || (height & (height - 1))) && !d3d_info->texture_npot && !d3d_info->texture_npot_conditional) @@ -3642,27 +3615,17 @@ HRESULT CDECL wined3d_texture_get_sub_resource_desc(const struct wined3d_texture return WINED3D_OK; }
-static 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 HRESULT wined3d_texture_gl_init(struct wined3d_texture_gl *texture_gl, struct wined3d_device *device, +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, - DWORD flags, void *parent, const struct wined3d_parent_ops *parent_ops, void *sub_resources) + uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; HRESULT hr;
- TRACE("texture_gl %p, device %p, desc %p, layer_count %u, level_count %u, " - "flags %#x, parent %p, parent_ops %p, sub_resources %p.\n", - texture_gl, device, desc, layer_count, level_count, - flags, parent, parent_ops, sub_resources); + TRACE("texture_gl %p, device %p, desc %p, layer_count %u, " + "level_count %u, flags %#x, parent %p, parent_ops %p.\n", + texture_gl, device, desc, layer_count, + level_count, flags, parent, parent_ops);
if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1 && !gl_info->supported[EXT_TEXTURE_ARRAY]) @@ -3718,7 +3681,7 @@ static HRESULT wined3d_texture_gl_init(struct wined3d_texture_gl *texture_gl, st list_init(&texture_gl->renderbuffers);
if (FAILED(hr = wined3d_texture_init(&texture_gl->t, desc, layer_count, level_count, - flags, device, parent, parent_ops, sub_resources, &texture_gl_ops))) + flags, device, parent, parent_ops, &texture_gl[1], &texture_gl_ops))) return hr;
if (texture_gl->t.resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT) @@ -3732,7 +3695,6 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture) { unsigned int sub_count = level_count * layer_count; - struct wined3d_texture_gl *object; unsigned int i; HRESULT hr;
@@ -3790,16 +3752,9 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct } }
- if (!(object = wined3d_texture_allocate_object_memory(sizeof(*object), level_count, layer_count))) - return E_OUTOFMEMORY; - - if (FAILED(hr = wined3d_texture_gl_init(object, device, desc, layer_count, - level_count, flags, parent, parent_ops, &object[1]))) - { - WARN("Failed to initialize texture, returning %#x.\n", hr); - heap_free(object); + if (FAILED(hr = device->adapter->adapter_ops->adapter_create_texture(device, desc, + layer_count, level_count, flags, parent, parent_ops, texture))) return hr; - }
/* FIXME: We'd like to avoid ever allocating system memory for the texture * in this case. */ @@ -3809,14 +3764,13 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
for (i = 0; i < sub_count; ++i) { - wined3d_texture_get_level_box(&object->t, i % object->t.level_count, &box); - wined3d_cs_emit_update_sub_resource(device->cs, &object->t.resource, + wined3d_texture_get_level_box(*texture, i % (*texture)->level_count, &box); + wined3d_cs_emit_update_sub_resource(device->cs, &(*texture)->resource, i, &box, data[i].data, data[i].row_pitch, data[i].slice_pitch); } }
- TRACE("Created texture %p.\n", object); - *texture = &object->t; + TRACE("Created texture %p.\n", *texture);
return WINED3D_OK; } @@ -3993,3 +3947,101 @@ void wined3d_texture_download_from_texture(struct wined3d_texture *dst_texture, wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, dst_location); wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~dst_location); } + +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, + struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, unsigned int dst_location, + unsigned int dst_x, unsigned int dst_y, unsigned int dst_z) +{ + FIXME("Not implemented.\n"); +} + +static void wined3d_texture_no3d_download_data(struct wined3d_context *context, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, unsigned int src_location, + const struct wined3d_box *src_box, const struct wined3d_bo_address *dst_bo_addr, + const struct wined3d_format *dst_format, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, + unsigned int dst_row_pitch, unsigned int dst_slice_pitch) +{ + FIXME("Not implemented.\n"); +} + +static BOOL wined3d_texture_no3d_load_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) +{ + TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n", + texture, sub_resource_idx, context, wined3d_debug_location(location)); + + if (location == WINED3D_LOCATION_USER_MEMORY || location == WINED3D_LOCATION_SYSMEM) + return TRUE; + + ERR("Unhandled location %s.\n", wined3d_debug_location(location)); + + return FALSE; +} + +static const struct wined3d_texture_ops wined3d_texture_no3d_ops = +{ + wined3d_texture_no3d_load_location, + wined3d_texture_no3d_upload_data, + wined3d_texture_no3d_download_data, +}; + +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) +{ + TRACE("texture_no3d %p, device %p, desc %p, layer_count %u, " + "level_count %u, flags %#x, parent %p, parent_ops %p.\n", + texture_no3d, device, desc, layer_count, + level_count, flags, parent, parent_ops); + + return wined3d_texture_init(texture_no3d, desc, layer_count, level_count, + flags, device, parent, parent_ops, &texture_no3d[1], &wined3d_texture_no3d_ops); +} + +static void wined3d_texture_vk_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, + struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, unsigned int dst_location, + unsigned int dst_x, unsigned int dst_y, unsigned int dst_z) +{ + FIXME("Not implemented.\n"); +} + +static void wined3d_texture_vk_download_data(struct wined3d_context *context, + struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, unsigned int src_location, + const struct wined3d_box *src_box, const struct wined3d_bo_address *dst_bo_addr, + const struct wined3d_format *dst_format, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, + unsigned int dst_row_pitch, unsigned int dst_slice_pitch) +{ + FIXME("Not implemented.\n"); +} + +static BOOL wined3d_texture_vk_load_location(struct wined3d_texture *texture, + unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) +{ + FIXME("Not implemented.\n"); + + return FALSE; +} + +static const struct wined3d_texture_ops wined3d_texture_vk_ops = +{ + wined3d_texture_vk_load_location, + wined3d_texture_vk_upload_data, + wined3d_texture_vk_download_data, +}; + +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) +{ + TRACE("texture_vk %p, device %p, desc %p, layer_count %u, " + "level_count %u, flags %#x, parent %p, parent_ops %p.\n", + texture_vk, device, desc, layer_count, + level_count, flags, parent, parent_ops); + + return wined3d_texture_init(&texture_vk->t, desc, layer_count, level_count, + flags, device, parent, parent_ops, &texture_vk[1], &wined3d_texture_vk_ops); +} diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 860cf03169d..e81d72b7db3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -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 {