Commit 3b96ac29 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Allocate system memory for complete textures.

parent e6780a5e
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment