wined3d: Merge volumetexture_init() and texture_init().

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2018-03-16 13:38:26 +03:30 committed by Alexandre Julliard
parent 0a354365bd
commit eba15f7042
1 changed files with 40 additions and 120 deletions

View File

@ -2175,7 +2175,7 @@ static const struct wined3d_resource_ops texture_resource_ops =
static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device, unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device,
void *parent, const struct wined3d_parent_ops *parent_ops) void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_texture_ops *texture_ops)
{ {
struct wined3d_device_parent *device_parent = device->device_parent; struct wined3d_device_parent *device_parent = device->device_parent;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
@ -2183,6 +2183,21 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
unsigned int sub_count, i; unsigned int sub_count, i;
HRESULT hr; HRESULT hr;
if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
{
if (layer_count != 1)
{
ERR("Invalid layer count for volume texture.\n");
return E_INVALIDARG;
}
if (!gl_info->supported[EXT_TEXTURE3D])
{
WARN("OpenGL implementation does not support 3D textures.\n");
return WINED3DERR_INVALIDCALL;
}
}
if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1 if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1
&& !gl_info->supported[EXT_TEXTURE_ARRAY]) && !gl_info->supported[EXT_TEXTURE_ARRAY])
{ {
@ -2194,7 +2209,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
* that are reported as supported. */ * that are reported as supported. */
if (WINED3DFMT_UNKNOWN >= desc->format) if (WINED3DFMT_UNKNOWN >= desc->format)
{ {
WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); WARN("Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n");
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
@ -2214,15 +2229,16 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
pow2_width = desc->width; pow2_width = desc->width;
pow2_height = desc->height; pow2_height = desc->height;
if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1))) if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1)) || (desc->depth & (desc->depth - 1)))
&& !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
{ {
/* level_count == 0 returns an error as well. */ /* level_count == 0 returns an error as well. */
if (level_count != 1 || layer_count != 1) if (level_count != 1 || layer_count != 1 || desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
{ {
if (!(desc->usage & WINED3DUSAGE_SCRATCH)) if (!(desc->usage & WINED3DUSAGE_SCRATCH))
{ {
WARN("Attempted to create a mipmapped/cube/array NPOT texture without unconditional NPOT support.\n"); WARN("Attempted to create a mipmapped/cube/array/volume NPOT "
"texture without unconditional NPOT support.\n");
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
@ -2230,7 +2246,8 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
} }
texture->flags |= WINED3D_TEXTURE_COND_NP2; texture->flags |= WINED3D_TEXTURE_COND_NP2;
if (!gl_info->supported[ARB_TEXTURE_RECTANGLE] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !gl_info->supported[ARB_TEXTURE_RECTANGLE]
&& !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
{ {
const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format, desc->usage); const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format, desc->usage);
@ -2278,7 +2295,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height); TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height);
} }
if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc, if (FAILED(hr = wined3d_texture_init(texture, texture_ops, layer_count, level_count, desc,
flags, device, parent, parent_ops, &texture_resource_ops))) flags, device, parent, parent_ops, &texture_resource_ops)))
{ {
WARN("Failed to initialize texture, returning %#x.\n", hr); WARN("Failed to initialize texture, returning %#x.\n", hr);
@ -2306,7 +2323,11 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
texture->pow2_matrix[0] = 1.0f; texture->pow2_matrix[0] = 1.0f;
texture->pow2_matrix[5] = 1.0f; texture->pow2_matrix[5] = 1.0f;
} }
if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
{
texture->target = GL_TEXTURE_3D;
}
else if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
{ {
texture->target = GL_TEXTURE_CUBE_MAP_ARB; texture->target = GL_TEXTURE_CUBE_MAP_ARB;
} }
@ -2330,7 +2351,12 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]); TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]);
if (wined3d_texture_use_pbo(texture, gl_info)) if (wined3d_texture_use_pbo(texture, gl_info))
{
if (desc->resource_type == WINED3D_RTYPE_TEXTURE_3D
|| (texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
wined3d_resource_free_sysmem(&texture->resource);
texture->resource.map_binding = WINED3D_LOCATION_BUFFER; texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
}
sub_count = level_count * layer_count; sub_count = level_count * layer_count;
if (sub_count / layer_count != level_count) if (sub_count / layer_count != level_count)
@ -2361,7 +2387,8 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
sub_resource = &texture->sub_resources[i]; sub_resource = &texture->sub_resources[i];
sub_resource->locations = WINED3D_LOCATION_DISCARDED; sub_resource->locations = WINED3D_LOCATION_DISCARDED;
if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)) if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D
&& !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
{ {
wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_SYSMEM); wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_SYSMEM);
wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_SYSMEM); wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_SYSMEM);
@ -2677,115 +2704,6 @@ static const struct wined3d_texture_ops texture3d_ops =
texture3d_prepare_texture, texture3d_prepare_texture,
}; };
static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc,
UINT layer_count, UINT level_count, DWORD flags, struct wined3d_device *device, void *parent,
const struct wined3d_parent_ops *parent_ops)
{
struct wined3d_device_parent *device_parent = device->device_parent;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
unsigned int i;
HRESULT hr;
if (layer_count != 1)
{
ERR("Invalid layer count for volume texture.\n");
return E_INVALIDARG;
}
/* TODO: It should only be possible to create textures for formats
* that are reported as supported. */
if (WINED3DFMT_UNKNOWN >= desc->format)
{
WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
return WINED3DERR_INVALIDCALL;
}
if (!gl_info->supported[EXT_TEXTURE3D])
{
WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture);
return WINED3DERR_INVALIDCALL;
}
if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access)
|| desc->usage & WINED3DUSAGE_SCRATCH))
{
WARN("Attempted to create a DYNAMIC texture with access %s.\n",
wined3d_debug_resource_access(desc->access));
return WINED3DERR_INVALIDCALL;
}
if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
{
UINT pow2_w, pow2_h, pow2_d;
pow2_w = 1;
while (pow2_w < desc->width)
pow2_w <<= 1;
pow2_h = 1;
while (pow2_h < desc->height)
pow2_h <<= 1;
pow2_d = 1;
while (pow2_d < desc->depth)
pow2_d <<= 1;
if (pow2_w != desc->width || pow2_h != desc->height || pow2_d != desc->depth)
{
if (desc->usage & WINED3DUSAGE_SCRATCH)
{
WARN("Creating a scratch NPOT volume texture despite lack of HW support.\n");
}
else
{
WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n",
desc->width, desc->height, desc->depth);
return WINED3DERR_INVALIDCALL;
}
}
}
if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, level_count, desc,
flags, device, parent, parent_ops, &texture_resource_ops)))
{
WARN("Failed to initialize texture, returning %#x.\n", hr);
return hr;
}
texture->pow2_matrix[0] = 1.0f;
texture->pow2_matrix[5] = 1.0f;
texture->pow2_matrix[10] = 1.0f;
texture->pow2_matrix[15] = 1.0f;
texture->target = GL_TEXTURE_3D;
if (wined3d_texture_use_pbo(texture, gl_info))
{
wined3d_resource_free_sysmem(&texture->resource);
texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
}
/* Generate all the sub resources. */
for (i = 0; i < texture->level_count; ++i)
{
struct wined3d_texture_sub_resource *sub_resource;
sub_resource = &texture->sub_resources[i];
sub_resource->locations = WINED3D_LOCATION_DISCARDED;
if (FAILED(hr = device_parent->ops->texture_sub_resource_created(device_parent,
desc->resource_type, texture, i, &sub_resource->parent, &sub_resource->parent_ops)))
{
WARN("Failed to create volume parent, hr %#x.\n", hr);
sub_resource->parent = NULL;
wined3d_texture_cleanup_sync(texture);
return hr;
}
TRACE("parent %p, parent_ops %p.\n", parent, parent_ops);
TRACE("Created volume level %u.\n", i);
}
return WINED3D_OK;
}
HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter) const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
@ -3082,11 +3000,13 @@ HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct
switch (desc->resource_type) switch (desc->resource_type)
{ {
case WINED3D_RTYPE_TEXTURE_2D: case WINED3D_RTYPE_TEXTURE_2D:
hr = texture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops); hr = texture_init(object, desc, layer_count, level_count,
flags, device, parent, parent_ops, &texture2d_ops);
break; break;
case WINED3D_RTYPE_TEXTURE_3D: case WINED3D_RTYPE_TEXTURE_3D:
hr = volumetexture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops); hr = texture_init(object, desc, layer_count, level_count,
flags, device, parent, parent_ops, &texture3d_ops);
break; break;
default: default: