Exemplo n.º 1
0
static ULONG WINAPI d3d9_vertexbuffer_Release(IDirect3DVertexBuffer9 *iface)
{
    struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface);
    ULONG refcount = InterlockedDecrement(&buffer->resource.refcount);

    TRACE("%p decreasing refcount to %u.\n", iface, refcount);

    if (!refcount)
    {
        struct wined3d_buffer *draw_buffer = buffer->draw_buffer;
        IDirect3DDevice9Ex *device = buffer->parent_device;

        wined3d_mutex_lock();
        if (draw_buffer)
            wined3d_buffer_decref(draw_buffer);
        else
            wined3d_buffer_decref(buffer->wined3d_buffer);
        wined3d_mutex_unlock();

        /* Release the device last, as it may cause the device to be destroyed. */
        IDirect3DDevice9Ex_Release(device);
    }

    return refcount;
}
Exemplo n.º 2
0
/*****************************************************************************
 * IDirect3DVertexBuffer7::Release
 *
 * Release for Vertex Buffers
 *
 * Returns:
 *  The new refcount
 *
 *****************************************************************************/
static ULONG WINAPI IDirect3DVertexBufferImpl_Release(IDirect3DVertexBuffer7 *iface)
{
    IDirect3DVertexBufferImpl *This = impl_from_IDirect3DVertexBuffer7(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("%p decreasing refcount to %u.\n", This, ref);

    if (ref == 0)
    {
        struct wined3d_buffer *curVB = NULL;
        UINT offset, stride;

        /* D3D7 Vertex buffers don't stay bound in the device, they are passed
         * as a parameter to drawPrimitiveVB. DrawPrimitiveVB sets them as the
         * stream source in wined3d, and they should get unset there before
         * they are destroyed. */
        wined3d_mutex_lock();
        wined3d_device_get_stream_source(This->ddraw->wined3d_device,
                0, &curVB, &offset, &stride);
        if (curVB == This->wineD3DVertexBuffer)
            wined3d_device_set_stream_source(This->ddraw->wined3d_device, 0, NULL, 0, 0);
        if (curVB)
            wined3d_buffer_decref(curVB); /* For the GetStreamSource */

        wined3d_vertex_declaration_decref(This->wineD3DVertexDeclaration);
        wined3d_buffer_decref(This->wineD3DVertexBuffer);
        wined3d_mutex_unlock();

        HeapFree(GetProcessHeap(), 0, This);

        return 0;
    }
    return ref;
}
Exemplo n.º 3
0
HRESULT vertexbuffer_init(struct d3d8_vertexbuffer *buffer, struct d3d8_device *device,
        UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
{
    const struct wined3d_parent_ops *parent_ops = &d3d8_null_wined3d_parent_ops;
    struct wined3d_buffer_desc desc;
    HRESULT hr;

    if (pool == D3DPOOL_SCRATCH)
    {
        WARN("Vertex buffer with D3DPOOL_SCRATCH requested.\n");
        return D3DERR_INVALIDCALL;
    }

    /* In d3d8, buffers can't be used as rendertarget or depth/stencil buffer. */
    if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
        return D3DERR_INVALIDCALL;

    buffer->IDirect3DVertexBuffer8_iface.lpVtbl = &Direct3DVertexBuffer8_Vtbl;
    d3d8_resource_init(&buffer->resource);
    buffer->fvf = fvf;
    buffer->usage = usage;

    desc.byte_width = size;
    desc.usage = usage & WINED3DUSAGE_MASK;
    desc.bind_flags = 0;
    desc.access = wined3daccess_from_d3dpool(pool, usage) | map_access_from_usage(usage);
    /* Buffers are always readable. */
    if (pool != D3DPOOL_DEFAULT)
        desc.access |= WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
    desc.misc_flags = 0;
    desc.structure_byte_stride = 0;

    if (desc.access & WINED3D_RESOURCE_ACCESS_GPU)
    {
        desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
        parent_ops = &d3d8_vertexbuffer_wined3d_parent_ops;
    }

    wined3d_mutex_lock();
    hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, parent_ops, &buffer->wined3d_buffer);
    if (SUCCEEDED(hr) && !(desc.access & WINED3D_RESOURCE_ACCESS_GPU))
    {
        desc.bind_flags = WINED3D_BIND_VERTEX_BUFFER;
        desc.access = WINED3D_RESOURCE_ACCESS_GPU;
        if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
                &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->draw_buffer)))
            wined3d_buffer_decref(buffer->wined3d_buffer);
    }
    wined3d_mutex_unlock();
    if (FAILED(hr))
    {
        WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
        return hr;
    }

    buffer->parent_device = &device->IDirect3DDevice8_iface;
    IDirect3DDevice8_AddRef(buffer->parent_device);

    return D3D_OK;
}
Exemplo n.º 4
0
/*****************************************************************************
 * IDirect3DVertexBuffer7::Lock
 *
 * Locks the vertex buffer and returns a pointer to the vertex data
 * Locking vertex buffers is similar to locking surfaces, because Windows
 * uses surfaces to store vertex data internally (According to the DX sdk)
 *
 * Params:
 *  Flags: Locking flags. Relevant here are DDLOCK_READONLY, DDLOCK_WRITEONLY,
 *         DDLOCK_DISCARDCONTENTS and DDLOCK_NOOVERWRITE.
 *  Data:  Returns a pointer to the vertex data
 *  Size:  Returns the size of the buffer if not NULL
 *
 * Returns:
 *  D3D_OK on success
 *  DDERR_INVALIDPARAMS if Data is NULL
 *  D3DERR_VERTEXBUFFEROPTIMIZED if called on an optimized buffer(WineD3D)
 *
 *****************************************************************************/
