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; }
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; }