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

wined3d: Add a download function for WINED3DFMT_X8D24_UNORM.

parent c1ff2f19
......@@ -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
{
......
......@@ -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));
......
......@@ -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)
......
......@@ -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;
......
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