Module: wine Branch: master Commit: bb172d2a38f560b2f551804c3e68d6e03728f1f2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=bb172d2a38f560b2f551804c3e...
Author: Stefan Dösinger stefan@codeweavers.com Date: Mon Sep 23 13:29:12 2013 +0200
wined3d: Add support for converted volumes.
---
dlls/wined3d/directx.c | 12 ---------- dlls/wined3d/volume.c | 56 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 16 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 653d123..4a65993 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3874,18 +3874,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; }
- /* Filter formats that need conversion; For one part, this - * conversion is unimplemented, and volume textures are huge, so - * it would be a big performance hit. Unless we hit an application - * needing one of those formats, don't advertize them to avoid - * leading applications into temptation. The windows drivers don't - * support most of those formats on volumes anyway. */ - if (format->convert) - { - TRACE("[FAILED] - No converted formats on volumes.\n"); - return WINED3DERR_NOTAVAILABLE; - } - /* The GL_EXT_texture_compression_s3tc spec requires that loading * an s3tc compressed texture results in an error. While the D3D * refrast does support s3tc volumes, at least the nvidia Windows diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index ea481a1..b0dd756 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -102,11 +102,37 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine { const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format; + UINT width = volume->resource.width; + UINT height = volume->resource.height; + UINT depth = volume->resource.depth, z; + BYTE *mem = data->addr;
TRACE("volume %p, context %p, level %u, format %s (%#x).\n", volume, context, volume->texture_level, debug_d3dformat(format->id), format->id);
+ if (format->convert) + { + UINT dst_row_pitch, dst_slice_pitch; + UINT src_row_pitch, src_slice_pitch; + UINT alignment = volume->resource.device->surface_alignment; + + if (data->buffer_object) + ERR("Loading a converted volume from a PBO.\n"); + if (format->flags & WINED3DFMT_FLAG_BLOCKS) + ERR("Converting a block-based format.\n"); + + dst_row_pitch = width * format->conv_byte_count; + dst_row_pitch = (dst_row_pitch + alignment - 1) & ~(alignment - 1); + dst_slice_pitch = dst_row_pitch * height; + + wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch); + + mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth); + for (z = 0; z < depth; z++) + format->convert(data->addr + z * src_slice_pitch, mem + z * dst_slice_pitch, + src_row_pitch, dst_row_pitch, width, height); + }
if (data->buffer_object) { @@ -115,8 +141,8 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine }
GL_EXTCALL(glTexSubImage3DEXT(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0, - volume->resource.width, volume->resource.height, volume->resource.depth, - format->glFormat, format->glType, data->addr)); + width, height, depth, + format->glFormat, format->glType, mem)); checkGLcall("glTexSubImage3D");
if (data->buffer_object) @@ -124,6 +150,9 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0)); checkGLcall("glBindBufferARB"); } + + if (mem != data->addr) + HeapFree(GetProcessHeap(), 0, mem); }
static void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location) @@ -147,6 +176,13 @@ static void wined3d_volume_download_data(struct wined3d_volume *volume, const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_format *format = volume->resource.format;
+ if (format->convert) + { + FIXME("Attempting to download a converted volume, format %s.\n", + debug_d3dformat(format->id)); + return; + } + if (data->buffer_object) { GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, data->buffer_object)); @@ -218,6 +254,17 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume, HeapFree(GetProcessHeap(), 0, data.addr); }
+static BOOL wined3d_volume_can_evict(const struct wined3d_volume *volume) +{ + if (volume->resource.pool != WINED3D_POOL_MANAGED) + return FALSE; + if (volume->download_count >= 10) + return FALSE; + if (volume->resource.format->convert) + return FALSE; + + return TRUE; +} /* Context activation is done by the caller. */ static void wined3d_volume_load_location(struct wined3d_volume *volume, struct wined3d_context *context, DWORD location) @@ -280,7 +327,7 @@ static void wined3d_volume_load_location(struct wined3d_volume *volume, } wined3d_volume_validate_location(volume, location);
- if (volume->resource.pool == WINED3D_POOL_MANAGED && volume->download_count < 10) + if (wined3d_volume_can_evict(volume)) wined3d_volume_evict_sysmem(volume);
break; @@ -808,7 +855,8 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_device volume->locations = WINED3D_LOCATION_DISCARDED;
if (pool == WINED3D_POOL_DEFAULT && usage & WINED3DUSAGE_DYNAMIC - && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) + && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] + && !format->convert) { wined3d_resource_free_sysmem(&volume->resource); volume->flags |= WINED3D_VFLAG_PBO;