static HRESULT d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEMENT_DESC *element_descs, UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length, WINED3DVERTEXELEMENT **wined3d_elements, UINT *wined3d_element_count) { struct wined3d_shader_signature is; HRESULT hr; UINT i; hr = parse_dxbc(shader_byte_code, shader_byte_code_length, isgn_handler, &is); if (FAILED(hr)) { ERR("Failed to parse input signature.\n"); return E_FAIL; } *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(**wined3d_elements)); if (!*wined3d_elements) { ERR("Failed to allocate wined3d vertex element array memory.\n"); HeapFree(GetProcessHeap(), 0, is.elements); return E_OUTOFMEMORY; } *wined3d_element_count = 0; for (i = 0; i < element_count; ++i) { UINT j; for (j = 0; j < is.element_count; ++j) { if (!strcmp(element_descs[i].SemanticName, is.elements[j].semantic_name) && element_descs[i].SemanticIndex == is.elements[j].semantic_idx) { WINED3DVERTEXELEMENT *e = &(*wined3d_elements)[(*wined3d_element_count)++]; const D3D10_INPUT_ELEMENT_DESC *f = &element_descs[i]; e->format = wined3dformat_from_dxgi_format(f->Format); e->input_slot = f->InputSlot; e->offset = f->AlignedByteOffset; e->output_slot = is.elements[j].register_idx; e->method = WINED3DDECLMETHOD_DEFAULT; e->usage = 0; e->usage_idx = 0; if (f->AlignedByteOffset == D3D10_APPEND_ALIGNED_ELEMENT) FIXME("D3D10_APPEND_ALIGNED_ELEMENT not supported\n"); if (f->InputSlotClass != D3D10_INPUT_PER_VERTEX_DATA) FIXME("Ignoring input slot class (%#x)\n", f->InputSlotClass); if (f->InstanceDataStepRate) FIXME("Ignoring instace data step rate (%#x)\n", f->InstanceDataStepRate); break; } } } shader_free_signature(&is); return S_OK; }
HRESULT d3d10_texture3d_init(struct d3d10_texture3d *texture, struct d3d10_device *device, const D3D10_TEXTURE3D_DESC *desc) { struct wined3d_resource_desc wined3d_desc; HRESULT hr; texture->ID3D10Texture3D_iface.lpVtbl = &d3d10_texture3d_vtbl; texture->refcount = 1; texture->desc = *desc; wined3d_desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE; wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = 0; wined3d_desc.usage = wined3d_usage_from_d3d10core(desc->BindFlags, desc->Usage); wined3d_desc.pool = WINED3D_POOL_DEFAULT; wined3d_desc.width = desc->Width; wined3d_desc.height = desc->Height; wined3d_desc.depth = desc->Depth; wined3d_desc.size = 0; if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, desc->MipLevels, 0, texture, &d3d10_texture3d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); return hr; } texture->desc.MipLevels = wined3d_texture_get_level_count(texture->wined3d_texture); texture->device = &device->ID3D10Device1_iface; ID3D10Device1_AddRef(texture->device); return S_OK; }
HRESULT d3d10_texture2d_init(struct d3d10_texture2d *texture, struct d3d10_device *device, const D3D10_TEXTURE2D_DESC *desc) { struct wined3d_resource_desc wined3d_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; } } if (desc->ArraySize != 1) FIXME("Array textures not implemented.\n"); if (desc->SampleDesc.Count > 1) FIXME("Multisampled textures not implemented.\n"); wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE; wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = desc->SampleDesc.Quality; wined3d_desc.usage = wined3d_usage_from_d3d10core(desc->BindFlags, desc->Usage); wined3d_desc.pool = WINED3D_POOL_DEFAULT; wined3d_desc.width = desc->Width; wined3d_desc.height = desc->Height; wined3d_desc.depth = 1; wined3d_desc.size = 0; if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, desc->MipLevels, 0, texture, &d3d10_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); if (texture->dxgi_surface) IUnknown_Release(texture->dxgi_surface); return hr; } texture->desc.MipLevels = wined3d_texture_get_level_count(texture->wined3d_texture); return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *iface, IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain) { struct wined3d_swapchain *wined3d_swapchain; struct wined3d_swapchain_desc wined3d_desc; IWineDXGIDevice *dxgi_device; HRESULT hr; FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain); hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device); if (FAILED(hr)) { ERR("This is not the device we're looking for\n"); return hr; } if (!desc->OutputWindow) { FIXME("No output window, should use factory output window\n"); } FIXME("Ignoring SwapEffect and Flags\n"); wined3d_desc.backbuffer_width = desc->BufferDesc.Width; wined3d_desc.backbuffer_height = desc->BufferDesc.Height; wined3d_desc.backbuffer_format = wined3dformat_from_dxgi_format(desc->BufferDesc.Format); wined3d_desc.backbuffer_count = desc->BufferCount; if (desc->SampleDesc.Count > 1) { wined3d_desc.multisample_type = desc->SampleDesc.Count; wined3d_desc.multisample_quality = desc->SampleDesc.Quality; } else { wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = 0; } wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; wined3d_desc.device_window = desc->OutputWindow; wined3d_desc.windowed = desc->Windowed; wined3d_desc.enable_auto_depth_stencil = FALSE; wined3d_desc.auto_depth_stencil_format = 0; wined3d_desc.flags = 0; /* WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL? */ wined3d_desc.refresh_rate = dxgi_rational_to_uint(&desc->BufferDesc.RefreshRate); wined3d_desc.swap_interval = WINED3DPRESENT_INTERVAL_DEFAULT; hr = IWineDXGIDevice_create_swapchain(dxgi_device, &wined3d_desc, &wined3d_swapchain); IWineDXGIDevice_Release(dxgi_device); if (FAILED(hr)) { WARN("Failed to create swapchain, hr %#x.\n", hr); return hr; } *swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); return S_OK; }
static HRESULT d3d11_input_layout_to_wined3d_declaration(const D3D11_INPUT_ELEMENT_DESC *element_descs, UINT element_count, const void *shader_byte_code, SIZE_T shader_byte_code_length, struct wined3d_vertex_element **wined3d_elements) { struct wined3d_shader_signature is; unsigned int i; HRESULT hr; if (FAILED(hr = parse_dxbc(shader_byte_code, shader_byte_code_length, isgn_handler, &is))) { ERR("Failed to parse input signature.\n"); return E_FAIL; } if (!(*wined3d_elements = d3d11_calloc(element_count, sizeof(**wined3d_elements)))) { ERR("Failed to allocate wined3d vertex element array memory.\n"); HeapFree(GetProcessHeap(), 0, is.elements); return E_OUTOFMEMORY; } for (i = 0; i < element_count; ++i) { struct wined3d_vertex_element *e = &(*wined3d_elements)[i]; const D3D11_INPUT_ELEMENT_DESC *f = &element_descs[i]; unsigned int j; e->format = wined3dformat_from_dxgi_format(f->Format); e->input_slot = f->InputSlot; e->offset = f->AlignedByteOffset; e->output_slot = WINED3D_OUTPUT_SLOT_UNUSED; e->input_slot_class = f->InputSlotClass; e->instance_data_step_rate = f->InstanceDataStepRate; e->method = WINED3D_DECL_METHOD_DEFAULT; e->usage = 0; e->usage_idx = 0; for (j = 0; j < is.element_count; ++j) { if (!strcasecmp(element_descs[i].SemanticName, is.elements[j].semantic_name) && element_descs[i].SemanticIndex == is.elements[j].semantic_idx) { e->output_slot = is.elements[j].register_idx; break; } } if (e->output_slot == WINED3D_OUTPUT_SLOT_UNUSED) WARN("Unused input element %u.\n", i); } shader_free_signature(&is); return S_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"); if (desc->ArraySize != 1) FIXME("Array textures not implemented.\n"); if (desc->SampleDesc.Count > 1) FIXME("Multisampled textures not implemented.\n"); hr = wined3d_texture_create_2d(device->wined3d_device, desc->Width, desc->Height, desc->MipLevels, desc->Usage, wined3dformat_from_dxgi_format(desc->Format), WINED3D_POOL_DEFAULT, texture, &d3d10_texture2d_wined3d_parent_ops, &texture->wined3d_texture); if (FAILED(hr)) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); if (texture->dxgi_surface) IDXGISurface_Release(texture->dxgi_surface); return hr; } return S_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 d3d_texture3d_init(struct d3d_texture3d *texture, struct d3d_device *device, const D3D11_TEXTURE3D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data) { struct wined3d_resource_desc wined3d_desc; unsigned int levels; HRESULT hr; texture->ID3D11Texture3D_iface.lpVtbl = &d3d11_texture3d_vtbl; texture->ID3D10Texture3D_iface.lpVtbl = &d3d10_texture3d_vtbl; texture->refcount = 1; wined3d_mutex_lock(); wined3d_private_store_init(&texture->private_store); texture->desc = *desc; wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_desc.multisample_type = WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = 0; wined3d_desc.usage = wined3d_usage_from_d3d11(desc->BindFlags, desc->Usage); wined3d_desc.pool = WINED3D_POOL_DEFAULT; wined3d_desc.width = desc->Width; wined3d_desc.height = desc->Height; wined3d_desc.depth = desc->Depth; wined3d_desc.size = 0; levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(max(desc->Width, desc->Height), desc->Depth)) + 1; if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, 1, levels, 0, (struct wined3d_sub_resource_data *)data, texture, &d3d_texture3d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); wined3d_private_store_cleanup(&texture->private_store); wined3d_mutex_unlock(); if (hr == WINED3DERR_INVALIDCALL) hr = E_INVALIDARG; return hr; } wined3d_mutex_unlock(); texture->desc.MipLevels = levels; texture->device = &device->ID3D11Device_iface; ID3D11Device_AddRef(texture->device); return S_OK; }
HRESULT d3d10_texture3d_init(struct d3d10_texture3d *texture, struct d3d10_device *device, const D3D10_TEXTURE3D_DESC *desc) { HRESULT hr; texture->ID3D10Texture3D_iface.lpVtbl = &d3d10_texture3d_vtbl; texture->refcount = 1; texture->desc = *desc; FIXME("Implement DXGI<->wined3d usage conversion.\n"); hr = wined3d_texture_create_3d(device->wined3d_device, desc->Width, desc->Height, desc->Depth, desc->MipLevels, desc->Usage, wined3dformat_from_dxgi_format(desc->Format), WINED3D_POOL_DEFAULT, texture, &d3d10_texture3d_wined3d_parent_ops, &texture->wined3d_texture); if (FAILED(hr)) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); return hr; } return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_swapchain_ResizeBuffers(IDXGISwapChain *iface, UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags) { struct dxgi_swapchain *swapchain = impl_from_IDXGISwapChain(iface); struct wined3d_swapchain_desc wined3d_desc; struct wined3d_surface *surface; IUnknown *parent; unsigned int i; HRESULT hr; TRACE("iface %p, buffer_count %u, width %u, height %u, format %s, flags %#x.\n", iface, buffer_count, width, height, debug_dxgi_format(format), flags); if (flags) FIXME("Ignoring flags %#x.\n", flags); EnterCriticalSection(&dxgi_cs); wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc); for (i = 0; i < wined3d_desc.backbuffer_count; ++i) { surface = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, i, WINED3D_BACKBUFFER_TYPE_MONO); parent = wined3d_surface_get_parent(surface); IUnknown_AddRef(parent); if (IUnknown_Release(parent)) { LeaveCriticalSection(&dxgi_cs); return DXGI_ERROR_INVALID_CALL; } } if (format != DXGI_FORMAT_UNKNOWN) wined3d_desc.backbuffer_format = wined3dformat_from_dxgi_format(format); hr = wined3d_swapchain_resize_buffers(swapchain->wined3d_swapchain, buffer_count, width, height, wined3d_desc.backbuffer_format, wined3d_desc.multisample_type, wined3d_desc.multisample_quality); LeaveCriticalSection(&dxgi_cs); return hr; }
static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *iface, const DXGI_SURFACE_DESC *desc, UINT surface_count, DXGI_USAGE usage, const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface) { struct wined3d_device_parent *device_parent; IWineDXGIDeviceParent *dxgi_device_parent; HRESULT hr; UINT i; UINT j; TRACE("iface %p, desc %p, surface_count %u, usage %#x, shared_resource %p, surface %p\n", iface, desc, surface_count, usage, shared_resource, surface); hr = IWineDXGIDevice_QueryInterface(iface, &IID_IWineDXGIDeviceParent, (void **)&dxgi_device_parent); if (FAILED(hr)) { ERR("Device should implement IWineD3DDeviceParent\n"); return E_FAIL; } device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent); FIXME("Implement DXGI<->wined3d usage conversion\n"); memset(surface, 0, surface_count * sizeof(*surface)); for (i = 0; i < surface_count; ++i) { struct wined3d_surface *wined3d_surface; IUnknown *parent; hr = device_parent->ops->create_swapchain_surface(device_parent, NULL, desc->Width, desc->Height, wined3dformat_from_dxgi_format(desc->Format), usage, desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE, desc->SampleDesc.Quality, &wined3d_surface); if (FAILED(hr)) { ERR("CreateSurface failed, returning %#x\n", hr); goto fail; } parent = wined3d_surface_get_parent(wined3d_surface); hr = IUnknown_QueryInterface(parent, &IID_IDXGISurface, (void **)&surface[i]); wined3d_surface_decref(wined3d_surface); if (FAILED(hr)) { ERR("Surface should implement IDXGISurface\n"); goto fail; } TRACE("Created IDXGISurface %p (%u/%u)\n", surface[i], i + 1, surface_count); } IWineDXGIDeviceParent_Release(dxgi_device_parent); return S_OK; fail: for (j = 0; j < i; ++j) { IDXGISurface_Release(surface[i]); } IWineDXGIDeviceParent_Release(dxgi_device_parent); return hr; }
static HRESULT d3d_texture2d_init(struct d3d_texture2d *texture, struct d3d_device *device, const D3D11_TEXTURE2D_DESC *desc, const D3D11_SUBRESOURCE_DATA *data) { struct wined3d_resource_desc wined3d_desc; unsigned int levels; HRESULT hr; texture->ID3D11Texture2D_iface.lpVtbl = &d3d11_texture2d_vtbl; texture->ID3D10Texture2D_iface.lpVtbl = &d3d10_texture2d_vtbl; texture->refcount = 1; wined3d_mutex_lock(); wined3d_private_store_init(&texture->private_store); texture->desc = *desc; if (desc->ArraySize != 1) FIXME("Array textures not implemented.\n"); if (desc->SampleDesc.Count > 1) FIXME("Multisampled textures not implemented.\n"); wined3d_desc.resource_type = WINED3D_RTYPE_TEXTURE; wined3d_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_desc.multisample_type = desc->SampleDesc.Count > 1 ? desc->SampleDesc.Count : WINED3D_MULTISAMPLE_NONE; wined3d_desc.multisample_quality = desc->SampleDesc.Quality; wined3d_desc.usage = wined3d_usage_from_d3d11(desc->BindFlags, desc->Usage); wined3d_desc.pool = WINED3D_POOL_DEFAULT; wined3d_desc.width = desc->Width; wined3d_desc.height = desc->Height; wined3d_desc.depth = 1; wined3d_desc.size = 0; levels = desc->MipLevels ? desc->MipLevels : wined3d_log2i(max(desc->Width, desc->Height)) + 1; if (FAILED(hr = wined3d_texture_create(device->wined3d_device, &wined3d_desc, levels, 0, (struct wined3d_sub_resource_data *)data, texture, &d3d_texture2d_wined3d_parent_ops, &texture->wined3d_texture))) { WARN("Failed to create wined3d texture, hr %#x.\n", hr); wined3d_private_store_cleanup(&texture->private_store); wined3d_mutex_unlock(); return hr; } texture->desc.MipLevels = levels; if (desc->MipLevels == 1 && desc->ArraySize == 1) { IWineDXGIDevice *wine_device; if (FAILED(hr = ID3D10Device1_QueryInterface(&device->ID3D10Device1_iface, &IID_IWineDXGIDevice, (void **)&wine_device))) { ERR("Device should implement IWineDXGIDevice.\n"); wined3d_texture_decref(texture->wined3d_texture); wined3d_mutex_unlock(); return E_FAIL; } hr = IWineDXGIDevice_create_surface(wine_device, wined3d_texture_get_resource(texture->wined3d_texture), 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); texture->dxgi_surface = NULL; wined3d_texture_decref(texture->wined3d_texture); wined3d_mutex_unlock(); return hr; } } wined3d_mutex_unlock(); texture->device = &device->ID3D11Device_iface; ID3D11Device_AddRef(texture->device); return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *iface, const DXGI_SURFACE_DESC *desc, UINT surface_count, DXGI_USAGE usage, const DXGI_SHARED_RESOURCE *shared_resource, IDXGISurface **surface) { struct wined3d_device_parent *device_parent; struct wined3d_resource_desc surface_desc; IWineDXGIDeviceParent *dxgi_device_parent; HRESULT hr; UINT i; UINT j; TRACE("iface %p, desc %p, surface_count %u, usage %#x, shared_resource %p, surface %p\n", iface, desc, surface_count, usage, shared_resource, surface); hr = IWineDXGIDevice_QueryInterface(iface, &IID_IWineDXGIDeviceParent, (void **)&dxgi_device_parent); if (FAILED(hr)) { ERR("Device should implement IWineD3DDeviceParent\n"); return E_FAIL; } device_parent = IWineDXGIDeviceParent_get_wined3d_device_parent(dxgi_device_parent); FIXME("Implement DXGI<->wined3d usage conversion\n"); surface_desc.resource_type = WINED3D_RTYPE_SURFACE; surface_desc.format = wined3dformat_from_dxgi_format(desc->Format); wined3d_sample_desc_from_dxgi(&surface_desc.multisample_type, &surface_desc.multisample_quality, &desc->SampleDesc); surface_desc.usage = usage; surface_desc.pool = WINED3D_POOL_DEFAULT; surface_desc.width = desc->Width; surface_desc.height = desc->Height; surface_desc.depth = 1; surface_desc.size = 0; wined3d_mutex_lock(); memset(surface, 0, surface_count * sizeof(*surface)); for (i = 0; i < surface_count; ++i) { struct wined3d_texture *wined3d_texture; IUnknown *parent; if (FAILED(hr = device_parent->ops->create_swapchain_texture(device_parent, NULL, &surface_desc, &wined3d_texture))) { ERR("Failed to create surface, hr %#x.\n", hr); goto fail; } parent = wined3d_texture_get_parent(wined3d_texture); hr = IUnknown_QueryInterface(parent, &IID_IDXGISurface, (void **)&surface[i]); wined3d_texture_decref(wined3d_texture); if (FAILED(hr)) { ERR("Surface should implement IDXGISurface\n"); goto fail; } TRACE("Created IDXGISurface %p (%u/%u)\n", surface[i], i + 1, surface_count); } wined3d_mutex_unlock(); IWineDXGIDeviceParent_Release(dxgi_device_parent); return S_OK; fail: wined3d_mutex_unlock(); for (j = 0; j < i; ++j) { IDXGISurface_Release(surface[i]); } IWineDXGIDeviceParent_Release(dxgi_device_parent); return hr; }
/* TODO: The DXGI swapchain desc is a bit nicer than WINED3DPRESENT_PARAMETERS, * change wined3d to use a structure more similar to DXGI. */ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IWineDXGIFactory *iface, IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain) { WINED3DPRESENT_PARAMETERS present_parameters; IWineD3DSwapChain *wined3d_swapchain; IWineD3DDevice *wined3d_device; IWineDXGIDevice *dxgi_device; UINT count; HRESULT hr; FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain); hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device); if (FAILED(hr)) { ERR("This is not the device we're looking for\n"); return hr; } wined3d_device = IWineDXGIDevice_get_wined3d_device(dxgi_device); IWineDXGIDevice_Release(dxgi_device); count = IWineD3DDevice_GetNumberOfSwapChains(wined3d_device); if (count) { FIXME("Only a single swapchain supported.\n"); IWineD3DDevice_Release(wined3d_device); return E_FAIL; } if (!desc->OutputWindow) { FIXME("No output window, should use factory output window\n"); } FIXME("Ignoring SwapEffect and Flags\n"); present_parameters.BackBufferWidth = desc->BufferDesc.Width; present_parameters.BackBufferHeight = desc->BufferDesc.Height; present_parameters.BackBufferFormat = wined3dformat_from_dxgi_format(desc->BufferDesc.Format); present_parameters.BackBufferCount = desc->BufferCount; if (desc->SampleDesc.Count > 1) { present_parameters.MultiSampleType = desc->SampleDesc.Count; present_parameters.MultiSampleQuality = desc->SampleDesc.Quality; } else { present_parameters.MultiSampleType = WINED3DMULTISAMPLE_NONE; present_parameters.MultiSampleQuality = 0; } present_parameters.SwapEffect = WINED3DSWAPEFFECT_DISCARD; present_parameters.hDeviceWindow = desc->OutputWindow; present_parameters.Windowed = desc->Windowed; present_parameters.EnableAutoDepthStencil = FALSE; present_parameters.AutoDepthStencilFormat = 0; present_parameters.Flags = 0; /* WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL? */ present_parameters.FullScreen_RefreshRateInHz = desc->BufferDesc.RefreshRate.Numerator / desc->BufferDesc.RefreshRate.Denominator; present_parameters.PresentationInterval = WINED3DPRESENT_INTERVAL_DEFAULT; hr = IWineD3DDevice_Init3D(wined3d_device, &present_parameters); if (FAILED(hr)) { WARN("Failed to initialize 3D, returning %#x\n", hr); IWineD3DDevice_Release(wined3d_device); return hr; } hr = IWineD3DDevice_GetSwapChain(wined3d_device, 0, &wined3d_swapchain); IWineD3DDevice_Release(wined3d_device); if (FAILED(hr)) { WARN("Failed to get swapchain, returning %#x\n", hr); return hr; } hr = IWineD3DSwapChain_GetParent(wined3d_swapchain, (IUnknown **)swapchain); IUnknown_Release(wined3d_swapchain); if (FAILED(hr)) { WARN("Failed to get swapchain, returning %#x\n", hr); return hr; } /* FIXME? The swapchain is created with refcount 1 by the wined3d device, * but the wined3d device can't hold a real reference. */ IUnknown_Release(*swapchain); TRACE("Created IDXGISwapChain %p\n", *swapchain); return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput4 *iface, DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC *desc) { struct dxgi_output *output = impl_from_IDXGIOutput4(iface); enum wined3d_format_id wined3d_format; unsigned int i, max_count; struct wined3d *wined3d; FIXME("iface %p, format %s, flags %#x, mode_count %p, desc %p partial stub!\n", iface, debug_dxgi_format(format), flags, mode_count, desc); if (!mode_count) return DXGI_ERROR_INVALID_CALL; if (format == DXGI_FORMAT_UNKNOWN) { *mode_count = 0; return S_OK; } wined3d = output->adapter->factory->wined3d; wined3d_format = wined3dformat_from_dxgi_format(format); wined3d_mutex_lock(); max_count = wined3d_get_adapter_mode_count(wined3d, output->adapter->ordinal, wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN); if (!desc) { wined3d_mutex_unlock(); *mode_count = max_count; return S_OK; } if (max_count > *mode_count) { wined3d_mutex_unlock(); return DXGI_ERROR_MORE_DATA; } *mode_count = max_count; for (i = 0; i < *mode_count; ++i) { struct wined3d_display_mode mode; HRESULT hr; hr = wined3d_enum_adapter_modes(wined3d, output->adapter->ordinal, wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &mode); if (FAILED(hr)) { WARN("EnumAdapterModes failed, hr %#x.\n", hr); wined3d_mutex_unlock(); return hr; } dxgi_mode_from_wined3d(&desc[i], &mode); } wined3d_mutex_unlock(); return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput *iface, DXGI_FORMAT format, UINT flags, UINT *mode_count, DXGI_MODE_DESC *desc) { struct dxgi_output *This = impl_from_IDXGIOutput(iface); enum wined3d_format_id wined3d_format; struct wined3d *wined3d; UINT i; UINT max_count; FIXME("iface %p, format %s, flags %#x, mode_count %p, desc %p partial stub!\n", iface, debug_dxgi_format(format), flags, mode_count, desc); if (!mode_count) { return S_OK; } if (format == DXGI_FORMAT_UNKNOWN) { *mode_count = 0; return S_OK; } wined3d = IWineDXGIFactory_get_wined3d(This->adapter->parent); wined3d_format = wined3dformat_from_dxgi_format(format); EnterCriticalSection(&dxgi_cs); max_count = wined3d_get_adapter_mode_count(wined3d, This->adapter->ordinal, wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN); if (!desc) { wined3d_decref(wined3d); LeaveCriticalSection(&dxgi_cs); *mode_count = max_count; return S_OK; } *mode_count = min(*mode_count,max_count); for (i = 0; i < *mode_count; ++i) { struct wined3d_display_mode mode; HRESULT hr; hr = wined3d_enum_adapter_modes(wined3d, This->adapter->ordinal, wined3d_format, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &mode); if (FAILED(hr)) { WARN("EnumAdapterModes failed, hr %#x.\n", hr); wined3d_decref(wined3d); LeaveCriticalSection(&dxgi_cs); return hr; } desc[i].Width = mode.width; desc[i].Height = mode.height; desc[i].RefreshRate.Numerator = mode.refresh_rate; desc[i].RefreshRate.Denominator = 1; desc[i].Format = format; desc[i].ScanlineOrdering = mode.scanline_ordering; desc[i].Scaling = DXGI_MODE_SCALING_UNSPECIFIED; /* FIXME */ } wined3d_decref(wined3d); LeaveCriticalSection(&dxgi_cs); return S_OK; }
static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *iface, IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain) { struct wined3d_swapchain *wined3d_swapchain; struct wined3d_swapchain_desc wined3d_desc; IWineDXGIDevice *dxgi_device; HRESULT hr; UINT min_buffer_count; FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain); switch (desc->SwapEffect) { case DXGI_SWAP_EFFECT_DISCARD: case DXGI_SWAP_EFFECT_SEQUENTIAL: min_buffer_count = 1; break; case DXGI_SWAP_EFFECT_FLIP_DISCARD: case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL: min_buffer_count = 2; break; default: WARN("Invalid swap effect %u used, returning DXGI_ERROR_INVALID_CALL.\n", desc->SwapEffect); return DXGI_ERROR_INVALID_CALL; } if (desc->BufferCount < min_buffer_count || desc->BufferCount > 16) { WARN("BufferCount is %u, returning DXGI_ERROR_INVALID_CALL.\n", desc->BufferCount); return DXGI_ERROR_INVALID_CALL; } if (!desc->OutputWindow) { FIXME("No output window, should use factory output window\n"); } hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device); if (FAILED(hr)) { ERR("This is not the device we're looking for\n"); return hr; } FIXME("Ignoring SwapEffect and Flags\n"); wined3d_desc.backbuffer_width = desc->BufferDesc.Width; wined3d_desc.backbuffer_height = desc->BufferDesc.Height; wined3d_desc.backbuffer_format = wined3dformat_from_dxgi_format(desc->BufferDesc.Format); wined3d_desc.backbuffer_count = desc->BufferCount; wined3d_sample_desc_from_dxgi(&wined3d_desc.multisample_type, &wined3d_desc.multisample_quality, &desc->SampleDesc); wined3d_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; wined3d_desc.device_window = desc->OutputWindow; wined3d_desc.windowed = desc->Windowed; wined3d_desc.enable_auto_depth_stencil = FALSE; wined3d_desc.auto_depth_stencil_format = 0; wined3d_desc.flags = 0; /* WINED3DPRESENTFLAG_DISCARD_DEPTHSTENCIL? */ wined3d_desc.refresh_rate = dxgi_rational_to_uint(&desc->BufferDesc.RefreshRate); wined3d_desc.swap_interval = WINED3DPRESENT_INTERVAL_DEFAULT; wined3d_desc.auto_restore_display_mode = TRUE; hr = IWineDXGIDevice_create_swapchain(dxgi_device, &wined3d_desc, FALSE, &wined3d_swapchain); IWineDXGIDevice_Release(dxgi_device); if (FAILED(hr)) { WARN("Failed to create swapchain, hr %#x.\n", hr); return hr; } wined3d_mutex_lock(); *swapchain = wined3d_swapchain_get_parent(wined3d_swapchain); wined3d_mutex_unlock(); return S_OK; }