Esempio n. 1
0
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);
}
Esempio n. 2
0
File: volume.c Progetto: kholia/wine
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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
static void wined3d_volume_evict_sysmem(struct wined3d_volume *volume)
{
    wined3d_resource_free_sysmem(&volume->resource);
    wined3d_volume_invalidate_location(volume, WINED3D_LOCATION_SYSMEM);
}