HRESULT surface_init(struct d3d8_surface *surface, struct d3d8_device *device, UINT width, UINT height, D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality) { HRESULT hr; surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl; surface->refcount = 1; /* FIXME: Check MAX bounds of MultisampleQuality. */ if (multisample_quality > 0) { FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality); multisample_quality = 0; } wined3d_mutex_lock(); hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format), usage & WINED3DUSAGE_MASK, (enum wined3d_pool)pool, multisample_type, multisample_quality, flags, surface, &d3d8_surface_wined3d_parent_ops, &surface->wined3d_surface); wined3d_mutex_unlock(); if (FAILED(hr)) { WARN("Failed to create wined3d surface, hr %#x.\n", hr); return hr; } surface->parent_device = &device->IDirect3DDevice8_iface; IDirect3DDevice8_AddRef(surface->parent_device); return D3D_OK; }
HRESULT surface_init(IDirect3DSurface8Impl *surface, IDirect3DDevice8Impl *device, UINT width, UINT height, D3DFORMAT format, BOOL lockable, BOOL discard, UINT level, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality) { HRESULT hr; surface->IDirect3DSurface8_iface.lpVtbl = &Direct3DSurface8_Vtbl; surface->ref = 1; /* FIXME: Check MAX bounds of MultisampleQuality. */ if (multisample_quality > 0) { FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality); multisample_quality = 0; } wined3d_mutex_lock(); hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format), lockable, discard, level, usage & WINED3DUSAGE_MASK, (WINED3DPOOL)pool, multisample_type, multisample_quality, SURFACE_OPENGL, surface, &d3d8_surface_wined3d_parent_ops, &surface->wined3d_surface); wined3d_mutex_unlock(); if (FAILED(hr)) { WARN("Failed to create wined3d surface, hr %#x.\n", hr); return hr; } surface->parentDevice = &device->IDirect3DDevice8_iface; IUnknown_AddRef(surface->parentDevice); return D3D_OK; }
HRESULT surface_init(struct d3d9_surface *surface, struct d3d9_device *device, UINT width, UINT height, D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality #ifdef VBOX_WITH_WDDM , HANDLE *shared_handle , void *pvClientMem #endif ) { HRESULT hr; surface->IDirect3DSurface9_iface.lpVtbl = &d3d9_surface_vtbl; surface->refcount = 1; switch (format) { case D3DFMT_A8R8G8B8: case D3DFMT_X8R8G8B8: case D3DFMT_R5G6B5: case D3DFMT_X1R5G5B5: case D3DFMT_A1R5G5B5: case D3DFMT_R8G8B8: surface->getdc_supported = TRUE; break; default: surface->getdc_supported = FALSE; break; } /* FIXME: Check MAX bounds of MultisampleQuality. */ if (multisample_quality > 0) { FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality); multisample_quality = 0; } wined3d_mutex_lock(); hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format), usage & WINED3DUSAGE_MASK, (enum wined3d_pool)pool, multisample_type, multisample_quality, flags, surface, &d3d9_surface_wined3d_parent_ops, &surface->wined3d_surface #ifdef VBOX_WITH_WDDM , shared_handle , pvClientMem #endif ); wined3d_mutex_unlock(); if (FAILED(hr)) { WARN("Failed to create wined3d surface, hr %#x.\n", hr); return hr; } surface->parent_device = &device->IDirect3DDevice9Ex_iface; IDirect3DDevice9Ex_AddRef(surface->parent_device); return D3D_OK; }
HRESULT surface_init(IDirect3DSurface9Impl *surface, IDirect3DDevice9Impl *device, UINT width, UINT height, D3DFORMAT format, BOOL lockable, BOOL discard, UINT level, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality) { DWORD flags = 0; HRESULT hr; surface->IDirect3DSurface9_iface.lpVtbl = &Direct3DSurface9_Vtbl; surface->ref = 1; switch (format) { case D3DFMT_A8R8G8B8: case D3DFMT_X8R8G8B8: case D3DFMT_R5G6B5: case D3DFMT_X1R5G5B5: case D3DFMT_A1R5G5B5: case D3DFMT_R8G8B8: surface->getdc_supported = TRUE; break; default: surface->getdc_supported = FALSE; break; } /* FIXME: Check MAX bounds of MultisampleQuality. */ if (multisample_quality > 0) { FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality); multisample_quality = 0; } if (lockable) flags |= WINED3D_SURFACE_MAPPABLE; if (discard) flags |= WINED3D_SURFACE_DISCARD; wined3d_mutex_lock(); hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format), level, usage & WINED3DUSAGE_MASK, (WINED3DPOOL)pool, multisample_type, multisample_quality, SURFACE_OPENGL, flags, surface, &d3d9_surface_wined3d_parent_ops, &surface->wined3d_surface); wined3d_mutex_unlock(); if (FAILED(hr)) { WARN("Failed to create wined3d surface, hr %#x.\n", hr); return hr; } surface->parentDevice = &device->IDirect3DDevice9Ex_iface; IDirect3DDevice9Ex_AddRef(surface->parentDevice); return D3D_OK; }
HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_device *device, const D3D10_TEXTURE2D_DESC *desc) { HRESULT hr; texture->ID3D10Texture2D_iface.lpVtbl = &d3d10_texture2d_vtbl; texture->refcount = 1; texture->desc = *desc; if (desc->MipLevels == 1 && desc->ArraySize == 1) { IWineDXGIDevice *wine_device; hr = ID3D10Device_QueryInterface(&device->ID3D10Device_iface, &IID_IWineDXGIDevice, (void **)&wine_device); if (FAILED(hr)) { ERR("Device should implement IWineDXGIDevice\n"); return E_FAIL; } hr = IWineDXGIDevice_create_surface(wine_device, NULL, 0, NULL, (IUnknown *)&texture->ID3D10Texture2D_iface, (void **)&texture->dxgi_surface); IWineDXGIDevice_Release(wine_device); if (FAILED(hr)) { ERR("Failed to create DXGI surface, returning %#x\n", hr); return hr; } FIXME("Implement DXGI<->wined3d usage conversion\n"); hr = wined3d_surface_create(device->wined3d_device, desc->Width, desc->Height, wined3dformat_from_dxgi_format(desc->Format), 0, desc->Usage, WINED3DPOOL_DEFAULT, desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3DMULTISAMPLE_NONE, desc->SampleDesc.Quality, SURFACE_OPENGL, 0, texture, &d3d10_texture2d_wined3d_parent_ops, &texture->wined3d_surface); if (FAILED(hr)) { ERR("CreateSurface failed, returning %#x\n", hr); IDXGISurface_Release(texture->dxgi_surface); return hr; } } return S_OK; }
static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_resource_desc surface_desc; UINT pow2_width, pow2_height; unsigned int i; HRESULT hr; /* TODO: It should only be possible to create textures for formats * that are reported as supported. */ if (WINED3DFMT_UNKNOWN >= desc->format) { WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); return WINED3DERR_INVALIDCALL; } /* Non-power2 support. */ if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) { pow2_width = desc->width; pow2_height = desc->height; } else { /* Find the nearest pow2 match. */ pow2_width = pow2_height = 1; while (pow2_width < desc->width) pow2_width <<= 1; while (pow2_height < desc->height) pow2_height <<= 1; if (pow2_width != desc->width || pow2_height != desc->height) { /* levels == 0 returns an error as well */ if (levels != 1) { if (desc->pool == WINED3D_POOL_SCRATCH) { WARN("Creating a scratch mipmapped NPOT texture despite lack of HW support.\n"); } else { WARN("Attempted to create a mipmapped NPOT texture without unconditional NPOT support.\n"); return WINED3DERR_INVALIDCALL; } } } } /* Calculate levels for mip mapping. */ if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) { if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) { WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); return WINED3DERR_INVALIDCALL; } if (levels > 1) { WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning WINED3DERR_INVALIDCALL.\n"); return WINED3DERR_INVALIDCALL; } levels = 1; } else if (!levels) { levels = wined3d_log2i(max(desc->width, desc->height)) + 1; TRACE("Calculated levels = %u.\n", levels); } if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels, desc, device, parent, parent_ops, &texture_resource_ops))) { WARN("Failed to initialize texture, returning %#x.\n", hr); return hr; } /* Precalculated scaling for 'faked' non power of two texture coords. */ if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] && (desc->width != pow2_width || desc->height != pow2_height)) { texture->pow2_matrix[0] = 1.0f; texture->pow2_matrix[5] = 1.0f; texture->pow2_matrix[10] = 1.0f; texture->pow2_matrix[15] = 1.0f; texture->target = GL_TEXTURE_2D; texture->flags |= WINED3D_TEXTURE_COND_NP2; texture->min_mip_lookup = minMipLookup_noFilter; } else if (gl_info->supported[ARB_TEXTURE_RECTANGLE] && (desc->width != pow2_width || desc->height != pow2_height)) { texture->pow2_matrix[0] = (float)desc->width; texture->pow2_matrix[5] = (float)desc->height; texture->pow2_matrix[10] = 1.0f; texture->pow2_matrix[15] = 1.0f; texture->target = GL_TEXTURE_RECTANGLE_ARB; texture->flags |= WINED3D_TEXTURE_COND_NP2; texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT; if (texture->resource.format->flags & WINED3DFMT_FLAG_FILTERING) texture->min_mip_lookup = minMipLookup_noMip; else texture->min_mip_lookup = minMipLookup_noFilter; } else { if ((desc->width != pow2_width) || (desc->height != pow2_height)) { texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width)); texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height)); texture->flags &= ~WINED3D_TEXTURE_POW2_MAT_IDENT; } else { texture->pow2_matrix[0] = 1.0f; texture->pow2_matrix[5] = 1.0f; } texture->pow2_matrix[10] = 1.0f; texture->pow2_matrix[15] = 1.0f; texture->target = GL_TEXTURE_2D; } TRACE("xf(%f) yf(%f)\n", texture->pow2_matrix[0], texture->pow2_matrix[5]); /* Generate all the surfaces. */ surface_desc = *desc; surface_desc.resource_type = WINED3D_RTYPE_SURFACE; for (i = 0; i < texture->level_count; ++i) { struct wined3d_surface *surface; if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, texture->target, i, 0, surface_flags, &surface))) { WARN("Failed to create surface, hr %#x.\n", hr); wined3d_texture_cleanup(texture); return hr; } texture->sub_resources[i] = &surface->resource; TRACE("Created surface level %u @ %p.\n", i, surface); /* Calculate the next mipmap level. */ surface_desc.width = max(1, surface_desc.width >> 1); surface_desc.height = max(1, surface_desc.height >> 1); } return WINED3D_OK; }
static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wined3d_resource_desc *desc, UINT levels, DWORD surface_flags, struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops) { const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_resource_desc surface_desc; unsigned int i, j; HRESULT hr; /* TODO: It should only be possible to create textures for formats * that are reported as supported. */ if (WINED3DFMT_UNKNOWN >= desc->format) { WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture); return WINED3DERR_INVALIDCALL; } if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP] && desc->pool != WINED3D_POOL_SCRATCH) { WARN("(%p) : Tried to create not supported cube texture.\n", texture); return WINED3DERR_INVALIDCALL; } /* Calculate levels for mip mapping */ if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) { if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) { WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); return WINED3DERR_INVALIDCALL; } if (levels > 1) { WARN("D3DUSAGE_AUTOGENMIPMAP is set, and level count > 1, returning D3DERR_INVALIDCALL.\n"); return WINED3DERR_INVALIDCALL; } levels = 1; } else if (!levels) { levels = wined3d_log2i(desc->width) + 1; TRACE("Calculated levels = %u.\n", levels); } if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]) { UINT pow2_edge_length = 1; while (pow2_edge_length < desc->width) pow2_edge_length <<= 1; if (desc->width != pow2_edge_length) { if (desc->pool == WINED3D_POOL_SCRATCH) { /* SCRATCH textures cannot be used for texturing */ WARN("Creating a scratch NPOT cube texture despite lack of HW support.\n"); } else { WARN("Attempted to create a NPOT cube texture (edge length %u) without GL support.\n", desc->width); return WINED3DERR_INVALIDCALL; } } } if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels, desc, device, parent, parent_ops, &texture_resource_ops))) { WARN("Failed to initialize texture, returning %#x\n", hr); return hr; } texture->pow2_matrix[0] = 1.0f; texture->pow2_matrix[5] = 1.0f; texture->pow2_matrix[10] = 1.0f; texture->pow2_matrix[15] = 1.0f; texture->target = GL_TEXTURE_CUBE_MAP_ARB; /* Generate all the surfaces. */ surface_desc = *desc; surface_desc.resource_type = WINED3D_RTYPE_SURFACE; for (i = 0; i < texture->level_count; ++i) { /* Create the 6 faces. */ for (j = 0; j < 6; ++j) { static const GLenum cube_targets[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, }; UINT idx = j * texture->level_count + i; struct wined3d_surface *surface; if (FAILED(hr = wined3d_surface_create(texture, &surface_desc, cube_targets[j], i, j, surface_flags, &surface))) { WARN("Failed to create surface, hr %#x.\n", hr); wined3d_texture_cleanup(texture); return hr; } texture->sub_resources[idx] = &surface->resource; TRACE("Created surface level %u @ %p.\n", i, surface); } surface_desc.width = max(1, surface_desc.width >> 1); surface_desc.height = surface_desc.width; } return WINED3D_OK; }