/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Definition of the DXGL wrapper for ID3D11Device #include "StdAfx.h" #include "CCryDXGLBlendState.hpp" #include "CCryDXGLBuffer.hpp" #include "CCryDXGLDepthStencilState.hpp" #include "CCryDXGLDepthStencilView.hpp" #include "CCryDXGLDevice.hpp" #include "CCryDXGLDeviceContext.hpp" #include "CCryDXGLGIAdapter.hpp" #include "CCryDXGLInputLayout.hpp" #include "CCryDXGLQuery.hpp" #include "CCryDXGLRasterizerState.hpp" #include "CCryDXGLRenderTargetView.hpp" #include "CCryDXGLSamplerState.hpp" #include "CCryDXGLSwapChain.hpp" #include "CCryDXGLShader.hpp" #include "CCryDXGLShaderResourceView.hpp" #include "CCryDXGLTexture1D.hpp" #include "CCryDXGLTexture2D.hpp" #include "CCryDXGLTexture3D.hpp" #include "CCryDXGLUnorderedAccessView.hpp" #include "../Implementation/GLDevice.hpp" #include "../Implementation/GLFormat.hpp" #include "../Implementation/GLResource.hpp" #include "../Implementation/GLShader.hpp" CCryDXGLDevice::CCryDXGLDevice(CCryDXGLGIAdapter* pAdapter, D3D_FEATURE_LEVEL eFeatureLevel) : m_spAdapter(pAdapter) , m_eFeatureLevel(eFeatureLevel) { DXGL_INITIALIZE_INTERFACE(DXGIDevice) DXGL_INITIALIZE_INTERFACE(D3D11Device) CCryDXGLDeviceContext * pImmediateContext(new CCryDXGLDeviceContext()); m_spImmediateContext = pImmediateContext; pImmediateContext->Release(); } CCryDXGLDevice::~CCryDXGLDevice() { m_spImmediateContext->Shutdown(); } #if !DXGL_FULL_EMULATION HRESULT CCryDXGLDevice::QueryInterface(REFIID riid, void** ppvObject) { if (SingleInterface::Query(this, riid, ppvObject) || SingleInterface::Query(this, riid, ppvObject)) { return S_OK; } #if DXGL_VIRTUAL_DEVICE_AND_CONTEXT return E_NOINTERFACE; #else return CCryDXGLBase::QueryInterface(riid, ppvObject); #endif } #endif //!DXGL_FULL_EMULATION bool CCryDXGLDevice::Initialize(const DXGI_SWAP_CHAIN_DESC* pDesc, IDXGISwapChain** ppSwapChain) { NCryOpenGL::InitializeCryGlFramebufferFunctions(); NCryOpenGL::SAdapter* pGLAdapter(m_spAdapter->GetGLAdapter()); NCryOpenGL::SFeatureSpec kFeatureSpec; // Enable all features so the FeatureLevelToFeatureSpec function can disable depending on the D3D_FEATURE_LEVEL kFeatureSpec.m_kFeatures.SetOne(); if (!NCryOpenGL::FeatureLevelToFeatureSpec(kFeatureSpec, m_eFeatureLevel, pGLAdapter)) { return false; } // Disable features not provided by the adapter kFeatureSpec.m_kFeatures = pGLAdapter->m_kFeatures & kFeatureSpec.m_kFeatures; NCryOpenGL::TNativeDisplay kNativeDisplay(NULL); if (pDesc == NULL || ppSwapChain == NULL) { #if DXGL_FULL_EMULATION NCryOpenGL::SPixelFormatSpec kStandardPixelFormatSpec; NCryOpenGL::GetStandardPixelFormatSpec(kStandardPixelFormatSpec); m_spGLDevice = new NCryOpenGL::CDevice(pGLAdapter, kFeatureSpec, kStandardPixelFormatSpec); #else return false; #endif //DXGL_FULL_EMULATION } else { NCryOpenGL::SFrameBufferSpec kFrameBufferSpec; if (!NCryOpenGL::SwapChainDescToFrameBufferSpec(kFrameBufferSpec, *pDesc) || !NCryOpenGL::GetNativeDisplay(kNativeDisplay, pDesc->OutputWindow)) { return false; } m_spGLDevice = new NCryOpenGL::CDevice(pGLAdapter, kFeatureSpec, kFrameBufferSpec); } if (!m_spGLDevice->Initialize(kNativeDisplay)) { return false; } #if DXGL_FULL_EMULATION if (ppSwapChain != NULL && pDesc != NULL) #endif //!DXGL_FULL_EMULATION { CCryDXGLSwapChain* pDXGLSwapChain(new CCryDXGLSwapChain(this, *pDesc)); CCryDXGLSwapChain::ToInterface(ppSwapChain, pDXGLSwapChain); if (!pDXGLSwapChain->Initialize()) { return false; } } return m_spImmediateContext->Initialize(this); } NCryOpenGL::CDevice* CCryDXGLDevice::GetGLDevice() { return m_spGLDevice; } //////////////////////////////////////////////////////////////////////////////// // IDXGIObject overrides //////////////////////////////////////////////////////////////////////////////// HRESULT CCryDXGLDevice::GetParent(REFIID riid, void** ppParent) { IUnknown* pAdapterInterface; CCryDXGLBase::ToInterface(&pAdapterInterface, m_spAdapter); if (pAdapterInterface->QueryInterface(riid, ppParent) == S_OK && ppParent != NULL) { return S_OK; } #if DXGL_VIRTUAL_DEVICE_AND_CONTEXT && !DXGL_FULL_EMULATION return E_FAIL; #else return CCryDXGLGIObject::GetParent(riid, ppParent); #endif } //////////////////////////////////////////////////////////////////////////////// // IDXGIDevice implementation //////////////////////////////////////////////////////////////////////////////// HRESULT CCryDXGLDevice::GetAdapter(IDXGIAdapter** pAdapter) { if (m_spAdapter == NULL) { return E_FAIL; } CCryDXGLGIAdapter::ToInterface(pAdapter, m_spAdapter); return S_OK; } HRESULT CCryDXGLDevice::CreateSurface(const DXGI_SURFACE_DESC* pDesc, UINT NumSurfaces, DXGI_USAGE Usage, const DXGI_SHARED_RESOURCE* pSharedResource, IDXGISurface** ppSurface) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::QueryResourceResidency(IUnknown* const* ppResources, DXGI_RESIDENCY* pResidencyStatus, UINT NumResources) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::SetGPUThreadPriority(INT Priority) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::GetGPUThreadPriority(INT* pPriority) { DXGL_NOT_IMPLEMENTED return E_FAIL; } //////////////////////////////////////////////////////////////////////////////// // ID3D11Device implementation //////////////////////////////////////////////////////////////////////////////// struct SAutoContext { SAutoContext(NCryOpenGL::CDevice* pDevice) : m_pDevice(pDevice) { m_pContext = m_pDevice->ReserveContext(); } ~SAutoContext() { m_pDevice->ReleaseContext(); } NCryOpenGL::CContext* operator*() { return m_pContext; } NCryOpenGL::CContext* m_pContext; NCryOpenGL::CDevice* m_pDevice; }; HRESULT CCryDXGLDevice::CreateBuffer(const D3D11_BUFFER_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Buffer** ppBuffer) { if (ppBuffer == NULL) { // In this case the method should perform parameter validation and return the result DXGL_NOT_IMPLEMENTED return E_FAIL; } SAutoContext kAutoContext(m_spGLDevice); NCryOpenGL::SBufferPtr spGLBuffer(NCryOpenGL::CreateBuffer(*pDesc, pInitialData, *kAutoContext)); if (spGLBuffer == NULL) { return E_FAIL; } CCryDXGLBuffer::ToInterface(ppBuffer, new CCryDXGLBuffer(*pDesc, spGLBuffer, this)); return S_OK; } HRESULT CCryDXGLDevice::CreateTexture1D(const D3D11_TEXTURE1D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture1D** ppTexture1D) { if (ppTexture1D == NULL) { // In this case the method should perform parameter validation and return the result DXGL_NOT_IMPLEMENTED return E_FAIL; } SAutoContext kAutoContext(m_spGLDevice); NCryOpenGL::STexturePtr spGLTexture(NCryOpenGL::CreateTexture1D(*pDesc, pInitialData, *kAutoContext)); if (spGLTexture == NULL) { return E_FAIL; } CCryDXGLTexture1D::ToInterface(ppTexture1D, new CCryDXGLTexture1D(*pDesc, spGLTexture, this)); return S_OK; } HRESULT CCryDXGLDevice::CreateTexture2D(const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture2D** ppTexture2D) { if (ppTexture2D == NULL) { // In this case the method should perform parameter validation and return the result DXGL_NOT_IMPLEMENTED return E_FAIL; } SAutoContext kAutoContext(m_spGLDevice); NCryOpenGL::STexturePtr spGLTexture(NCryOpenGL::CreateTexture2D(*pDesc, pInitialData, *kAutoContext)); if (spGLTexture == NULL) { return E_FAIL; } CCryDXGLTexture2D::ToInterface(ppTexture2D, new CCryDXGLTexture2D(*pDesc, spGLTexture, this)); return S_OK; } HRESULT CCryDXGLDevice::CreateTexture3D(const D3D11_TEXTURE3D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture3D** ppTexture3D) { if (ppTexture3D == NULL) { // In this case the method should perform parameter validation and return the result DXGL_NOT_IMPLEMENTED return E_FAIL; } SAutoContext kAutoContext(m_spGLDevice); NCryOpenGL::STexturePtr spGLTexture(NCryOpenGL::CreateTexture3D(*pDesc, pInitialData, *kAutoContext)); if (spGLTexture == NULL) { return E_FAIL; } CCryDXGLTexture3D::ToInterface(ppTexture3D, new CCryDXGLTexture3D(*pDesc, spGLTexture, this)); return S_OK; } bool GetStandardViewDesc(CCryDXGLTexture1D* pTexture, D3D11_SHADER_RESOURCE_VIEW_DESC& kStandardDesc) { D3D11_TEXTURE1D_DESC kTextureDesc; pTexture->GetDesc(&kTextureDesc); kStandardDesc.Format = kTextureDesc.Format; if (kTextureDesc.ArraySize > 0) { kStandardDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; kStandardDesc.Texture1DArray.MostDetailedMip = 0; kStandardDesc.Texture1DArray.MipLevels = -1; kStandardDesc.Texture1DArray.FirstArraySlice = 0; kStandardDesc.Texture1DArray.ArraySize = kTextureDesc.ArraySize; } else { kStandardDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; kStandardDesc.Texture1D.MostDetailedMip = 0; kStandardDesc.Texture1DArray.MipLevels = -1; } pTexture->Release(); return true; } bool GetStandardViewDesc(CCryDXGLTexture2D* pTexture, D3D11_SHADER_RESOURCE_VIEW_DESC& kStandardDesc) { D3D11_TEXTURE2D_DESC kTextureDesc; pTexture->GetDesc(&kTextureDesc); kStandardDesc.Format = kTextureDesc.Format; if (kTextureDesc.ArraySize > 1) { if (kTextureDesc.SampleDesc.Count > 1) { kStandardDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; kStandardDesc.Texture2DMSArray.FirstArraySlice = 0; kStandardDesc.Texture2DMSArray.ArraySize = kTextureDesc.ArraySize; } else { kStandardDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; kStandardDesc.Texture2DArray.MostDetailedMip = 0; kStandardDesc.Texture2DArray.MipLevels = -1; kStandardDesc.Texture2DArray.FirstArraySlice = 0; kStandardDesc.Texture2DArray.ArraySize = kTextureDesc.ArraySize; } } else if (kTextureDesc.SampleDesc.Count > 1) { kStandardDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; } else { kStandardDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; kStandardDesc.Texture2D.MostDetailedMip = 0; kStandardDesc.Texture2D.MipLevels = -1; } pTexture->Release(); return true; } bool GetStandardViewDesc(CCryDXGLTexture3D* pTexture, D3D11_SHADER_RESOURCE_VIEW_DESC& kStandardDesc) { D3D11_TEXTURE3D_DESC kTextureDesc; pTexture->GetDesc(&kTextureDesc); kStandardDesc.Format = kTextureDesc.Format; kStandardDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; kStandardDesc.Texture3D.MostDetailedMip = 0; kStandardDesc.Texture3D.MipLevels = -1; pTexture->Release(); return true; } bool GetStandardViewDesc(CCryDXGLBuffer* pBuffer, D3D11_SHADER_RESOURCE_VIEW_DESC& kStandardDesc) { D3D11_BUFFER_DESC kBufferDesc; pBuffer->GetDesc(&kBufferDesc); bool bSuccess((kBufferDesc.MiscFlags | D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) != 0); if (bSuccess) { kStandardDesc.Format = DXGI_FORMAT_UNKNOWN; kStandardDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; kStandardDesc.Buffer.FirstElement = 0; kStandardDesc.Buffer.NumElements = kBufferDesc.StructureByteStride; } else { DXGL_ERROR("Default shader resource view for a buffer requires element size specification"); } pBuffer->Release(); return bSuccess; } bool GetStandardViewDesc(CCryDXGLTexture1D* pTexture, D3D11_RENDER_TARGET_VIEW_DESC& kStandardDesc) { D3D11_TEXTURE1D_DESC kTextureDesc; pTexture->GetDesc(&kTextureDesc); kStandardDesc.Format = kTextureDesc.Format; if (kTextureDesc.ArraySize > 0) { kStandardDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; kStandardDesc.Texture1DArray.MipSlice = 0; kStandardDesc.Texture1DArray.FirstArraySlice = 0; kStandardDesc.Texture1DArray.ArraySize = kTextureDesc.ArraySize; } else { kStandardDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; kStandardDesc.Texture1D.MipSlice = 0; } pTexture->Release(); return true; } bool GetStandardViewDesc(CCryDXGLTexture2D* pTexture, D3D11_RENDER_TARGET_VIEW_DESC& kStandardDesc) { D3D11_TEXTURE2D_DESC kTextureDesc; pTexture->GetDesc(&kTextureDesc); kStandardDesc.Format = kTextureDesc.Format; if (kTextureDesc.ArraySize > 1) { if (kTextureDesc.SampleDesc.Count > 1) { kStandardDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; kStandardDesc.Texture2DMSArray.FirstArraySlice = 0; kStandardDesc.Texture2DMSArray.ArraySize = kTextureDesc.ArraySize; } else { kStandardDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; kStandardDesc.Texture2DArray.MipSlice = 0; kStandardDesc.Texture2DArray.FirstArraySlice = 0; kStandardDesc.Texture2DArray.ArraySize = kTextureDesc.ArraySize; } } else if (kTextureDesc.SampleDesc.Count > 1) { kStandardDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; } else { kStandardDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; kStandardDesc.Texture2D.MipSlice = 0; } pTexture->Release(); return true; } bool GetStandardViewDesc(CCryDXGLTexture3D* pTexture, D3D11_RENDER_TARGET_VIEW_DESC& kStandardDesc) { D3D11_TEXTURE3D_DESC kTextureDesc; pTexture->GetDesc(&kTextureDesc); kStandardDesc.Format = kTextureDesc.Format; kStandardDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; kStandardDesc.Texture3D.MipSlice = 0; kStandardDesc.Texture3D.FirstWSlice = 0; kStandardDesc.Texture3D.WSize = -1; pTexture->Release(); return true; } bool GetStandardViewDesc(CCryDXGLBuffer* pBuffer, D3D11_RENDER_TARGET_VIEW_DESC& kStandardDesc) { D3D11_BUFFER_DESC kBufferDesc; pBuffer->GetDesc(&kBufferDesc); bool bSuccess((kBufferDesc.MiscFlags | D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) != 0); if (bSuccess) { kStandardDesc.Format = DXGI_FORMAT_UNKNOWN; kStandardDesc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER; kStandardDesc.Buffer.FirstElement = 0; kStandardDesc.Buffer.NumElements = kBufferDesc.StructureByteStride; } else { DXGL_ERROR("Default render target view for a buffer requires element size specification"); } pBuffer->Release(); return bSuccess; } bool GetStandardViewDesc(CCryDXGLTexture1D* pTexture, D3D11_DEPTH_STENCIL_VIEW_DESC& kStandardDesc) { D3D11_TEXTURE1D_DESC kTextureDesc; pTexture->GetDesc(&kTextureDesc); kStandardDesc.Format = kTextureDesc.Format; kStandardDesc.Flags = 0; if (kTextureDesc.ArraySize > 0) { kStandardDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY; kStandardDesc.Texture1DArray.MipSlice = 0; kStandardDesc.Texture1DArray.FirstArraySlice = 0; kStandardDesc.Texture1DArray.ArraySize = kTextureDesc.ArraySize; } else { kStandardDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D; kStandardDesc.Texture1D.MipSlice = 0; } pTexture->Release(); return true; } bool GetStandardViewDesc(CCryDXGLTexture2D* pTexture, D3D11_DEPTH_STENCIL_VIEW_DESC& kStandardDesc) { D3D11_TEXTURE2D_DESC kTextureDesc; pTexture->GetDesc(&kTextureDesc); kStandardDesc.Format = kTextureDesc.Format; kStandardDesc.Flags = 0; if (kTextureDesc.ArraySize > 0) { if (kTextureDesc.SampleDesc.Count > 1) { kStandardDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; kStandardDesc.Texture2DMSArray.FirstArraySlice = 0; kStandardDesc.Texture2DMSArray.ArraySize = kTextureDesc.ArraySize; } else { kStandardDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; kStandardDesc.Texture2DArray.MipSlice = 0; kStandardDesc.Texture2DArray.FirstArraySlice = 0; kStandardDesc.Texture2DArray.ArraySize = kTextureDesc.ArraySize; } } else if (kTextureDesc.SampleDesc.Count > 1) { kStandardDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; } else { kStandardDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; kStandardDesc.Texture2D.MipSlice = 0; } pTexture->Release(); return true; } bool GetStandardViewDesc(CCryDXGLTexture3D* pTexture, D3D11_DEPTH_STENCIL_VIEW_DESC&) { DXGL_ERROR("Cannot bind a depth stencil view to a 3D texture"); pTexture->Release(); return false; } bool GetStandardViewDesc(CCryDXGLBuffer* pBuffer, D3D11_DEPTH_STENCIL_VIEW_DESC&) { DXGL_ERROR("Cannot bind a depth stencil view to a buffer"); pBuffer->Release(); return false; } template bool GetStandardViewDesc(ID3D11Resource* pResource, ViewDesc& kStandardDesc) { memset(&kStandardDesc, 0, sizeof(kStandardDesc)); void* pvData(NULL); if (!FAILED(pResource->QueryInterface(__uuidof(ID3D11Texture1D), &pvData)) && pvData != NULL) { return GetStandardViewDesc(CCryDXGLTexture1D::FromInterface(reinterpret_cast(pvData)), kStandardDesc); } if (!FAILED(pResource->QueryInterface(__uuidof(ID3D11Texture2D), &pvData)) && pvData != NULL) { return GetStandardViewDesc(CCryDXGLTexture2D::FromInterface(reinterpret_cast(pvData)), kStandardDesc); } if (!FAILED(pResource->QueryInterface(__uuidof(ID3D11Texture3D), &pvData)) && pvData != NULL) { return GetStandardViewDesc(CCryDXGLTexture3D::FromInterface(reinterpret_cast(pvData)), kStandardDesc); } if (!FAILED(pResource->QueryInterface(__uuidof(ID3D11Buffer), &pvData)) && pvData != NULL) { return GetStandardViewDesc(CCryDXGLBuffer::FromInterface(reinterpret_cast(pvData)), kStandardDesc); } DXGL_ERROR("Unknown resource type for standard view description"); return false; } HRESULT CCryDXGLDevice::CreateShaderResourceView(ID3D11Resource* pResource, const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, ID3D11ShaderResourceView** ppSRView) { D3D11_SHADER_RESOURCE_VIEW_DESC kStandardDesc; if (pDesc == NULL) { if (!GetStandardViewDesc(pResource, kStandardDesc)) { return E_INVALIDARG; } pDesc = &kStandardDesc; } assert(pDesc != NULL); CCryDXGLShaderResourceView* pSRView(new CCryDXGLShaderResourceView(CCryDXGLResource::FromInterface(pResource), *pDesc, this)); SAutoContext kAutoContext(m_spGLDevice); if (pSRView->Initialize(*kAutoContext)) { CCryDXGLShaderResourceView::ToInterface(ppSRView, pSRView); return S_OK; } pSRView->Release(); return E_FAIL; } HRESULT CCryDXGLDevice::CreateUnorderedAccessView(ID3D11Resource* pResource, const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc, ID3D11UnorderedAccessView** ppUAView) { D3D11_UNORDERED_ACCESS_VIEW_DESC kStandardDesc; if (pDesc == NULL) { if (!GetStandardViewDesc(pResource, kStandardDesc)) { return E_INVALIDARG; } pDesc = &kStandardDesc; } assert(pDesc != NULL); CCryDXGLUnorderedAccessView* pUAView(new CCryDXGLUnorderedAccessView(CCryDXGLResource::FromInterface(pResource), *pDesc, this)); SAutoContext kAutoContext(m_spGLDevice); if (pUAView->Initialize(*kAutoContext)) { CCryDXGLUnorderedAccessView::ToInterface(ppUAView, pUAView); return S_OK; } pUAView->Release(); return E_FAIL; } HRESULT CCryDXGLDevice::CreateRenderTargetView(ID3D11Resource* pResource, const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, ID3D11RenderTargetView** ppRTView) { D3D11_RENDER_TARGET_VIEW_DESC kStandardDesc; if (pDesc == NULL) { if (!GetStandardViewDesc(pResource, kStandardDesc)) { return E_INVALIDARG; } pDesc = &kStandardDesc; } assert(pDesc != NULL); CCryDXGLRenderTargetView* pRTView(new CCryDXGLRenderTargetView(CCryDXGLResource::FromInterface(pResource), *pDesc, this)); SAutoContext kAutoContext(m_spGLDevice); if (pRTView->Initialize(*kAutoContext)) { CCryDXGLRenderTargetView::ToInterface(ppRTView, pRTView); return S_OK; } pRTView->Release(); return E_FAIL; } HRESULT CCryDXGLDevice::CreateDepthStencilView(ID3D11Resource* pResource, const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc, ID3D11DepthStencilView** ppDepthStencilView) { D3D11_DEPTH_STENCIL_VIEW_DESC kStandardDesc; if (pDesc == NULL) { if (!GetStandardViewDesc(pResource, kStandardDesc)) { return E_INVALIDARG; } pDesc = &kStandardDesc; } assert(pDesc != NULL); CCryDXGLDepthStencilView* pDSView(new CCryDXGLDepthStencilView(CCryDXGLResource::FromInterface(pResource), *pDesc, this)); SAutoContext kAutoContext(m_spGLDevice); if (pDSView->Initialize(*kAutoContext)) { CCryDXGLDepthStencilView::ToInterface(ppDepthStencilView, pDSView); return S_OK; } pDSView->Release(); return E_FAIL; } HRESULT CCryDXGLDevice::CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC* pInputElementDescs, UINT NumElements, const void* pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength, ID3D11InputLayout** ppInputLayout) { NCryOpenGL::TShaderReflection kShaderReflection; if (!InitializeShaderReflectionFromInput(&kShaderReflection, pShaderBytecodeWithInputSignature)) { return E_FAIL; } _smart_ptr spGLInputLayout(NCryOpenGL::CreateInputLayout(pInputElementDescs, NumElements, kShaderReflection, m_spGLDevice)); if (spGLInputLayout == NULL) { return E_FAIL; } CCryDXGLInputLayout::ToInterface(ppInputLayout, new CCryDXGLInputLayout(spGLInputLayout, this)); return S_OK; } _smart_ptr CreateGLShader(const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, NCryOpenGL::EShaderType eType, NCryOpenGL::CContext* pContext) { if (pClassLinkage != NULL) { DXGL_ERROR("Class linkage not supported"); return NULL; } _smart_ptr spGLShader(new NCryOpenGL::SShader()); spGLShader->m_eType = eType; if (!NCryOpenGL::InitializeShader(spGLShader, pShaderBytecode, BytecodeLength)) { return NULL; } return spGLShader; } template HRESULT CreateShader(const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, D3DShader** ppShader, NCryOpenGL::EShaderType eType, CCryDXGLDevice* pDevice, NCryOpenGL::CContext* pContext) { _smart_ptr spGLShader(CreateGLShader(pShaderBytecode, BytecodeLength, pClassLinkage, eType, pContext)); if (spGLShader == NULL) { return E_FAIL; } DXGLShader::ToInterface(ppShader, new DXGLShader(spGLShader, pDevice)); return S_OK; } HRESULT CCryDXGLDevice::CreateVertexShader(const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11VertexShader** ppVertexShader) { SAutoContext kAutoContext(m_spGLDevice); return CreateShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppVertexShader, NCryOpenGL::eST_Vertex, this, *kAutoContext); } HRESULT CCryDXGLDevice::CreateGeometryShader(const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11GeometryShader** ppGeometryShader) { #if DXGL_SUPPORT_GEOMETRY_SHADERS SAutoContext kAutoContext(m_spGLDevice); return CreateShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppGeometryShader, NCryOpenGL::eST_Geometry, this, *kAutoContext); #else DXGL_ERROR("Geometry shaders are not supported by this GL implementation."); return E_FAIL; #endif } HRESULT CCryDXGLDevice::CreateGeometryShaderWithStreamOutput(const void* pShaderBytecode, SIZE_T BytecodeLength, const D3D11_SO_DECLARATION_ENTRY* pSODeclaration, UINT NumEntries, const UINT* pBufferStrides, UINT NumStrides, UINT RasterizedStream, ID3D11ClassLinkage* pClassLinkage, ID3D11GeometryShader** ppGeometryShader) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::CreatePixelShader(const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11PixelShader** ppPixelShader) { SAutoContext kAutoContext(m_spGLDevice); return CreateShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppPixelShader, NCryOpenGL::eST_Fragment, this, *kAutoContext); } HRESULT CCryDXGLDevice::CreateHullShader(const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11HullShader** ppHullShader) { #if DXGL_SUPPORT_TESSELLATION SAutoContext kAutoContext(m_spGLDevice); return CreateShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppHullShader, NCryOpenGL::eST_TessControl, this, *kAutoContext); #else DXGL_ERROR("Hull shaders are not supported by this GL implementation."); return E_FAIL; #endif } HRESULT CCryDXGLDevice::CreateDomainShader(const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11DomainShader** ppDomainShader) { #if DXGL_SUPPORT_TESSELLATION SAutoContext kAutoContext(m_spGLDevice); return CreateShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppDomainShader, NCryOpenGL::eST_TessEvaluation, this, *kAutoContext); #else DXGL_ERROR("Domain shaders are not supported by this GL implementation."); return E_FAIL; #endif } HRESULT CCryDXGLDevice::CreateComputeShader(const void* pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11ComputeShader** ppComputeShader) { #if DXGL_SUPPORT_COMPUTE SAutoContext kAutoContext(m_spGLDevice); return CreateShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppComputeShader, NCryOpenGL::eST_Compute, this, *kAutoContext); #else DXGL_ERROR("Compute shaders are not supported by this GL implementation."); return E_FAIL; #endif } HRESULT CCryDXGLDevice::CreateClassLinkage(ID3D11ClassLinkage** ppLinkage) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::CreateBlendState(const D3D11_BLEND_DESC* pBlendStateDesc, ID3D11BlendState** ppBlendState) { CCryDXGLBlendState* pState(new CCryDXGLBlendState(*pBlendStateDesc, this)); SAutoContext kAutoContext(m_spGLDevice); if (!pState->Initialize(this, *kAutoContext)) { pState->Release(); return E_FAIL; } CCryDXGLBlendState::ToInterface(ppBlendState, pState); return S_OK; } HRESULT CCryDXGLDevice::CreateDepthStencilState(const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc, ID3D11DepthStencilState** ppDepthStencilState) { CCryDXGLDepthStencilState* pState(new CCryDXGLDepthStencilState(*pDepthStencilDesc, this)); SAutoContext kAutoContext(m_spGLDevice); if (!pState->Initialize(this, *kAutoContext)) { pState->Release(); return E_FAIL; } CCryDXGLDepthStencilState::ToInterface(ppDepthStencilState, pState); return S_OK; } HRESULT CCryDXGLDevice::CreateRasterizerState(const D3D11_RASTERIZER_DESC* pRasterizerDesc, ID3D11RasterizerState** ppRasterizerState) { CCryDXGLRasterizerState* pState(new CCryDXGLRasterizerState(*pRasterizerDesc, this)); SAutoContext kAutoContext(m_spGLDevice); if (!pState->Initialize(this, *kAutoContext)) { pState->Release(); return E_FAIL; } CCryDXGLRasterizerState::ToInterface(ppRasterizerState, pState); return S_OK; } HRESULT CCryDXGLDevice::CreateSamplerState(const D3D11_SAMPLER_DESC* pSamplerDesc, ID3D11SamplerState** ppSamplerState) { CCryDXGLSamplerState* pState(new CCryDXGLSamplerState(*pSamplerDesc, this)); SAutoContext kAutoContext(m_spGLDevice); if (!pState->Initialize(this, *kAutoContext)) { pState->Release(); return E_FAIL; } CCryDXGLSamplerState::ToInterface(ppSamplerState, pState); return S_OK; } HRESULT CCryDXGLDevice::CreateQuery(const D3D11_QUERY_DESC* pQueryDesc, ID3D11Query** ppQuery) { SAutoContext kAutoContext(m_spGLDevice); NCryOpenGL::SQueryPtr spGLQuery(NCryOpenGL::CreateQuery(*pQueryDesc, *kAutoContext)); if (spGLQuery == NULL) { return E_FAIL; } CCryDXGLQuery::ToInterface(ppQuery, new CCryDXGLQuery(*pQueryDesc, spGLQuery, this)); return S_OK; } HRESULT CCryDXGLDevice::CreatePredicate(const D3D11_QUERY_DESC* pPredicateDesc, ID3D11Predicate** ppPredicate) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::CreateCounter(const D3D11_COUNTER_DESC* pCounterDesc, ID3D11Counter** ppCounter) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::CreateDeferredContext(UINT ContextFlags, ID3D11DeviceContext** ppDeferredContext) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::OpenSharedResource(HANDLE hResource, REFIID ReturnedInterface, void** ppResource) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::CheckFormatSupport(DXGI_FORMAT Format, UINT* pFormatSupport) { NCryOpenGL::EGIFormat eGIFormat(NCryOpenGL::GetGIFormat(Format)); if (eGIFormat == NCryOpenGL::eGIF_NUM) { DXGL_ERROR("Unknown DXGI format"); return E_FAIL; } (*pFormatSupport) = m_spAdapter->GetGLAdapter()->m_kCapabilities.m_auFormatSupport[eGIFormat]; return S_OK; } HRESULT CCryDXGLDevice::CheckMultisampleQualityLevels(DXGI_FORMAT Format, UINT SampleCount, UINT* pNumQualityLevels) { NCryOpenGL::EGIFormat eGIFormat(NCryOpenGL::GetGIFormat(Format)); if (eGIFormat != NCryOpenGL::eGIF_NUM && NCryOpenGL::CheckFormatMultisampleSupport(m_spAdapter->GetGLAdapter(), eGIFormat, SampleCount)) { *pNumQualityLevels = 1; } else { *pNumQualityLevels = 0; } DXGL_TODO("Check if there's a way to query for specific quality levels"); return S_OK; } void CCryDXGLDevice::CheckCounterInfo(D3D11_COUNTER_INFO* pCounterInfo) { DXGL_NOT_IMPLEMENTED } HRESULT CCryDXGLDevice::CheckCounter(const D3D11_COUNTER_DESC* pDesc, D3D11_COUNTER_TYPE* pType, UINT* pActiveCounters, LPSTR szName, UINT* pNameLength, LPSTR szUnits, UINT* pUnitsLength, LPSTR szDescription, UINT* pDescriptionLength) { DXGL_NOT_IMPLEMENTED return E_FAIL; } HRESULT CCryDXGLDevice::CheckFeatureSupport(D3D11_FEATURE Feature, void* pFeatureSupportData, UINT FeatureSupportDataSize) { switch (Feature) { case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS: { D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS* pData(static_cast(pFeatureSupportData)); bool bComputeShaderSupported(m_spGLDevice->GetFeatureSpec().m_kFeatures.Get(NCryOpenGL::eF_ComputeShader)); pData->ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = bComputeShaderSupported ? TRUE : FALSE; return S_OK; } break; default: DXGL_TODO("Add supported 11.1 features") return E_FAIL; } } HRESULT CCryDXGLDevice::GetPrivateData(REFGUID guid, UINT* pDataSize, void* pData) { return m_kPrivateDataContainer.GetPrivateData(guid, pDataSize, pData); } HRESULT CCryDXGLDevice::SetPrivateData(REFGUID guid, UINT DataSize, const void* pData) { return m_kPrivateDataContainer.SetPrivateData(guid, DataSize, pData); } HRESULT CCryDXGLDevice::SetPrivateDataInterface(REFGUID guid, const IUnknown* pData) { return m_kPrivateDataContainer.SetPrivateDataInterface(guid, pData); } D3D_FEATURE_LEVEL CCryDXGLDevice::GetFeatureLevel(void) { DXGL_NOT_IMPLEMENTED return D3D_FEATURE_LEVEL_11_0; } UINT CCryDXGLDevice::GetCreationFlags(void) { DXGL_NOT_IMPLEMENTED return 0; } HRESULT CCryDXGLDevice::GetDeviceRemovedReason(void) { DXGL_NOT_IMPLEMENTED return E_FAIL; } void CCryDXGLDevice::GetImmediateContext(ID3D11DeviceContext** ppImmediateContext) { m_spImmediateContext->AddRef(); CCryDXGLDeviceContext::ToInterface(ppImmediateContext, m_spImmediateContext); } HRESULT CCryDXGLDevice::SetExceptionMode(UINT RaiseFlags) { DXGL_NOT_IMPLEMENTED return E_FAIL; } UINT CCryDXGLDevice::GetExceptionMode(void) { DXGL_NOT_IMPLEMENTED return 0; }