wined3d: Merge wined3d_volume_load_location() into texture3d_load_location().
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d262a18311
commit
2337c50ed7
|
@ -80,6 +80,27 @@ GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture)
|
|||
return GL_BACK;
|
||||
}
|
||||
|
||||
static DWORD wined3d_resource_access_from_location(DWORD location)
|
||||
{
|
||||
switch (location)
|
||||
{
|
||||
case WINED3D_LOCATION_DISCARDED:
|
||||
return 0;
|
||||
|
||||
case WINED3D_LOCATION_SYSMEM:
|
||||
return WINED3D_RESOURCE_ACCESS_CPU;
|
||||
|
||||
case WINED3D_LOCATION_BUFFER:
|
||||
case WINED3D_LOCATION_TEXTURE_RGB:
|
||||
case WINED3D_LOCATION_TEXTURE_SRGB:
|
||||
return WINED3D_RESOURCE_ACCESS_GPU;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled location %#x.\n", location);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture)
|
||||
{
|
||||
struct wined3d_texture_sub_resource *sub_resource;
|
||||
|
@ -2095,10 +2116,186 @@ static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int
|
|||
wined3d_volume_upload_data(texture, sub_resource_idx, context, &addr);
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static void texture3d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
|
||||
const struct wined3d_context *context, const struct wined3d_bo_address *data)
|
||||
{
|
||||
const struct wined3d_format *format = texture->resource.format;
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
|
||||
if (format->convert)
|
||||
{
|
||||
FIXME("Attempting to download a converted volume, format %s.\n",
|
||||
debug_d3dformat(format->id));
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
}
|
||||
|
||||
gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, sub_resource_idx,
|
||||
format->glFormat, format->glType, data->addr);
|
||||
checkGLcall("glGetTexImage");
|
||||
|
||||
if (data->buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
|
||||
checkGLcall("glBindBuffer");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx,
|
||||
struct wined3d_context *context, BOOL dest_is_srgb)
|
||||
{
|
||||
struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
|
||||
struct wined3d_bo_address data;
|
||||
|
||||
/* Optimisations are possible, but the effort should be put into either
|
||||
* implementing EXT_SRGB_DECODE in the driver or finding out why we
|
||||
* picked the wrong copy for the original upload and fixing that.
|
||||
*
|
||||
* Also keep in mind that we want to avoid using resource.heap_memory
|
||||
* for DEFAULT pool surfaces. */
|
||||
WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n");
|
||||
data.buffer_object = 0;
|
||||
if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size)))
|
||||
return;
|
||||
|
||||
wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb);
|
||||
texture3d_download_data(texture, sub_resource_idx, context, &data);
|
||||
wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb);
|
||||
wined3d_volume_upload_data(texture, sub_resource_idx, context, wined3d_const_bo_address(&data));
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data.addr);
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
|
||||
struct wined3d_context *context, DWORD location)
|
||||
{
|
||||
return wined3d_volume_load_location(texture->sub_resources[sub_resource_idx].u.volume, context, location);
|
||||
struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
|
||||
DWORD required_access = wined3d_resource_access_from_location(location);
|
||||
|
||||
TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
|
||||
texture, sub_resource_idx, context, wined3d_debug_location(location));
|
||||
|
||||
TRACE("Current resource location %s.\n", wined3d_debug_location(sub_resource->locations));
|
||||
|
||||
if ((sub_resource->locations & location) == location)
|
||||
{
|
||||
TRACE("Location(s) already up to date.\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((texture->resource.access_flags & required_access) != required_access)
|
||||
{
|
||||
ERR("Operation requires %#x access, but volume only has %#x.\n",
|
||||
required_access, texture->resource.access_flags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
|
||||
return FALSE;
|
||||
|
||||
if (sub_resource->locations & WINED3D_LOCATION_DISCARDED)
|
||||
{
|
||||
TRACE("Volume previously discarded, nothing to do.\n");
|
||||
wined3d_texture_validate_location(texture, sub_resource_idx, location);
|
||||
wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED);
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (location)
|
||||
{
|
||||
case WINED3D_LOCATION_TEXTURE_RGB:
|
||||
case WINED3D_LOCATION_TEXTURE_SRGB:
|
||||
if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
|
||||
{
|
||||
struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
|
||||
data.addr += sub_resource->offset;
|
||||
wined3d_texture_bind_and_dirtify(texture, context,
|
||||
location == WINED3D_LOCATION_TEXTURE_SRGB);
|
||||
wined3d_volume_upload_data(texture, sub_resource_idx, context, &data);
|
||||
}
|
||||
else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
|
||||
{
|
||||
struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
|
||||
wined3d_texture_bind_and_dirtify(texture, context,
|
||||
location == WINED3D_LOCATION_TEXTURE_SRGB);
|
||||
wined3d_volume_upload_data(texture, sub_resource_idx, context, &data);
|
||||
}
|
||||
else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
|
||||
{
|
||||
texture3d_srgb_transfer(texture, sub_resource_idx, context, TRUE);
|
||||
}
|
||||
else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB)
|
||||
{
|
||||
texture3d_srgb_transfer(texture, sub_resource_idx, context, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WINED3D_LOCATION_SYSMEM:
|
||||
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
|
||||
{
|
||||
struct wined3d_bo_address data = {0, texture->resource.heap_memory};
|
||||
|
||||
data.addr += sub_resource->offset;
|
||||
if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
|
||||
wined3d_texture_bind_and_dirtify(texture, context, FALSE);
|
||||
else
|
||||
wined3d_texture_bind_and_dirtify(texture, context, TRUE);
|
||||
|
||||
texture3d_download_data(texture, sub_resource_idx, context, &data);
|
||||
++texture->download_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
|
||||
wined3d_debug_location(sub_resource->locations));
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WINED3D_LOCATION_BUFFER:
|
||||
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
|
||||
{
|
||||
struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
|
||||
|
||||
if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
|
||||
wined3d_texture_bind_and_dirtify(texture, context, FALSE);
|
||||
else
|
||||
wined3d_texture_bind_and_dirtify(texture, context, TRUE);
|
||||
|
||||
texture3d_download_data(texture, sub_resource_idx, context, &data);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
|
||||
wined3d_debug_location(sub_resource->locations));
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
|
||||
wined3d_debug_location(sub_resource->locations));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
done:
|
||||
wined3d_texture_validate_location(texture, sub_resource_idx, location);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "wined3d_private.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
|
||||
|
||||
/* This call just uploads data, the caller is responsible for binding the
|
||||
* correct texture. */
|
||||
|
@ -86,208 +85,3 @@ void wined3d_volume_upload_data(struct wined3d_texture *texture, unsigned int su
|
|||
|
||||
HeapFree(GetProcessHeap(), 0, converted_mem);
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static void texture3d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
|
||||
const struct wined3d_context *context, const struct wined3d_bo_address *data)
|
||||
{
|
||||
const struct wined3d_format *format = texture->resource.format;
|
||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||
|
||||
if (format->convert)
|
||||
{
|
||||
FIXME("Attempting to download a converted volume, format %s.\n",
|
||||
debug_d3dformat(format->id));
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
|
||||
checkGLcall("glBindBuffer");
|
||||
}
|
||||
|
||||
gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, sub_resource_idx,
|
||||
format->glFormat, format->glType, data->addr);
|
||||
checkGLcall("glGetTexImage");
|
||||
|
||||
if (data->buffer_object)
|
||||
{
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
|
||||
checkGLcall("glBindBuffer");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static DWORD volume_access_from_location(DWORD location)
|
||||
{
|
||||
switch (location)
|
||||
{
|
||||
case WINED3D_LOCATION_DISCARDED:
|
||||
return 0;
|
||||
|
||||
case WINED3D_LOCATION_SYSMEM:
|
||||
return WINED3D_RESOURCE_ACCESS_CPU;
|
||||
|
||||
case WINED3D_LOCATION_BUFFER:
|
||||
case WINED3D_LOCATION_TEXTURE_RGB:
|
||||
case WINED3D_LOCATION_TEXTURE_SRGB:
|
||||
return WINED3D_RESOURCE_ACCESS_GPU;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled location %#x.\n", location);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx,
|
||||
struct wined3d_context *context, BOOL dest_is_srgb)
|
||||
{
|
||||
struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
|
||||
struct wined3d_bo_address data;
|
||||
|
||||
/* Optimizations are possible, but the effort should be put into either
|
||||
* implementing EXT_SRGB_DECODE in the driver or finding out why we
|
||||
* picked the wrong copy for the original upload and fixing that.
|
||||
*
|
||||
* Also keep in mind that we want to avoid using resource.heap_memory
|
||||
* for DEFAULT pool surfaces. */
|
||||
|
||||
WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n");
|
||||
data.buffer_object = 0;
|
||||
if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size)))
|
||||
return;
|
||||
|
||||
wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb);
|
||||
texture3d_download_data(texture, sub_resource_idx, context, &data);
|
||||
wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb);
|
||||
wined3d_volume_upload_data(texture, sub_resource_idx, context, wined3d_const_bo_address(&data));
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data.addr);
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
|
||||
struct wined3d_context *context, DWORD location)
|
||||
{
|
||||
DWORD required_access = volume_access_from_location(location);
|
||||
unsigned int sub_resource_idx = volume->texture_level;
|
||||
struct wined3d_texture *texture = volume->container;
|
||||
struct wined3d_texture_sub_resource *sub_resource;
|
||||
|
||||
sub_resource = &texture->sub_resources[sub_resource_idx];
|
||||
TRACE("Volume %p, loading %s, have %s.\n", volume, wined3d_debug_location(location),
|
||||
wined3d_debug_location(sub_resource->locations));
|
||||
|
||||
if ((sub_resource->locations & location) == location)
|
||||
{
|
||||
TRACE("Location(s) already up to date.\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((texture->resource.access_flags & required_access) != required_access)
|
||||
{
|
||||
ERR("Operation requires %#x access, but volume only has %#x.\n",
|
||||
required_access, texture->resource.access_flags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
|
||||
return FALSE;
|
||||
|
||||
if (sub_resource->locations & WINED3D_LOCATION_DISCARDED)
|
||||
{
|
||||
TRACE("Volume previously discarded, nothing to do.\n");
|
||||
wined3d_texture_validate_location(texture, sub_resource_idx, location);
|
||||
wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED);
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (location)
|
||||
{
|
||||
case WINED3D_LOCATION_TEXTURE_RGB:
|
||||
case WINED3D_LOCATION_TEXTURE_SRGB:
|
||||
if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
|
||||
{
|
||||
struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
|
||||
data.addr += sub_resource->offset;
|
||||
wined3d_texture_bind_and_dirtify(texture, context,
|
||||
location == WINED3D_LOCATION_TEXTURE_SRGB);
|
||||
wined3d_volume_upload_data(texture, sub_resource_idx, context, &data);
|
||||
}
|
||||
else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
|
||||
{
|
||||
struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
|
||||
wined3d_texture_bind_and_dirtify(texture, context,
|
||||
location == WINED3D_LOCATION_TEXTURE_SRGB);
|
||||
wined3d_volume_upload_data(texture, sub_resource_idx, context, &data);
|
||||
}
|
||||
else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
|
||||
{
|
||||
texture3d_srgb_transfer(texture, sub_resource_idx, context, TRUE);
|
||||
}
|
||||
else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB)
|
||||
{
|
||||
texture3d_srgb_transfer(texture, sub_resource_idx, context, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WINED3D_LOCATION_SYSMEM:
|
||||
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
|
||||
{
|
||||
struct wined3d_bo_address data = {0, texture->resource.heap_memory};
|
||||
|
||||
data.addr += sub_resource->offset;
|
||||
if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
|
||||
wined3d_texture_bind_and_dirtify(texture, context, FALSE);
|
||||
else
|
||||
wined3d_texture_bind_and_dirtify(texture, context, TRUE);
|
||||
|
||||
texture3d_download_data(texture, sub_resource_idx, context, &data);
|
||||
++texture->download_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
|
||||
wined3d_debug_location(sub_resource->locations));
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WINED3D_LOCATION_BUFFER:
|
||||
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
|
||||
{
|
||||
struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
|
||||
|
||||
if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
|
||||
wined3d_texture_bind_and_dirtify(texture, context, FALSE);
|
||||
else
|
||||
wined3d_texture_bind_and_dirtify(texture, context, TRUE);
|
||||
|
||||
texture3d_download_data(texture, sub_resource_idx, context, &data);
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
|
||||
wined3d_debug_location(sub_resource->locations));
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
|
||||
wined3d_debug_location(sub_resource->locations));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
done:
|
||||
wined3d_texture_validate_location(texture, sub_resource_idx, location);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -2786,8 +2786,6 @@ struct wined3d_volume
|
|||
GLint texture_level;
|
||||
};
|
||||
|
||||
BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
|
||||
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
|
||||
void wined3d_volume_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
|
||||
const struct wined3d_context *context, const struct wined3d_const_bo_address *data) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
Loading…
Reference in New Issue