static HRESULT WINAPI d3d_vertex_buffer7_Lock(IDirect3DVertexBuffer7 *iface,
        DWORD flags, void **data, DWORD *data_size)
{
    struct d3d_vertex_buffer *buffer = impl_from_IDirect3DVertexBuffer7(iface);
    struct wined3d_resource_desc wined3d_desc;
    struct wined3d_resource *wined3d_resource;
    HRESULT hr;
    DWORD wined3d_flags = 0;

    TRACE("iface %p, flags %#x, data %p, data_size %p.\n", iface, flags, data, data_size);

    /* Writeonly: Pointless. Event: Unsupported by native according to the sdk
     * nosyslock: Not applicable
     */
    if (!(flags & DDLOCK_WAIT))
        wined3d_flags |= WINED3D_MAP_DONOTWAIT;
    if (flags & DDLOCK_READONLY)
        wined3d_flags |= WINED3D_MAP_READONLY;
    if (flags & DDLOCK_NOOVERWRITE)
        wined3d_flags |= WINED3D_MAP_NOOVERWRITE;
    if (flags & DDLOCK_DISCARDCONTENTS)
    {
        wined3d_flags |= WINED3D_MAP_DISCARD;

        if (!buffer->dynamic)
        {
            struct wined3d_buffer *new_buffer;
            wined3d_mutex_lock();
            hr = d3d_vertex_buffer_create_wined3d_buffer(buffer, TRUE, &new_buffer);
            if (SUCCEEDED(hr))
            {
                buffer->dynamic = TRUE;
                wined3d_buffer_decref(buffer->wineD3DVertexBuffer);
                buffer->wineD3DVertexBuffer = new_buffer;
            }
            else
            {
                WARN("Failed to create a dynamic buffer\n");
            }
            wined3d_mutex_unlock();
        }
    }

    wined3d_mutex_lock();
    if (data_size)
    {
        /* Get the size, for returning it, and for locking */
        wined3d_resource = wined3d_buffer_get_resource(buffer->wineD3DVertexBuffer);
        wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
        *data_size = wined3d_desc.size;
    }

    hr = wined3d_buffer_map(buffer->wineD3DVertexBuffer, 0, 0, (BYTE **)data, wined3d_flags);

    wined3d_mutex_unlock();

    return hr;
}
Exemplo n.º 5
0
static void STDMETHODCALLTYPE d3d9_indexbuffer_wined3d_object_destroyed(void *parent)
{
    struct d3d9_indexbuffer *buffer = parent;

    if (buffer->draw_buffer)
        wined3d_buffer_decref(buffer->wined3d_buffer);
    d3d9_resource_cleanup(&buffer->resource);
    heap_free(buffer);
}
Exemplo n.º 6
0
HRESULT d3d_vertex_buffer_create(struct d3d_vertex_buffer **vertex_buf,
        struct ddraw *ddraw, D3DVERTEXBUFFERDESC *desc)
{
    struct d3d_vertex_buffer *buffer;
    HRESULT hr = D3D_OK;

