static BOOL volume_prepare_system_memory(struct wined3d_volume *volume) { if (volume->resource.allocatedMemory) return TRUE; volume->resource.heap_memory = wined3d_resource_allocate_sysmem(volume->resource.size); if (!volume->resource.heap_memory) return FALSE; volume->resource.allocatedMemory = volume->resource.heap_memory; return TRUE; }
static BOOL volume_prepare_system_memory(struct wined3d_volume *volume) { if (volume->resource.heap_memory) return TRUE; if (!wined3d_resource_allocate_sysmem(&volume->resource)) { ERR("Failed to allocate system memory.\n"); return FALSE; } return TRUE; }
BOOL wined3d_resource_prepare_system_memory(struct wined3d_resource *resource) { if (resource->heap_memory) return TRUE; if (!wined3d_resource_allocate_sysmem(resource)) { ERR("Failed to allocate system memory.\n"); return FALSE; } resource->heap_memory = resource->map_heap_memory; return TRUE; }
void *wined3d_resource_map_internal(struct wined3d_resource *resource, DWORD flags) { struct wined3d_device *device = resource->device; struct wined3d_context *context = NULL; void *mem; if (device->d3d_initialized) context = context_acquire(device, NULL); if (!wined3d_resource_prepare_map_memory(resource, context)) { WARN("Out of memory.\n"); context_release(context); return NULL; } if (flags & WINED3D_MAP_DISCARD) { switch (resource->map_binding) { case WINED3D_LOCATION_BUFFER: resource->map_buffer = wined3d_device_get_bo(device, resource->size, GL_STREAM_DRAW_ARB, GL_PIXEL_UNPACK_BUFFER_ARB, context); break; case WINED3D_LOCATION_SYSMEM: wined3d_resource_allocate_sysmem(resource); break; default: if (resource->access_fence) ERR("Location %s does not support DISCARD maps.\n", wined3d_debug_location(resource->map_binding)); if (resource->pool != WINED3D_POOL_DEFAULT) FIXME("Discard used on %s pool resource.\n", debug_d3dpool(resource->pool)); } wined3d_resource_validate_location(resource, resource->map_binding); } else { wined3d_resource_load_location(resource, context, resource->map_binding); } mem = wined3d_resource_get_map_ptr(resource, context, flags); if (context) context_release(context); return mem; }
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; }