wined3d: Allocate system memory for complete textures.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e6780a5e05
commit
3b96ac290d
|
@ -7929,7 +7929,7 @@ static void test_miptree_layout(void)
|
|||
if (!i)
|
||||
base = map_desc.pBits;
|
||||
else
|
||||
todo_wine ok(map_desc.pBits == base + offset,
|
||||
ok(map_desc.pBits == base + offset,
|
||||
"%s, %s, level %u: Got unexpected pBits %p, expected %p.\n",
|
||||
pools[pool_idx].name, formats[format_idx].name, i, map_desc.pBits, base + offset);
|
||||
offset += (base_dimension >> i) * map_desc.Pitch;
|
||||
|
@ -7968,7 +7968,7 @@ static void test_miptree_layout(void)
|
|||
if (!i && !j)
|
||||
base = map_desc.pBits;
|
||||
else
|
||||
todo_wine ok(map_desc.pBits == base + offset,
|
||||
ok(map_desc.pBits == base + offset,
|
||||
"%s, %s, face %u, level %u: Got unexpected pBits %p, expected %p.\n",
|
||||
pools[pool_idx].name, formats[format_idx].name, i, j, map_desc.pBits, base + offset);
|
||||
offset += (base_dimension >> j) * map_desc.Pitch;
|
||||
|
|
|
@ -11060,7 +11060,7 @@ static void test_miptree_layout(void)
|
|||
if (!i)
|
||||
base = map_desc.pBits;
|
||||
else
|
||||
todo_wine ok(map_desc.pBits == base + offset,
|
||||
ok(map_desc.pBits == base + offset,
|
||||
"%s, %s, level %u: Got unexpected pBits %p, expected %p.\n",
|
||||
pools[pool_idx].name, formats[format_idx].name, i, map_desc.pBits, base + offset);
|
||||
offset += (base_dimension >> i) * map_desc.Pitch;
|
||||
|
@ -11099,7 +11099,7 @@ static void test_miptree_layout(void)
|
|||
if (!i && !j)
|
||||
base = map_desc.pBits;
|
||||
else
|
||||
todo_wine ok(map_desc.pBits == base + offset,
|
||||
ok(map_desc.pBits == base + offset,
|
||||
"%s, %s, face %u, level %u: Got unexpected pBits %p, expected %p.\n",
|
||||
pools[pool_idx].name, formats[format_idx].name, i, j, map_desc.pBits, base + offset);
|
||||
offset += (base_dimension >> j) * map_desc.Pitch;
|
||||
|
|
|
@ -398,7 +398,7 @@ HRESULT wined3d_surface_create_dc(struct wined3d_surface *surface)
|
|||
}
|
||||
|
||||
wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
|
||||
desc.pMemory = wined3d_texture_map_bo_address(&data, surface->resource.size,
|
||||
desc.pMemory = wined3d_texture_map_bo_address(&data, texture->sub_resources[sub_resource_idx].size,
|
||||
gl_info, GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
if (context)
|
||||
|
@ -2746,21 +2746,21 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD
|
|||
unsigned int sub_resource_idx = surface_get_sub_resource_idx(surface);
|
||||
struct wined3d_texture *texture = surface->container;
|
||||
struct wined3d_device *device = texture->resource.device;
|
||||
struct wined3d_texture_sub_resource *sub_resource;
|
||||
struct wined3d_context *context;
|
||||
const struct wined3d_gl_info *gl_info;
|
||||
struct wined3d_bo_address dst, src;
|
||||
UINT size = surface->resource.size;
|
||||
|
||||
sub_resource = &texture->sub_resources[sub_resource_idx];
|
||||
wined3d_texture_get_memory(texture, sub_resource_idx, &dst, location);
|
||||
wined3d_texture_get_memory(texture, sub_resource_idx, &src,
|
||||
texture->sub_resources[sub_resource_idx].locations);
|
||||
wined3d_texture_get_memory(texture, sub_resource_idx, &src, sub_resource->locations);
|
||||
|
||||
if (dst.buffer_object)
|
||||
{
|
||||
context = context_acquire(device, NULL);
|
||||
gl_info = context->gl_info;
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object));
|
||||
GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr));
|
||||
GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, sub_resource->size, src.addr));
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
|
||||
checkGLcall("Upload PBO");
|
||||
context_release(context);
|
||||
|
@ -2771,13 +2771,13 @@ static void surface_copy_simple_location(struct wined3d_surface *surface, DWORD
|
|||
context = context_acquire(device, NULL);
|
||||
gl_info = context->gl_info;
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object));
|
||||
GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr));
|
||||
GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, dst.addr));
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
|
||||
checkGLcall("Download PBO");
|
||||
context_release(context);
|
||||
return;
|
||||
}
|
||||
memcpy(dst.addr, src.addr, size);
|
||||
memcpy(dst.addr, src.addr, sub_resource->size);
|
||||
}
|
||||
|
||||
/* Context activation is done by the caller. */
|
||||
|
@ -4316,16 +4316,11 @@ HRESULT wined3d_surface_init(struct wined3d_surface *surface, struct wined3d_tex
|
|||
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
||||
const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format);
|
||||
UINT multisample_quality = desc->multisample_quality;
|
||||
unsigned int resource_size;
|
||||
HRESULT hr;
|
||||
|
||||
resource_size = wined3d_format_calculate_size(format, device->surface_alignment, desc->width, desc->height, 1);
|
||||
if (!resource_size)
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (FAILED(hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE,
|
||||
format, desc->multisample_type, multisample_quality, desc->usage, desc->pool, desc->width, desc->height,
|
||||
1, resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops)))
|
||||
1, 0, NULL, &wined3d_null_parent_ops, &surface_resource_ops)))
|
||||
{
|
||||
WARN("Failed to initialize resource, returning %#x.\n", hr);
|
||||
return hr;
|
||||
|
|
|
@ -703,15 +703,15 @@ static void swapchain_gdi_present(struct wined3d_swapchain *swapchain,
|
|||
/* Flip the surface data. */
|
||||
dc = front->dc;
|
||||
bitmap = front->bitmap;
|
||||
data = front->resource.heap_memory;
|
||||
data = front->container->resource.heap_memory;
|
||||
|
||||
front->dc = back->dc;
|
||||
front->bitmap = back->bitmap;
|
||||
front->resource.heap_memory = back->resource.heap_memory;
|
||||
front->container->resource.heap_memory = back->container->resource.heap_memory;
|
||||
|
||||
back->dc = dc;
|
||||
back->bitmap = bitmap;
|
||||
back->resource.heap_memory = data;
|
||||
back->container->resource.heap_memory = data;
|
||||
|
||||
/* FPS support */
|
||||
if (TRACE_ON(fps))
|
||||
|
|
|
@ -93,8 +93,8 @@ static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture)
|
|||
ERR("WINED3D_LOCATION_SYSMEM is the only location for sub-resource %u of texture %p.\n",
|
||||
i, texture);
|
||||
sub_resource->locations &= ~WINED3D_LOCATION_SYSMEM;
|
||||
wined3d_resource_free_sysmem(sub_resource->resource);
|
||||
}
|
||||
wined3d_resource_free_sysmem(&texture->resource);
|
||||
}
|
||||
|
||||
void wined3d_texture_validate_location(struct wined3d_texture *texture,
|
||||
|
@ -203,7 +203,8 @@ void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int su
|
|||
}
|
||||
if (locations & WINED3D_LOCATION_SYSMEM)
|
||||
{
|
||||
data->addr = sub_resource->resource->heap_memory;
|
||||
data->addr = texture->resource.heap_memory;
|
||||
data->addr += sub_resource->offset;
|
||||
data->buffer_object = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -219,6 +220,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
|
|||
const struct wined3d_resource_ops *resource_ops)
|
||||
{
|
||||
const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format);
|
||||
unsigned int i, j, size, offset = 0;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, "
|
||||
|
@ -229,9 +231,30 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
|
|||
debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth,
|
||||
flags, device, parent, parent_ops, resource_ops);
|
||||
|
||||
if (!desc->width || !desc->height || !desc->depth)
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
for (i = 0; i < layer_count; ++i)
|
||||
{
|
||||
for (j = 0; j < level_count; ++j)
|
||||
{
|
||||
unsigned int idx = i * level_count + j;
|
||||
|
||||
size = wined3d_format_calculate_size(format, device->surface_alignment,
|
||||
max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j));
|
||||
texture->sub_resources[idx].offset = offset;
|
||||
texture->sub_resources[idx].size = size;
|
||||
offset += size;
|
||||
}
|
||||
offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1);
|
||||
}
|
||||
|
||||
if (!offset)
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
||||
if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
|
||||
desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool,
|
||||
desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops)))
|
||||
desc->width, desc->height, desc->depth, offset, parent, parent_ops, resource_ops)))
|
||||
{
|
||||
static unsigned int once;
|
||||
|
||||
|
@ -984,7 +1007,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
|
|||
create_dib = TRUE;
|
||||
}
|
||||
|
||||
wined3d_resource_free_sysmem(sub_resource->resource);
|
||||
wined3d_resource_free_sysmem(&texture->resource);
|
||||
|
||||
if ((texture->row_pitch = pitch))
|
||||
texture->slice_pitch = height * pitch;
|
||||
|
@ -998,13 +1021,14 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
|
|||
texture->resource.multisample_quality = multisample_quality;
|
||||
texture->resource.width = width;
|
||||
texture->resource.height = height;
|
||||
texture->resource.size = texture->slice_pitch;
|
||||
|
||||
sub_resource->resource->format = format;
|
||||
sub_resource->resource->multisample_type = multisample_type;
|
||||
sub_resource->resource->multisample_quality = multisample_quality;
|
||||
sub_resource->resource->width = width;
|
||||
sub_resource->resource->height = height;
|
||||
sub_resource->resource->size = texture->slice_pitch;
|
||||
sub_resource->size = texture->slice_pitch;
|
||||
sub_resource->locations = WINED3D_LOCATION_DISCARDED;
|
||||
|
||||
if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]
|
||||
|
@ -1055,21 +1079,20 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
|
|||
static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture,
|
||||
unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
|
||||
{
|
||||
GLuint *buffer_object;
|
||||
struct wined3d_texture_sub_resource *sub_resource;
|
||||
|
||||
buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object;
|
||||
if (*buffer_object)
|
||||
sub_resource = &texture->sub_resources[sub_resource_idx];
|
||||
if (sub_resource->buffer_object)
|
||||
return;
|
||||
|
||||
GL_EXTCALL(glGenBuffers(1, buffer_object));
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, *buffer_object));
|
||||
GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER,
|
||||
texture->sub_resources[sub_resource_idx].resource->size, NULL, GL_STREAM_DRAW));
|
||||
GL_EXTCALL(glGenBuffers(1, &sub_resource->buffer_object));
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sub_resource->buffer_object));
|
||||
GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sub_resource->size, NULL, GL_STREAM_DRAW));
|
||||
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
|
||||
checkGLcall("Create buffer object");
|
||||
|
||||
TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
|
||||
*buffer_object, texture, sub_resource_idx);
|
||||
sub_resource->buffer_object, texture, sub_resource_idx);
|
||||
}
|
||||
|
||||
static void wined3d_texture_force_reload(struct wined3d_texture *texture)
|
||||
|
@ -1179,10 +1202,10 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned
|
|||
switch (location)
|
||||
{
|
||||
case WINED3D_LOCATION_SYSMEM:
|
||||
if (texture->sub_resources[sub_resource_idx].resource->heap_memory)
|
||||
if (texture->resource.heap_memory)
|
||||
return TRUE;
|
||||
|
||||
if (!wined3d_resource_allocate_sysmem(texture->sub_resources[sub_resource_idx].resource))
|
||||
if (!wined3d_resource_allocate_sysmem(&texture->resource))
|
||||
{
|
||||
ERR("Failed to allocate system memory.\n");
|
||||
return FALSE;
|
||||
|
@ -1589,7 +1612,7 @@ static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resour
|
|||
wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
|
||||
|
||||
wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
|
||||
base_memory = wined3d_texture_map_bo_address(&data, sub_resource->resource->size,
|
||||
base_memory = wined3d_texture_map_bo_address(&data, sub_resource->size,
|
||||
gl_info, GL_PIXEL_UNPACK_BUFFER, flags);
|
||||
TRACE("Base memory pointer %p.\n", base_memory);
|
||||
|
||||
|
@ -2128,7 +2151,10 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
|
|||
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;
|
||||
}
|
||||
|
||||
if (!(volumes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*volumes) * levels)))
|
||||
{
|
||||
|
@ -2391,7 +2417,7 @@ HRESULT CDECL wined3d_texture_get_sub_resource_desc(const struct wined3d_texture
|
|||
desc->width = wined3d_texture_get_level_width(texture, level_idx);
|
||||
desc->height = wined3d_texture_get_level_height(texture, level_idx);
|
||||
desc->depth = wined3d_texture_get_level_depth(texture, level_idx);
|
||||
desc->size = texture->sub_resources[sub_resource_idx].resource->size;
|
||||
desc->size = texture->sub_resources[sub_resource_idx].size;
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
|
|
@ -146,6 +146,7 @@ static DWORD volume_access_from_location(DWORD location)
|
|||
static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume,
|
||||
struct wined3d_context *context, BOOL dest_is_srgb)
|
||||
{
|
||||
struct wined3d_texture *texture = volume->container;
|
||||
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
|
||||
|
@ -156,13 +157,12 @@ static void wined3d_volume_srgb_transfer(struct wined3d_volume *volume,
|
|||
|
||||
WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n");
|
||||
data.buffer_object = 0;
|
||||
data.addr = HeapAlloc(GetProcessHeap(), 0, volume->resource.size);
|
||||
if (!data.addr)
|
||||
if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, texture->sub_resources[volume->texture_level].size)))
|
||||
return;
|
||||
|
||||
wined3d_texture_bind_and_dirtify(volume->container, context, !dest_is_srgb);
|
||||
wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb);
|
||||
wined3d_volume_download_data(volume, context, &data);
|
||||
wined3d_texture_bind_and_dirtify(volume->container, context, dest_is_srgb);
|
||||
wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb);
|
||||
wined3d_volume_upload_data(volume, context, wined3d_const_bo_address(&data));
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data.addr);
|
||||
|
@ -211,7 +211,8 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
|
|||
case WINED3D_LOCATION_TEXTURE_SRGB:
|
||||
if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
|
||||
{
|
||||
struct wined3d_const_bo_address data = {0, volume->resource.heap_memory};
|
||||
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(volume, context, &data);
|
||||
|
@ -241,8 +242,9 @@ BOOL wined3d_volume_load_location(struct wined3d_volume *volume,
|
|||
case WINED3D_LOCATION_SYSMEM:
|
||||
if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
|
||||
{
|
||||
struct wined3d_bo_address data = {0, volume->resource.heap_memory};
|
||||
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
|
||||
|
@ -348,21 +350,15 @@ HRESULT wined3d_volume_init(struct wined3d_volume *volume, struct wined3d_textur
|
|||
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
||||
const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format);
|
||||
HRESULT hr;
|
||||
UINT size;
|
||||
|
||||
size = wined3d_format_calculate_size(format, device->surface_alignment, desc->width, desc->height, desc->depth);
|
||||
|
||||
if (FAILED(hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format,
|
||||
WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->pool, desc->width, desc->height, desc->depth,
|
||||
size, NULL, &wined3d_null_parent_ops, &volume_resource_ops)))
|
||||
0, NULL, &wined3d_null_parent_ops, &volume_resource_ops)))
|
||||
{
|
||||
WARN("Failed to initialize resource, returning %#x.\n", hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (container->resource.map_binding == WINED3D_LOCATION_BUFFER)
|
||||
wined3d_resource_free_sysmem(&volume->resource);
|
||||
|
||||
volume->texture_level = level;
|
||||
volume->container = container;
|
||||
|
||||
|
|
|
@ -2505,6 +2505,8 @@ struct wined3d_texture
|
|||
struct wined3d_surface *surface;
|
||||
struct wined3d_volume *volume;
|
||||
} u;
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
|
||||
unsigned int map_count;
|
||||
DWORD locations;
|
||||
|
|
Loading…
Reference in New Issue