wined3d: Add support for converted volumes.
This commit is contained in:
parent
78fe60ac76
commit
bb172d2a38
|
@ -3874,18 +3874,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
|
||||||
return WINED3DERR_NOTAVAILABLE;
|
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
|
/* The GL_EXT_texture_compression_s3tc spec requires that loading
|
||||||
* an s3tc compressed texture results in an error. While the D3D
|
* an s3tc compressed texture results in an error. While the D3D
|
||||||
* refrast does support s3tc volumes, at least the nvidia Windows
|
* refrast does support s3tc volumes, at least the nvidia Windows
|
||||||
|
|
|
@ -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_gl_info *gl_info = context->gl_info;
|
||||||
const struct wined3d_format *format = volume->resource.format;
|
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",
|
TRACE("volume %p, context %p, level %u, format %s (%#x).\n",
|
||||||
volume, context, volume->texture_level, debug_d3dformat(format->id),
|
volume, context, volume->texture_level, debug_d3dformat(format->id),
|
||||||
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)
|
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,
|
GL_EXTCALL(glTexSubImage3DEXT(GL_TEXTURE_3D, volume->texture_level, 0, 0, 0,
|
||||||
volume->resource.width, volume->resource.height, volume->resource.depth,
|
width, height, depth,
|
||||||
format->glFormat, format->glType, data->addr));
|
format->glFormat, format->glType, mem));
|
||||||
checkGLcall("glTexSubImage3D");
|
checkGLcall("glTexSubImage3D");
|
||||||
|
|
||||||
if (data->buffer_object)
|
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));
|
GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
|
||||||
checkGLcall("glBindBufferARB");
|
checkGLcall("glBindBufferARB");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mem != data->addr)
|
||||||
|
HeapFree(GetProcessHeap(), 0, mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wined3d_volume_validate_location(struct wined3d_volume *volume, DWORD location)
|
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_gl_info *gl_info = context->gl_info;
|
||||||
const struct wined3d_format *format = volume->resource.format;
|
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)
|
if (data->buffer_object)
|
||||||
{
|
{
|
||||||
GL_EXTCALL(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 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);
|
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. */
|
/* Context activation is done by the caller. */
|
||||||
static void wined3d_volume_load_location(struct wined3d_volume *volume,
|
static void wined3d_volume_load_location(struct wined3d_volume *volume,
|
||||||
struct wined3d_context *context, DWORD location)
|
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);
|
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);
|
wined3d_volume_evict_sysmem(volume);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -808,7 +855,8 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_device
|
||||||
volume->locations = WINED3D_LOCATION_DISCARDED;
|
volume->locations = WINED3D_LOCATION_DISCARDED;
|
||||||
|
|
||||||
if (pool == WINED3D_POOL_DEFAULT && usage & WINED3DUSAGE_DYNAMIC
|
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);
|
wined3d_resource_free_sysmem(&volume->resource);
|
||||||
volume->flags |= WINED3D_VFLAG_PBO;
|
volume->flags |= WINED3D_VFLAG_PBO;
|
||||||
|
|
Loading…
Reference in New Issue