Ejemplo n.º 1
0
HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc,
        UINT level_count, DWORD surface_flags, void *parent, const struct wined3d_parent_ops *parent_ops,
        struct wined3d_texture **texture)
{
    struct wined3d_texture *object;
    HRESULT hr;

    TRACE("device %p, desc %p, level_count %u, surface_flags %#x, parent %p, parent_ops %p, texture %p.\n",
            device, desc, level_count, surface_flags, parent, parent_ops, texture);

    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
        return E_OUTOFMEMORY;

    switch (desc->resource_type)
    {
        case WINED3D_RTYPE_TEXTURE:
            hr = texture_init(object, desc, level_count, surface_flags, device, parent, parent_ops);
            break;

        case WINED3D_RTYPE_VOLUME_TEXTURE:
            hr = volumetexture_init(object, desc, level_count, device, parent, parent_ops);
            break;

        case WINED3D_RTYPE_CUBE_TEXTURE:
            hr = cubetexture_init(object, desc, level_count, surface_flags, device, parent, parent_ops);
            break;

        default:
            ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
            hr = WINED3DERR_INVALIDCALL;
            break;
    }

    if (FAILED(hr))
    {
        WARN("Failed to initialize texture, returning %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created texture %p.\n", object);
    *texture = object;

    return WINED3D_OK;
}
Ejemplo n.º 2
0
void wined3d_rendertarget_view_validate_location(struct wined3d_rendertarget_view *view, DWORD location)
{
    struct wined3d_resource *resource = view->resource;
    unsigned int i, sub_resource_idx, layer_count;
    struct wined3d_texture *texture;

    if (resource->type == WINED3D_RTYPE_BUFFER)
    {
        FIXME("Not implemented for resources %s.\n", debug_d3dresourcetype(resource->type));
        return;
    }

    texture = texture_from_resource(resource);
    sub_resource_idx = view->sub_resource_idx;
    layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? view->layer_count : 1;
    for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count)
        wined3d_texture_validate_location(texture, sub_resource_idx, location);
}
Ejemplo n.º 3
0
void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_view *view,
        const struct wined3d_uvec4 *clear_value, struct wined3d_context *context)
{
    const struct wined3d_gl_info *gl_info = context->gl_info;
    const struct wined3d_format *format;
    struct wined3d_resource *resource;
    struct wined3d_buffer *buffer;
    unsigned int offset, size;

    resource = view->resource;
    if (resource->type != WINED3D_RTYPE_BUFFER)
    {
        FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type));
        return;
    }

    if (!gl_info->supported[ARB_CLEAR_BUFFER_OBJECT])
    {
        FIXME("OpenGL implementation does not support ARB_clear_buffer_object.\n");
        return;
    }

    format = view->format;
    if (format->id != WINED3DFMT_R32_UINT && format->id != WINED3DFMT_R32_SINT
            && format->id != WINED3DFMT_R32G32B32A32_UINT
            && format->id != WINED3DFMT_R32G32B32A32_SINT)
    {
        FIXME("Not implemented for format %s.\n", debug_d3dformat(format->id));
        return;
    }

    buffer = buffer_from_resource(resource);
    wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_BUFFER);
    wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER);

    get_buffer_view_range(buffer, &view->desc, format, &offset, &size);
    context_bind_bo(context, buffer->buffer_type_hint, buffer->buffer_object);
    GL_EXTCALL(glClearBufferSubData(buffer->buffer_type_hint, format->glInternal,
            offset, size, format->glFormat, format->glType, clear_value));
    checkGLcall("clear unordered access view");
}
Ejemplo n.º 4
0
HRESULT CDECL wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture,
        unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops,
        struct wined3d_rendertarget_view **view)
{
    struct wined3d_resource *sub_resource;

    TRACE("texture %p, sub_resource_idx %u, parent %p, parent_ops %p, view %p.\n",
          texture, sub_resource_idx, parent, parent_ops, view);

    if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
        return WINED3DERR_INVALIDCALL;

