wine-staging/patches/wined3d-1DTextures/0008-wined3d-Implement-downloading-from-s-rgb-1d-textures.patch
2018-03-16 14:23:41 +11:00

146 lines
5.3 KiB
Diff

From be0950f4dc83719ea9cbe322abb7affc327e1ef2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 27 Aug 2016 22:41:05 +0200
Subject: [PATCH] wined3d: Implement downloading from (s)rgb 1d textures to
system memory.
---
dlls/wined3d/texture.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 40ce11b..81a638e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1882,6 +1882,78 @@ 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)
+{
+ const struct wined3d_format *format = texture->resource.format;
+ unsigned int layer = sub_resource_idx / texture->level_count;
+ const struct wined3d_gl_info *gl_info = context->gl_info;
+ struct wined3d_texture_sub_resource *sub_resource;
+ BYTE *temporary_mem = NULL;
+ void *mem;
+ GLenum target;
+
+ sub_resource = &texture->sub_resources[sub_resource_idx];
+
+ if (format->conv_byte_count)
+ {
+ FIXME("Attempting to download a converted 1d texture, format %s.\n",
+ debug_d3dformat(format->id));
+ return;
+ }
+
+ target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
+ if (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 = heap_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(target, sub_resource_idx,
+ format->glFormat, format->glType, mem);
+ checkGLcall("glGetTexImage");
+
+ if (temporary_mem)
+ {
+ void *src_data = temporary_mem + 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)
{
@@ -1944,6 +2016,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