    TRACE("Vertex buffer description:\n");
    TRACE("    dwSize %u\n", desc->dwSize);
    TRACE("    dwCaps %#x\n", desc->dwCaps);
    TRACE("    FVF %#x\n", desc->dwFVF);
    TRACE("    dwNumVertices %u\n", desc->dwNumVertices);

    buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*buffer));
    if (!buffer)
        return DDERR_OUTOFMEMORY;

    buffer->IDirect3DVertexBuffer7_iface.lpVtbl = &d3d_vertex_buffer7_vtbl;
    buffer->IDirect3DVertexBuffer_iface.lpVtbl = &d3d_vertex_buffer1_vtbl;
    buffer->ref = 1;

    buffer->ddraw = ddraw;
    buffer->Caps = desc->dwCaps;
    buffer->fvf = desc->dwFVF;
    buffer->size = get_flexible_vertex_size(desc->dwFVF) * desc->dwNumVertices;

    wined3d_mutex_lock();

    hr = d3d_vertex_buffer_create_wined3d_buffer(buffer, FALSE, &buffer->wineD3DVertexBuffer);
    if (FAILED(hr))
    {
        WARN("Failed to create wined3d vertex buffer, hr %#x.\n", hr);
        if (hr == WINED3DERR_INVALIDCALL)
            hr = DDERR_INVALIDPARAMS;
        goto end;
    }

    buffer->wineD3DVertexDeclaration = ddraw_find_decl(ddraw, desc->dwFVF);
    if (!buffer->wineD3DVertexDeclaration)
    {
        ERR("Failed to find vertex declaration for fvf %#x.\n", desc->dwFVF);
        wined3d_buffer_decref(buffer->wineD3DVertexBuffer);
        hr = DDERR_INVALIDPARAMS;
        goto end;
    }
    wined3d_vertex_declaration_incref(buffer->wineD3DVertexDeclaration);