    if (sub_resource->type != WINED3D_RTYPE_SURFACE)
    {
        FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(texture->resource.type));
        return WINED3DERR_INVALIDCALL;
    }

    return wined3d_rendertarget_view_create_from_surface(surface_from_resource(sub_resource),
            parent, parent_ops, view);
}
Ejemplo n.º 5
0
static void wined3d_render_target_view_cs_init(void *object)
{
    struct wined3d_rendertarget_view *view = object;
    struct wined3d_resource *resource = view->resource;
    const struct wined3d_view_desc *desc = &view->desc;

    if (resource->type == WINED3D_RTYPE_BUFFER)
    {
        FIXME("Not implemented for resources %s.\n", debug_d3dresourcetype(resource->type));
    }
    else
    {
        struct wined3d_texture *texture = texture_from_resource(resource);
        unsigned int depth_or_layer_count;

        if (resource->type == WINED3D_RTYPE_TEXTURE_3D)
            depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx);
        else
            depth_or_layer_count = texture->layer_count;

        if (resource->format->id != view->format->id
                || (view->layer_count != 1 && view->layer_count != depth_or_layer_count))
        {
            if (resource->format->gl_view_class != view->format->gl_view_class)
            {
                FIXME("Render target view not supported, resource format %s, view format %s.\n",
                        debug_d3dformat(resource->format->id), debug_d3dformat(view->format->id));
                return;
            }
            if (texture->swapchain && texture->swapchain->desc.backbuffer_count > 1)
            {
                FIXME("Swapchain views not supported.\n");
                return;
            }

            create_texture_view(&view->gl_view, texture->target, desc, texture, view->format);
        }
    }
}
Ejemplo n.º 6
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)
{
    enum wined3d_gl_resource_type base_type = WINED3D_GL_RES_TYPE_COUNT;
    enum wined3d_gl_resource_type gl_type = WINED3D_GL_RES_TYPE_COUNT;
    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
    BOOL tex_2d_ok = FALSE;
    unsigned int i;

    static const struct
    {
        enum wined3d_resource_type type;
        DWORD cube_usage;
        enum wined3d_gl_resource_type gl_type;
    }
    resource_types[] =
    {
        {WINED3D_RTYPE_BUFFER,      0,                              WINED3D_GL_RES_TYPE_BUFFER},
        {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_TEX_2D},
        {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_TEX_RECT},
        {WINED3D_RTYPE_TEXTURE_2D,  0,                              WINED3D_GL_RES_TYPE_RB},
        {WINED3D_RTYPE_TEXTURE_2D,  WINED3DUSAGE_LEGACY_CUBEMAP,    WINED3D_GL_RES_TYPE_TEX_CUBE},
        {WINED3D_RTYPE_TEXTURE_3D,  0,                              WINED3D_GL_RES_TYPE_TEX_3D},
    };

    resource_check_usage(usage);

    for (i = 0; i < ARRAY_SIZE(resource_types); ++i)
    {
        if (resource_types[i].type != type
                || resource_types[i].cube_usage != (usage & WINED3DUSAGE_LEGACY_CUBEMAP))
            continue;

        gl_type = resource_types[i].gl_type;
        if (base_type == WINED3D_GL_RES_TYPE_COUNT)
            base_type = gl_type;

        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 (base_type != WINED3D_GL_RES_TYPE_COUNT && i == ARRAY_SIZE(resource_types))
    {
        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 for resource type %s.\n",
                    debug_d3dresourcetype(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;
    }

    if (!(usage & WINED3DUSAGE_PRIVATE))
    {
        /* Check that we have enough video ram left */
        if (pool == WINED3D_POOL_DEFAULT && device->wined3d->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;
}
Ejemplo n.º 7
0
static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops,
        UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, struct wined3d_device *device,
        void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops)
{
    const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format);
    HRESULT hr;

    TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, "
            "multisample_type %#x, multisample_quality %#x, usage %s, pool %s, width %u, height %u, depth %u, "
            "device %p, parent %p, parent_ops %p, resource_ops %p.\n",
            texture, texture_ops, layer_count, level_count, debug_d3dresourcetype(desc->resource_type),
            debug_d3dformat(desc->format), desc->multisample_type, desc->multisample_quality,
            debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth,
            device, parent, parent_ops, resource_ops);

    if ((format->flags & (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 (desc->width & width_mask || desc->height & height_mask)
            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)))
    {
        static unsigned int once;

        if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3
                || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5)
                && !(format->flags & WINED3DFMT_FLAG_TEXTURE) && !once++)
            ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n");

        WARN("Failed to initialize resource, returning %#x\n", hr);
        return hr;
    }
    wined3d_resource_update_draw_binding(&texture->resource);

    texture->texture_ops = texture_ops;
    texture->sub_resources = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
            level_count * layer_count * sizeof(*texture->sub_resources));
    if (!texture->sub_resources)
    {
        ERR("Failed to allocate sub-resource array.\n");
        resource_cleanup(&texture->resource);
        return E_OUTOFMEMORY;
    }

    texture->layer_count = layer_count;
    texture->level_count = level_count;
    texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE;
    texture->lod = 0;
    texture->flags = WINED3D_TEXTURE_POW2_MAT_IDENT;

    if (texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING)
    {
        texture->min_mip_lookup = minMipLookup;
        texture->mag_lookup = magLookup;
    }
    else
    {
        texture->min_mip_lookup = minMipLookup_noFilter;
        texture->mag_lookup = magLookup_noFilter;
    }

    return WINED3D_OK;
}