Commit 3d4001f4 authored by Connor McAdams's avatar Connor McAdams Committed by Alexandre Julliard

wined3d: Decompress DXTn 3D textures on upload.

parent 8a321bba
......@@ -477,3 +477,12 @@ void wined3d_resource_update_draw_binding(struct wined3d_resource *resource)
resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB;
}
}
const struct wined3d_format *wined3d_resource_get_decompress_format(struct wined3d_resource *resource,
const struct wined3d_context *context)
{
if (resource->format_flags & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE)
&& !(context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL))
return wined3d_get_format(context->gl_info, WINED3DFMT_B8G8R8A8_UNORM_SRGB, resource->usage);
return wined3d_get_format(context->gl_info, WINED3DFMT_B8G8R8A8_UNORM, resource->usage);
}
......@@ -1727,7 +1727,13 @@ void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct win
if (texture->flags & alloc_flag)
return;
if (format->conv_byte_count)
if (texture->resource.format_flags & WINED3DFMT_FLAG_DECOMPRESS)
{
TRACE("WINED3DFMT_FLAG_DECOMPRESS set.\n");
texture->flags |= WINED3D_TEXTURE_CONVERTED;
format = wined3d_resource_get_decompress_format(&texture->resource, context);
}
else if (format->conv_byte_count)
{
texture->flags |= WINED3D_TEXTURE_CONVERTED;
}
......@@ -1897,6 +1903,7 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
void *converted_mem = NULL;
struct wined3d_format f;
unsigned int level;
BOOL decompress;
GLenum target;
TRACE("texture %p, sub_resource_idx %u, context %p, format %s, src_box %s, data {%#x:%p}, "
......@@ -1948,20 +1955,31 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
bo.addr += src_box->left * format->byte_count;
}
if (format->upload)
decompress = texture->resource.format_flags & WINED3DFMT_FLAG_DECOMPRESS;
if (format->upload || decompress)
{
const struct wined3d_format *compressed_format = format;
unsigned int dst_row_pitch, dst_slice_pitch;
void *src_mem;
if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
ERR("Converting a block-based format.\n");
if (decompress)
{
format = wined3d_resource_get_decompress_format(&texture->resource, context);
}
else
{
if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
ERR("Converting a block-based format.\n");
f = *format;
f.byte_count = format->conv_byte_count;
format = &f;
f = *format;
f.byte_count = format->conv_byte_count;
format = &f;
}
wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch);
/* Note that uploading 3D textures may require quite some address
* space; it may make sense to upload them per-slice instead. */
if (!(converted_mem = heap_calloc(update_d, dst_slice_pitch)))
{
ERR("Failed to allocate upload buffer.\n");
......@@ -1970,8 +1988,12 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
src_mem = context_map_bo_address(context, &bo, src_slice_pitch,
GL_PIXEL_UNPACK_BUFFER, WINED3D_MAP_READ);
format->upload(src_mem, converted_mem, src_row_pitch, src_slice_pitch,
dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
if (decompress)
compressed_format->decompress(src_mem, converted_mem, src_row_pitch, src_slice_pitch,
dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
else
format->upload(src_mem, converted_mem, src_row_pitch, src_slice_pitch,
dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
context_unmap_bo_address(context, &bo, GL_PIXEL_UNPACK_BUFFER);
bo.buffer_object = 0;
......
......@@ -3081,6 +3081,8 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
const struct wined3d_format *wined3d_resource_get_decompress_format(struct wined3d_resource *resource,
const struct wined3d_context *context) DECLSPEC_HIDDEN;
GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN;
GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN;
BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
......@@ -4231,6 +4233,7 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN
#define WINED3DFMT_FLAG_EXTENSION 0x00000020
#define WINED3DFMT_FLAG_FBO_ATTACHABLE 0x00000040
#define WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB 0x00000080
#define WINED3DFMT_FLAG_DECOMPRESS 0x00000100
#define WINED3DFMT_FLAG_FLOAT 0x00000200
#define WINED3DFMT_FLAG_BUMPMAP 0x00000400
#define WINED3DFMT_FLAG_SRGB_READ 0x00000800
......@@ -4304,6 +4307,9 @@ struct wined3d_format
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);
void (*decompress)(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