From 8efaebed047f1b3a466f74fc982e5a3b22326ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sat, 27 Aug 2016 22:41:05 +0200 Subject: [PATCH 08/17] wined3d: Implement downloading from (s)rgb 1d textures to system memory. --- dlls/wined3d/texture.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index c5a4f0c..198d2a6 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1728,6 +1728,76 @@ static void texture1d_upload_data(struct wined3d_texture *texture, unsigned int } /* Context activation is done by the caller. */ +static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, + const struct wined3d_context *context, const struct wined3d_bo_address *data) +{ + struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface; + const struct wined3d_format *format = texture->resource.format; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_texture_sub_resource *sub_resource; + BYTE *temporary_mem = NULL; + void *mem; + + sub_resource = &texture->sub_resources[sub_resource_idx]; + + if (format->convert) + { + FIXME("Attempting to download a converted 1d texture, format %s.\n", + debug_d3dformat(format->id)); + return; + } + + if (surface->texture_target == GL_TEXTURE_1D_ARRAY) + { + WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n"); + + if (!(temporary_mem = wined3d_calloc(texture->layer_count, sub_resource->size))) + { + ERR("Out of memory.\n"); + return; + } + + mem = temporary_mem; + } + else if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + mem = data->addr; + } + else + mem = data->addr; + + gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, sub_resource_idx, + format->glFormat, format->glType, mem); + checkGLcall("glGetTexImage"); + + if (temporary_mem) + { + void *src_data = temporary_mem + surface->texture_layer * sub_resource->size; + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object)); + checkGLcall("glBindBuffer"); + GL_EXTCALL(glBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, src_data)); + checkGLcall("glBufferSubData"); + } + else + { + memcpy(data->addr, src_data, sub_resource->size); + } + } + + if (data->buffer_object) + { + GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)); + checkGLcall("glBindBuffer"); + } + + HeapFree(GetProcessHeap(), 0, temporary_mem); +} + +/* Context activation is done by the caller. */ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location) { @@ -1790,6 +1860,48 @@ static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned in } break; + case WINED3D_LOCATION_SYSMEM: + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { + struct wined3d_bo_address data = {0, texture->resource.heap_memory}; + + data.addr += sub_resource->offset; + if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_texture_bind_and_dirtify(texture, context, FALSE); + else + wined3d_texture_bind_and_dirtify(texture, context, TRUE); + + texture1d_download_data(texture, sub_resource_idx, context, &data); + ++texture->download_count; + } + else + { + FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n", + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; + + case WINED3D_LOCATION_BUFFER: + if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB)) + { + struct wined3d_bo_address data = {sub_resource->buffer_object, NULL}; + + if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB) + wined3d_texture_bind_and_dirtify(texture, context, FALSE); + else + wined3d_texture_bind_and_dirtify(texture, context, TRUE); + + texture1d_download_data(texture, sub_resource_idx, context, &data); + } + else + { + FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n", + wined3d_debug_location(sub_resource->locations)); + return FALSE; + } + break; + default: FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location), wined3d_debug_location(sub_resource->locations)); -- 1.9.1