[PATCH 1/2] wined3d: Add a download function for WINED3DFMT_X8D24_UNORM.
Henri Verbeet
hverbeet at codeweavers.com
Fri Jan 5 11:53:12 CST 2018
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
For bug 43654.
---
dlls/wined3d/surface.c | 58 ++++++++++++++++++++++++++++++++++++------
dlls/wined3d/texture.c | 10 ++++----
dlls/wined3d/utils.c | 47 +++++++++++++++++++++++++++-------
dlls/wined3d/wined3d_private.h | 8 ++++--
4 files changed, 99 insertions(+), 24 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index da22c7ad9aa..2a90c12353a 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -546,7 +546,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
void *mem;
/* Only support read back of converted P8 surfaces. */
- if (texture->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT)
+ if (texture->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT && !format->download)
{
ERR("Trying to read back converted surface %p with format %s.\n", surface, debug_d3dformat(format->id));
return;
@@ -556,6 +556,12 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
if (surface->texture_target == GL_TEXTURE_2D_ARRAY)
{
+ if (format->download)
+ {
+ FIXME("Reading back converted array texture %p is not supported.\n", texture);
+ return;
+ }
+
/* NP2 emulation is not allowed on array textures. */
if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
ERR("Array texture %p uses NP2 emulation.\n", texture);
@@ -573,6 +579,12 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
{
+ if (format->download)
+ {
+ FIXME("Reading back converted texture %p with NP2 emulation is not supported.\n", texture);
+ return;
+ }
+
wined3d_texture_get_pitch(texture, surface->texture_level, &dst_row_pitch, &dst_slice_pitch);
wined3d_format_calculate_pitch(format, texture->resource.device->surface_alignment,
wined3d_texture_get_level_pow2_width(texture, surface->texture_level),
@@ -590,6 +602,30 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
ERR("Unexpected compressed format for NP2 emulated texture.\n");
}
+ if (format->download)
+ {
+ struct wined3d_format f;
+
+ if (data.buffer_object)
+ ERR("Converted texture %p uses PBO unexpectedly.\n", texture);
+
+ WARN_(d3d_perf)("Downloading converted surface %p with format %s.\n", surface, debug_d3dformat(format->id));
+
+ f = *format;
+ f.byte_count = format->conv_byte_count;
+ wined3d_texture_get_pitch(texture, surface->texture_level, &dst_row_pitch, &dst_slice_pitch);
+ wined3d_format_calculate_pitch(&f, texture->resource.device->surface_alignment,
+ wined3d_texture_get_level_width(texture, surface->texture_level),
+ wined3d_texture_get_level_height(texture, surface->texture_level),
+ &src_row_pitch, &src_slice_pitch);
+
+ if (!(temporary_mem = HeapAlloc(GetProcessHeap(), 0, src_slice_pitch)))
+ {
+ ERR("Failed to allocate memory.\n");
+ return;
+ }
+ }
+
if (temporary_mem)
{
mem = temporary_mem;
@@ -623,7 +659,13 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
checkGLcall("glGetTexImage");
}
- if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
+ if (format->download)
+ {
+ format->download(mem, data.addr, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch,
+ wined3d_texture_get_level_width(texture, surface->texture_level),
+ wined3d_texture_get_level_height(texture, surface->texture_level), 1);
+ }
+ else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
{
const BYTE *src_data;
unsigned int h, y;
@@ -1261,8 +1303,8 @@ static struct wined3d_texture *surface_convert_format(struct wined3d_texture *sr
DWORD map_binding;
if (!(conv = find_converter(src_format->id, dst_format->id)) && (!device->d3d_initialized
- || !is_identity_fixup(src_format->color_fixup) || src_format->convert
- || !is_identity_fixup(dst_format->color_fixup) || dst_format->convert
+ || !is_identity_fixup(src_format->color_fixup) || src_format->conv_byte_count
+ || !is_identity_fixup(dst_format->color_fixup) || dst_format->conv_byte_count
|| (src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)))
{
FIXME("Cannot find a conversion function from format %s to %s.\n",
@@ -2258,7 +2300,7 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
/* Don't use PBOs for converted surfaces. During PBO conversion we look at
* WINED3D_TEXTURE_CONVERTED but it isn't set (yet) in all cases it is
* getting called. */
- if ((format.convert || conversion) && texture->sub_resources[sub_resource_idx].buffer_object)
+ if ((format.conv_byte_count || conversion) && texture->sub_resources[sub_resource_idx].buffer_object)
{
TRACE("Removing the pbo attached to surface %p.\n", surface);
@@ -2267,7 +2309,7 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
}
wined3d_texture_get_memory(texture, sub_resource_idx, &data, sub_resource->locations);
- if (format.convert)
+ if (format.conv_byte_count)
{
/* This code is entered for texture formats which need a fixup. */
format.byte_count = format.conv_byte_count;
@@ -2281,7 +2323,7 @@ static BOOL surface_load_texture(struct wined3d_surface *surface,
context_release(context);
return FALSE;
}
- format.convert(src_mem, dst_mem, src_row_pitch, src_slice_pitch,
+ format.upload(src_mem, dst_mem, src_row_pitch, src_slice_pitch,
dst_row_pitch, dst_slice_pitch, width, height, 1);
src_row_pitch = dst_row_pitch;
context_unmap_bo_address(context, &data, GL_PIXEL_UNPACK_BUFFER);
@@ -3871,7 +3913,7 @@ HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst
TRACE("Not doing upload because of scaling.\n");
else if (convert)
TRACE("Not doing upload because of format conversion.\n");
- else if (dst_texture->resource.format->convert)
+ else if (dst_texture->resource.format->conv_byte_count)
TRACE("Not doing upload because the destination format needs conversion.\n");
else
{
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index ddbe340dc82..4dc739cc4c0 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -35,7 +35,7 @@ static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const
return texture->resource.pool == WINED3D_POOL_DEFAULT
&& texture->resource.access_flags & WINED3D_RESOURCE_ACCESS_CPU
&& gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]
- && !texture->resource.format->convert
+ && !texture->resource.format->conv_byte_count
&& !(texture->flags & (WINED3D_TEXTURE_PIN_SYSMEM | WINED3D_TEXTURE_COND_NP2_EMULATED));
}
@@ -1668,7 +1668,7 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi
TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id));
- if (format->convert)
+ if (format->conv_byte_count)
{
texture->flags |= WINED3D_TEXTURE_CONVERTED;
}
@@ -2306,7 +2306,7 @@ static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int
update_d = box->back - box->front;
}
- if (format->convert)
+ if (format->conv_byte_count)
{
if (data->buffer_object)
ERR("Loading a converted texture from a PBO.\n");
@@ -2317,7 +2317,7 @@ static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int
dst_slice_pitch = dst_row_pitch * update_h;
converted_mem = wined3d_calloc(update_d, dst_slice_pitch);
- format->convert(data->addr, converted_mem, row_pitch, slice_pitch,
+ format->upload(data->addr, converted_mem, row_pitch, slice_pitch,
dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
mem = converted_mem;
}
@@ -2354,7 +2354,7 @@ static void texture3d_download_data(struct wined3d_texture *texture, unsigned in
const struct wined3d_format *format = texture->resource.format;
const struct wined3d_gl_info *gl_info = context->gl_info;
- if (format->convert)
+ if (format->conv_byte_count)
{
FIXME("Attempting to download a converted volume, format %s.\n",
debug_d3dformat(format->id));
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index b3003f13028..8a96a20c117 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -434,8 +434,12 @@ struct wined3d_format_texture_info
unsigned int conv_byte_count;
unsigned int flags;
enum wined3d_gl_extension extension;
- void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
- UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth);
+ void (*upload)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch,
+ unsigned int dst_row_pitch, unsigned int dst_slice_pitch,
+ unsigned int width, unsigned int height, unsigned int depth);
+ void (*download)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch,
+ unsigned int dst_row_pitch, unsigned int dst_slice_pitch,
+ unsigned int width, unsigned int height, unsigned int depth);
};
static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
@@ -839,8 +843,32 @@ static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_p
}
}
-static void convert_x8_d24_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
- UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+static void x8_d24_unorm_upload(const BYTE *src, BYTE *dst,
+ unsigned int src_row_pitch, unsigned int src_slice_pitch,
+ unsigned int dst_row_pitch, unsigned int dst_slice_pitch,
+ unsigned int width, unsigned int height, unsigned int depth)
+{
+ unsigned int x, y, z;
+
+ for (z = 0; z < depth; ++z)
+ {
+ for (y = 0; y < height; ++y)
+ {
+ const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
+ DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
+
+ for (x = 0; x < width; ++x)
+ {
+ dest[x] = source[x] << 8 | ((source[x] >> 16) & 0xff);
+ }
+ }
+ }
+}
+
+static void x8_d24_unorm_download(const BYTE *src, BYTE *dst,
+ unsigned int src_row_pitch, unsigned int src_slice_pitch,
+ unsigned int dst_row_pitch, unsigned int dst_slice_pitch,
+ unsigned int width, unsigned int height, unsigned int depth)
{
unsigned int x, y, z;
@@ -853,7 +881,7 @@ static void convert_x8_d24_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch,
for (x = 0; x < width; ++x)
{
- dest[x] = source[x] << 8 | source[x] >> 16;
+ dest[x] = source[x] >> 8;
}
}
}
@@ -1088,7 +1116,7 @@ static const struct wined3d_format_texture_info format_texture_info[] =
/* format id gl_internal gl_srgb_internal gl_rt_internal
gl_format gl_type conv_byte_count
flags
- extension convert */
+ extension upload download */
/* FourCC formats */
/* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
* is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
@@ -1609,12 +1637,12 @@ static const struct wined3d_format_texture_info format_texture_info[] =
{WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 4,
WINED3DFMT_FLAG_DEPTH,
- WINED3D_GL_EXT_NONE, convert_x8_d24_unorm},
+ WINED3D_GL_EXT_NONE, x8_d24_unorm_upload, x8_d24_unorm_download},
{WINED3DFMT_X8D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 4,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
- ARB_DEPTH_TEXTURE, convert_x8_d24_unorm},
+ ARB_DEPTH_TEXTURE, x8_d24_unorm_upload, x8_d24_unorm_download},
{WINED3DFMT_S4X4_UINT_D24_UNORM, GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT24_ARB, 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0,
WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
@@ -2944,8 +2972,9 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
query_internal_format(adapter, format, &format_texture_info[i], gl_info, srgb_write, FALSE);
/* Texture conversion stuff */
- format->convert = format_texture_info[i].convert;
format->conv_byte_count = format_texture_info[i].conv_byte_count;
+ format->upload = format_texture_info[i].upload;
+ format->download = format_texture_info[i].download;
srgb_format = NULL;
for (j = 0; j < ARRAY_SIZE(format_srgb_info); ++j)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 20f53aa9e96..9f68b0ad30f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4240,8 +4240,12 @@ struct wined3d_format
float depth_bias_scale;
struct wined3d_rational height_scale;
struct color_fixup_desc color_fixup;
- void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
- UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth);
+ void (*upload)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch,
+ unsigned int dst_row_pitch, unsigned dst_slice_pitch,
+ unsigned int width, unsigned int height, unsigned int depth);
+ void (*download)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch,
+ unsigned int dst_row_pitch, unsigned dst_slice_pitch,
+ unsigned int width, unsigned int height, unsigned int depth);
enum wined3d_format_id typeless_id;
GLenum gl_view_class;
--
2.11.0
More information about the wine-devel
mailing list