end:
    wined3d_mutex_unlock();
    if (hr == D3D_OK)
        *vertex_buf = buffer;
    else
        HeapFree(GetProcessHeap(), 0, buffer);

    return hr;
}
Exemplo n.º 7
0
HRESULT indexbuffer_init(struct d3d8_indexbuffer *buffer, struct d3d8_device *device,
        UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
{
    const struct wined3d_parent_ops *parent_ops = &d3d8_null_wined3d_parent_ops;
    struct wined3d_buffer_desc desc;
    HRESULT hr;

    if (pool == D3DPOOL_SCRATCH)
        return D3DERR_INVALIDCALL;

    /* In d3d8, buffers can't be used as rendertarget or depth/stencil buffer. */
    if (usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL))
        return D3DERR_INVALIDCALL;

    desc.byte_width = size;
    desc.usage = (usage & WINED3DUSAGE_MASK) | WINED3DUSAGE_STATICDECL;
    desc.bind_flags = 0;
    desc.access = wined3daccess_from_d3dpool(pool, usage)
            | WINED3D_RESOURCE_ACCESS_MAP_R | WINED3D_RESOURCE_ACCESS_MAP_W;
    desc.misc_flags = 0;
    desc.structure_byte_stride = 0;

    if (desc.access & WINED3D_RESOURCE_ACCESS_GPU)
    {
        desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
        parent_ops = &d3d8_indexbuffer_wined3d_parent_ops;
    }

    buffer->IDirect3DIndexBuffer8_iface.lpVtbl = &d3d8_indexbuffer_vtbl;
    d3d8_resource_init(&buffer->resource);
    buffer->format = wined3dformat_from_d3dformat(format);

    wined3d_mutex_lock();
    hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer, parent_ops, &buffer->wined3d_buffer);
    if (SUCCEEDED(hr) && !(desc.access & WINED3D_RESOURCE_ACCESS_GPU))
    {
        desc.bind_flags = WINED3D_BIND_INDEX_BUFFER;
        desc.access = WINED3D_RESOURCE_ACCESS_GPU;
        if (FAILED(hr = wined3d_buffer_create(device->wined3d_device, &desc, NULL, buffer,
                &d3d8_indexbuffer_wined3d_parent_ops, &buffer->draw_buffer)))
            wined3d_buffer_decref(buffer->wined3d_buffer);
    }
    wined3d_mutex_unlock();
    if (FAILED(hr))
    {
        WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
        return hr;
    }

    buffer->parent_device = &device->IDirect3DDevice8_iface;
    IDirect3DDevice8_AddRef(buffer->parent_device);

    return D3D_OK;
}
Exemplo n.º 8
0
static ULONG STDMETHODCALLTYPE d3d10_buffer_Release(ID3D10Buffer *iface)
{
    struct d3d10_buffer *This = (struct d3d10_buffer *)iface;
    ULONG refcount = InterlockedDecrement(&This->refcount);

    TRACE("%p decreasing refcount to %u\n", This, refcount);

    if (!refcount)
    {
        wined3d_buffer_decref(This->wined3d_buffer);
    }

    return refcount;
}
Exemplo n.º 9
0
HRESULT d3d_vertex_buffer_init(IDirect3DVertexBufferImpl *buffer,
        IDirectDrawImpl *ddraw, D3DVERTEXBUFFERDESC *desc)
{
    DWORD usage;
    HRESULT hr;

    buffer->lpVtbl = &d3d_vertex_buffer7_vtbl;
    buffer->IDirect3DVertexBuffer_vtbl = &d3d_vertex_buffer1_vtbl;
    buffer->ref = 1;

    buffer->ddraw = ddraw;
    buffer->Caps = desc->dwCaps;
    buffer->fvf = desc->dwFVF;

    usage = desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0;
    usage |= WINED3DUSAGE_STATICDECL;

    EnterCriticalSection(&ddraw_cs);

    hr = wined3d_buffer_create_vb(ddraw->wined3d_device,
            get_flexible_vertex_size(desc->dwFVF) * desc->dwNumVertices,
            usage, desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3DPOOL_SYSTEMMEM : WINED3DPOOL_DEFAULT,
            buffer, &ddraw_null_wined3d_parent_ops, &buffer->wineD3DVertexBuffer);
    if (FAILED(hr))
    {
        WARN("Failed to create wined3d vertex buffer, hr %#x.\n", hr);
        LeaveCriticalSection(&ddraw_cs);

        if (hr == WINED3DERR_INVALIDCALL)
            return DDERR_INVALIDPARAMS;
        else
            return hr;
    }

    buffer->wineD3DVertexDeclaration = ddraw_find_decl(ddraw, desc->dwFVF);
    if (!buffer->wineD3DVertexDeclaration)
    {
        ERR("Failed to find vertex declaration for fvf %#x.\n", desc->dwFVF);
        wined3d_buffer_decref(buffer->wineD3DVertexBuffer);
        LeaveCriticalSection(&ddraw_cs);

        return DDERR_INVALIDPARAMS;
    }
    wined3d_vertex_declaration_incref(buffer->wineD3DVertexDeclaration);

    LeaveCriticalSection(&ddraw_cs);

    return D3D_OK;
}
Exemplo n.º 10
0
static ULONG WINAPI d3d9_indexbuffer_Release(IDirect3DIndexBuffer9 *iface)
{
    IDirect3DIndexBuffer9Impl *buffer = impl_from_IDirect3DIndexBuffer9(iface);
    ULONG refcount = InterlockedDecrement(&buffer->ref);

    TRACE("%p decreasing refcount to %u.\n", iface, refcount);

    if (!refcount)
    {
        IDirect3DDevice9Ex *device = buffer->parentDevice;

        wined3d_mutex_lock();
        wined3d_buffer_decref(buffer->wineD3DIndexBuffer);
        wined3d_mutex_unlock();

        /* Release the device last, as it may cause the device to be destroyed. */
        IDirect3DDevice9Ex_Release(device);
    }

    return refcount;
}
Exemplo n.º 11
0
static ULONG STDMETHODCALLTYPE d3d11_buffer_Release(ID3D11Buffer *iface)
{
    struct d3d_buffer *buffer = impl_from_ID3D11Buffer(iface);
    ULONG refcount = InterlockedDecrement(&buffer->refcount);

    TRACE("%p decreasing refcount to %u.\n", buffer, refcount);

    if (!refcount)
    {
        ID3D11Device2 *device = buffer->device;

        wined3d_mutex_lock();
        wined3d_buffer_decref(buffer->wined3d_buffer);
        wined3d_mutex_unlock();
        /* Release the device last, it may cause the wined3d device to be
         * destroyed. */
        ID3D11Device2_Release(device);
    }

    return refcount;
}
Exemplo n.º 12
0
HRESULT d3d_vertex_buffer_create(IDirect3DVertexBufferImpl **vertex_buf, struct ddraw *ddraw,
        D3DVERTEXBUFFERDESC *desc)
{
    IDirect3DVertexBufferImpl *buffer;
    DWORD usage;
    HRESULT hr = D3D_OK;

    TRACE("Vertex buffer description:\n");
    TRACE("    dwSize %u\n", desc->dwSize);
    TRACE("    dwCaps %#x\n", desc->dwCaps);
    TRACE("    FVF %#x\n", desc->dwFVF);
    TRACE("    dwNumVertices %u\n", desc->dwNumVertices);

    buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*buffer));
    if (!buffer)
        return DDERR_OUTOFMEMORY;

    buffer->IDirect3DVertexBuffer7_iface.lpVtbl = &d3d_vertex_buffer7_vtbl;
    buffer->IDirect3DVertexBuffer_iface.lpVtbl = &d3d_vertex_buffer1_vtbl;
    buffer->ref = 1;

    buffer->ddraw = ddraw;
    buffer->Caps = desc->dwCaps;
    buffer->fvf = desc->dwFVF;

    usage = desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0;
    usage |= WINED3DUSAGE_STATICDECL;

    wined3d_mutex_lock();

    hr = wined3d_buffer_create_vb(ddraw->wined3d_device,
            get_flexible_vertex_size(desc->dwFVF) * desc->dwNumVertices,
            usage, desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3D_POOL_SYSTEM_MEM : WINED3D_POOL_DEFAULT,
            buffer, &ddraw_null_wined3d_parent_ops, &buffer->wineD3DVertexBuffer);
    if (FAILED(hr))
    {
        WARN("Failed to create wined3d vertex buffer, hr %#x.\n", hr);
        if (hr == WINED3DERR_INVALIDCALL)
            hr = DDERR_INVALIDPARAMS;
        goto end;
    }

    buffer->wineD3DVertexDeclaration = ddraw_find_decl(ddraw, desc->dwFVF);
    if (!buffer->wineD3DVertexDeclaration)
    {
        ERR("Failed to find vertex declaration for fvf %#x.\n", desc->dwFVF);
        wined3d_buffer_decref(buffer->wineD3DVertexBuffer);
        hr = DDERR_INVALIDPARAMS;
        goto end;
    }
    wined3d_vertex_declaration_incref(buffer->wineD3DVertexDeclaration);

end:
    wined3d_mutex_unlock();
    if (hr == D3D_OK)
        *vertex_buf = buffer;
    else
        HeapFree(GetProcessHeap(), 0, buffer);

    return hr;
}