static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) { wined3d_resource_free_sysmem(volume->resource.heap_memory); volume->resource.heap_memory = NULL; volume->resource.allocatedMemory = NULL; wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM); }
HRESULT wined3d_volume_init(struct wined3d_volume *volume, struct wined3d_texture *container, const struct wined3d_resource_desc *desc, UINT level) { struct wined3d_device *device = container->resource.device; 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))) { 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; container->sub_resources[level].locations = WINED3D_LOCATION_DISCARDED; volume->container = container; return WINED3D_OK; }
static void wined3d_resource_destroy_object(void *object) { struct wined3d_resource *resource = object; wined3d_resource_free_sysmem(resource); context_resource_released(resource->device, resource, resource->type); wined3d_resource_release(resource); }
void wined3d_resource_cleanup_cs(struct wined3d_resource *resource) { context_resource_released(resource->device, resource, resource->type); if (resource->buffer) wined3d_resource_free_bo(resource); wined3d_resource_free_sysmem(resource); resource->map_heap_memory = NULL; }
static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_device *device, UINT width, UINT height, UINT depth, UINT level, DWORD usage, enum wined3d_format_id format_id, enum wined3d_pool pool, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; const struct wined3d_format *format = wined3d_get_format(gl_info, format_id); HRESULT hr; UINT size; if (!gl_info->supported[EXT_TEXTURE3D]) { WARN("Volume cannot be created - no volume texture support.\n"); return WINED3DERR_INVALIDCALL; } /* TODO: Write tests for other resources and move this check * to resource_init, if applicable. */ if (usage & WINED3DUSAGE_DYNAMIC && (pool == WINED3D_POOL_MANAGED || pool == WINED3D_POOL_SCRATCH)) { WARN("Attempted to create a DYNAMIC texture in pool %u.\n", pool); return WINED3DERR_INVALIDCALL; } size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, depth); hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format, WINED3D_MULTISAMPLE_NONE, 0, usage, pool, width, height, depth, size, parent, parent_ops, &volume_resource_ops); if (FAILED(hr)) { WARN("Failed to initialize resource, returning %#x.\n", hr); return hr; } volume->texture_level = level; volume->locations = WINED3D_LOCATION_DISCARDED; if (pool == WINED3D_POOL_DEFAULT && usage & WINED3DUSAGE_DYNAMIC && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) { wined3d_resource_free_sysmem(volume->resource.heap_memory); volume->resource.heap_memory = NULL; volume->resource.allocatedMemory = NULL; volume->flags |= WINED3D_VFLAG_PBO; } return WINED3D_OK; }
static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture *container, const struct wined3d_resource_desc *desc, UINT level) { struct wined3d_device *device = container->resource.device; 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; if (!gl_info->supported[EXT_TEXTURE3D]) { WARN("Volume cannot be created - no volume texture support.\n"); return WINED3DERR_INVALIDCALL; } /* TODO: Write tests for other resources and move this check * to resource_init, if applicable. */ if (desc->usage & WINED3DUSAGE_DYNAMIC && (desc->pool == WINED3D_POOL_MANAGED || desc->pool == WINED3D_POOL_SCRATCH)) { WARN("Attempted to create a DYNAMIC texture in pool %s.\n", debug_d3dpool(desc->pool)); return WINED3DERR_INVALIDCALL; } 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))) { WARN("Failed to initialize resource, returning %#x.\n", hr); return hr; } volume->texture_level = level; volume->locations = WINED3D_LOCATION_DISCARDED; if (desc->pool == WINED3D_POOL_DEFAULT && desc->usage & WINED3DUSAGE_DYNAMIC && gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] && !format->convert) { wined3d_resource_free_sysmem(&volume->resource); volume->flags |= WINED3D_VFLAG_PBO; } volume->container = container; return WINED3D_OK; }
void resource_cleanup(struct wined3d_resource *resource) { const struct wined3d *d3d = resource->device->wined3d; TRACE("Cleaning up resource %p.\n", resource); if (resource->pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) { TRACE("Decrementing device memory pool by %u.\n", resource->size); adapter_adjust_memory(resource->device->adapter, (INT64)0 - resource->size); } wined3d_resource_free_sysmem(resource); device_resource_released(resource->device, resource); }
void wined3d_resource_changed(struct wined3d_resource *resource, struct wined3d_gl_bo *swap_buffer, void *swap_heap_memory) { struct wined3d_device *device = resource->device; if (swap_buffer && swap_buffer != resource->buffer) { struct wined3d_context *context = context_acquire(device, NULL); wined3d_device_release_bo(device, resource->buffer, context); context_release(context); resource->buffer = swap_buffer; } if (swap_heap_memory && swap_heap_memory != resource->heap_memory) { wined3d_resource_free_sysmem(resource); resource->heap_memory = swap_heap_memory; } wined3d_resource_invalidate_location(resource, ~resource->map_binding); }
HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device, enum wined3d_resource_type type, const struct wined3d_format *format, enum wined3d_multisample_type multisample_type, UINT multisample_quality, DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size, void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) { const struct wined3d *d3d = device->wined3d; const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; static const enum wined3d_gl_resource_type gl_resource_types[][4] = { /* 0 */ {WINED3D_GL_RES_TYPE_COUNT}, /* WINED3D_RTYPE_SURFACE */ {WINED3D_GL_RES_TYPE_COUNT}, /* WINED3D_RTYPE_VOLUME */ {WINED3D_GL_RES_TYPE_COUNT}, /* WINED3D_RTYPE_TEXTURE */ {WINED3D_GL_RES_TYPE_TEX_2D, WINED3D_GL_RES_TYPE_TEX_RECT, WINED3D_GL_RES_TYPE_RB, WINED3D_GL_RES_TYPE_COUNT}, /* WINED3D_RTYPE_VOLUME_TEXTURE */ {WINED3D_GL_RES_TYPE_TEX_3D, WINED3D_GL_RES_TYPE_COUNT}, /* WINED3D_RTYPE_CUBE_TEXTURE */ {WINED3D_GL_RES_TYPE_TEX_CUBE, WINED3D_GL_RES_TYPE_COUNT}, /* WINED3D_RTYPE_BUFFER */ {WINED3D_GL_RES_TYPE_BUFFER, WINED3D_GL_RES_TYPE_COUNT}, }; enum wined3d_gl_resource_type gl_type = WINED3D_GL_RES_TYPE_COUNT; enum wined3d_gl_resource_type base_type = gl_resource_types[type][0]; resource_check_usage(usage); if (base_type != WINED3D_GL_RES_TYPE_COUNT) { unsigned int i; BOOL tex_2d_ok = FALSE; for (i = 0; (gl_type = gl_resource_types[type][i]) != WINED3D_GL_RES_TYPE_COUNT; i++) { if ((usage & WINED3DUSAGE_RENDERTARGET) && !(format->flags[gl_type] & WINED3DFMT_FLAG_RENDERTARGET)) { WARN("Format %s cannot be used for render targets.\n", debug_d3dformat(format->id)); continue; } if ((usage & WINED3DUSAGE_DEPTHSTENCIL) && !(format->flags[gl_type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) { WARN("Format %s cannot be used for depth/stencil buffers.\n", debug_d3dformat(format->id)); continue; } if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_DEPTHSTENCIL) && !(format->flags[gl_type] & WINED3DFMT_FLAG_FBO_ATTACHABLE)) { WARN("Render target or depth stencil is not FBO attachable.\n"); continue; } if ((usage & WINED3DUSAGE_TEXTURE) && !(format->flags[gl_type] & WINED3DFMT_FLAG_TEXTURE)) { WARN("Format %s cannot be used for texturing.\n", debug_d3dformat(format->id)); continue; } if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] && gl_type == WINED3D_GL_RES_TYPE_TEX_2D) { TRACE("Skipping 2D texture type to try texture rectangle.\n"); tex_2d_ok = TRUE; continue; } break; } if (gl_type == WINED3D_GL_RES_TYPE_COUNT) { if (tex_2d_ok) { /* Non power of 2 texture and rectangle textures or renderbuffers do not work. * Use 2D textures, the texture code will pad to a power of 2 size. */ gl_type = WINED3D_GL_RES_TYPE_TEX_2D; } else if (pool == WINED3D_POOL_SCRATCH) { /* Needed for proper format information. */ gl_type = base_type; } else { WARN("Did not find a suitable GL resource type, resource type, d3d type %u.\n", type); return WINED3DERR_INVALIDCALL; } } } if (base_type != WINED3D_GL_RES_TYPE_COUNT && (format->flags[base_type] & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BLOCKS_NO_VERIFY)) == WINED3DFMT_FLAG_BLOCKS) { UINT width_mask = format->block_width - 1; UINT height_mask = format->block_height - 1; if (width & width_mask || height & height_mask) return WINED3DERR_INVALIDCALL; } resource->ref = 1; resource->device = device; resource->type = type; resource->gl_type = gl_type; resource->format = format; if (gl_type < WINED3D_GL_RES_TYPE_COUNT) resource->format_flags = format->flags[gl_type]; resource->multisample_type = multisample_type; resource->multisample_quality = multisample_quality; resource->usage = usage; resource->pool = pool; resource->access_flags = resource_access_from_pool(pool); if (usage & WINED3DUSAGE_DYNAMIC) resource->access_flags |= WINED3D_RESOURCE_ACCESS_CPU; resource->width = width; resource->height = height; resource->depth = depth; resource->size = size; resource->priority = 0; resource->parent = parent; resource->parent_ops = parent_ops; resource->resource_ops = resource_ops; resource->map_binding = WINED3D_LOCATION_SYSMEM; if (size) { if (!wined3d_resource_allocate_sysmem(resource)) { ERR("Failed to allocate system memory.\n"); return E_OUTOFMEMORY; } } else { resource->heap_memory = NULL; } /* Check that we have enough video ram left */ if (pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) { if (size > wined3d_device_get_available_texture_mem(device)) { ERR("Out of adapter memory\n"); wined3d_resource_free_sysmem(resource); return WINED3DERR_OUTOFVIDEOMEMORY; } adapter_adjust_memory(device->adapter, size); } device_resource_add(device, resource); return WINED3D_OK; }
HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device, enum wined3d_resource_type type, const struct wined3d_format *format, enum wined3d_multisample_type multisample_type, UINT multisample_quality, DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size, void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops) { const struct wined3d *d3d = device->wined3d; resource_check_usage(usage); if (pool != WINED3D_POOL_SCRATCH) { if ((usage & WINED3DUSAGE_RENDERTARGET) && !(format->flags & WINED3DFMT_FLAG_RENDERTARGET)) return WINED3DERR_INVALIDCALL; if ((usage & WINED3DUSAGE_DEPTHSTENCIL) && !(format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) return WINED3DERR_INVALIDCALL; /* if ((usage & WINED3DUSAGE_TEXTURE) && !(format->flags & WINED3DFMT_FLAG_TEXTURE)) return WINED3DERR_INVALIDCALL;*/ } resource->ref = 1; resource->device = device; resource->type = type; resource->format = format; resource->multisample_type = multisample_type; resource->multisample_quality = multisample_quality; resource->usage = usage; resource->pool = pool; resource->access_flags = resource_access_from_pool(pool); if (usage & WINED3DUSAGE_DYNAMIC) resource->access_flags |= WINED3D_RESOURCE_ACCESS_CPU; resource->width = width; resource->height = height; resource->depth = depth; resource->size = size; resource->priority = 0; resource->parent = parent; resource->parent_ops = parent_ops; resource->resource_ops = resource_ops; if (size) { if (!wined3d_resource_allocate_sysmem(resource)) { ERR("Failed to allocate system memory.\n"); return E_OUTOFMEMORY; } } else { resource->heap_memory = NULL; } /* Check that we have enough video ram left */ if (pool == WINED3D_POOL_DEFAULT && d3d->flags & WINED3D_VIDMEM_ACCOUNTING) { if (size > wined3d_device_get_available_texture_mem(device)) { ERR("Out of adapter memory\n"); wined3d_resource_free_sysmem(resource); return WINED3DERR_OUTOFVIDEOMEMORY; } adapter_adjust_memory(device->adapter, size); } device_resource_add(device, resource); return WINED3D_OK; }
static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume) { wined3d_resource_free_sysmem(&volume->resource); wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM); }