/* * 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 ID3D11DeviceContext #include "StdAfx.h" #include "CCryDXGLBlendState.hpp" #include "CCryDXGLBuffer.hpp" #include "CCryDXGLDepthStencilView.hpp" #include "CCryDXGLDeviceContext.hpp" #include "CCryDXGLDevice.hpp" #include "CCryDXGLBlendState.hpp" #include "CCryDXGLDepthStencilState.hpp" #include "CCryDXGLInputLayout.hpp" #include "CCryDXGLQuery.hpp" #include "CCryDXGLRasterizerState.hpp" #include "CCryDXGLRenderTargetView.hpp" #include "CCryDXGLSamplerState.hpp" #include "CCryDXGLShader.hpp" #include "CCryDXGLShaderResourceView.hpp" #include "CCryDXGLUnorderedAccessView.hpp" #include "../Implementation/GLDevice.hpp" #include "../Implementation/GLFormat.hpp" #include "../Implementation/GLView.hpp" #define DXGL_CHECK_HAZARDS 0 #define DXGL_CHECK_PIPELINE 0 #define DXGL_CHECK_CURRENT_CONTEXT 0 //////////////////////////////////////////////////////////////////////////////// // CCryDXGLDeviceContext //////////////////////////////////////////////////////////////////////////////// CCryDXGLDeviceContext::CCryDXGLDeviceContext() : m_uStencilRef(0) , m_uIndexBufferOffset(0) , m_eIndexBufferFormat(DXGI_FORMAT_UNKNOWN) , m_ePrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED) , m_uSampleMask(0xFFFFFFFF) , m_uNumViewports(0) , m_uNumScissorRects(0) , m_pContext(NULL) { DXGL_INITIALIZE_INTERFACE(D3D11DeviceContext) m_auBlendFactor[0] = 1.0f; m_auBlendFactor[1] = 1.0f; m_auBlendFactor[2] = 1.0f; m_auBlendFactor[3] = 1.0f; for (uint32 uVB = 0; uVB < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++uVB) { m_auVertexBufferStrides[uVB] = 0; m_auVertexBufferOffsets[uVB] = 0; } for (uint32 uSO = 0; uSO < D3D11_SO_BUFFER_SLOT_COUNT; ++uSO) { m_auStreamOutputBufferOffsets[uSO] = 0; } m_kStages.resize(NCryOpenGL::eST_NUM); std::vector::iterator kStageIter(m_kStages.begin()); const std::vector::iterator kStageEnd(m_kStages.end()); while (kStageIter != kStageEnd) { memset(kStageIter->m_auConstantBufferOffsets, 0, sizeof(kStageIter->m_auConstantBufferOffsets)); memset(kStageIter->m_auConstantBufferSizes, 0, sizeof(kStageIter->m_auConstantBufferSizes)); ++kStageIter; } } CCryDXGLDeviceContext::~CCryDXGLDeviceContext() { Shutdown(); } bool CCryDXGLDeviceContext::Initialize(CCryDXGLDevice* pDevice) { SetDevice(pDevice); m_spDefaultBlendState = CreateDefaultBlendState(pDevice); m_spDefaultDepthStencilState = CreateDefaultDepthStencilState(pDevice); m_spDefaultRasterizerState = CreateDefaultRasterizerState(pDevice); m_spDefaultSamplerState = CreateDefaultSamplerState(pDevice); NCryOpenGL::CDevice* pGLDevice(pDevice->GetGLDevice()); m_pContext = pGLDevice->AllocateContext(NCryOpenGL::CContext::RenderingType); pGLDevice->BindContext(m_pContext); bool bResult = m_spDefaultBlendState->Initialize(pDevice, m_pContext) && m_spDefaultDepthStencilState->Initialize(pDevice, m_pContext) && m_spDefaultRasterizerState->Initialize(pDevice, m_pContext) && m_spDefaultSamplerState->Initialize(pDevice, m_pContext); pGLDevice->UnbindContext(m_pContext); return bResult; } void CCryDXGLDeviceContext::Shutdown() { if (m_pContext != NULL) { m_pContext->GetDevice()->FreeContext(m_pContext); m_pContext = NULL; } m_pDevice = NULL; } NCryOpenGL::CContext* CCryDXGLDeviceContext::GetGLContext() { return m_pContext; } _smart_ptr CCryDXGLDeviceContext::CreateDefaultBlendState(CCryDXGLDevice* pDevice) { // Default D3D11_BLEND_DESC values from DXSDK D3D11_BLEND_DESC kDesc; ZeroMemory(&kDesc, sizeof(kDesc)); kDesc.AlphaToCoverageEnable = FALSE; kDesc.IndependentBlendEnable = FALSE; kDesc.RenderTarget[0].BlendEnable = FALSE; kDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; kDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO; kDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; kDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; kDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; kDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; kDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; return new CCryDXGLBlendState(kDesc, pDevice); } _smart_ptr CCryDXGLDeviceContext::CreateDefaultDepthStencilState(CCryDXGLDevice* pDevice) { // Default D3D11_DEPTH_STENCIL_DESC values from DXSDK D3D11_DEPTH_STENCIL_DESC kDesc; kDesc.DepthEnable = TRUE; kDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; kDesc.DepthFunc = D3D11_COMPARISON_LESS; kDesc.StencilEnable = FALSE; kDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; kDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; kDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; kDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; kDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; kDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; kDesc.BackFace = kDesc.FrontFace; return new CCryDXGLDepthStencilState(kDesc, pDevice); } _smart_ptr CCryDXGLDeviceContext::CreateDefaultRasterizerState(CCryDXGLDevice* pDevice) { // Default D3D11_RASTERIZER_DESC values from DXSDK D3D11_RASTERIZER_DESC kDesc; kDesc.FillMode = D3D11_FILL_SOLID; kDesc.CullMode = D3D11_CULL_BACK; kDesc.FrontCounterClockwise = FALSE; kDesc.DepthBias = 0; kDesc.SlopeScaledDepthBias = 0.0f; kDesc.DepthBiasClamp = 0.0f; kDesc.DepthClipEnable = TRUE; kDesc.ScissorEnable = FALSE; kDesc.MultisampleEnable = FALSE; kDesc.AntialiasedLineEnable = FALSE; return new CCryDXGLRasterizerState(kDesc, pDevice); } _smart_ptr CCryDXGLDeviceContext::CreateDefaultSamplerState(CCryDXGLDevice* pDevice) { // Default D3D11_SAMPLER_DESC values from DXSDK D3D11_SAMPLER_DESC kDesc; kDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; kDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; kDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; kDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; kDesc.MinLOD = -FLT_MAX; kDesc.MaxLOD = FLT_MAX; kDesc.MipLODBias = 0.0f; kDesc.MaxAnisotropy = 1; kDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; kDesc.BorderColor[0] = 1.0f; kDesc.BorderColor[1] = 1.0f; kDesc.BorderColor[2] = 1.0f; kDesc.BorderColor[3] = 1.0f; return new CCryDXGLSamplerState(kDesc, pDevice); } #if DXGL_CHECK_HAZARDS void CheckHazard(uint32 uRTVIndex, CCryDXGLRenderTargetView* pRTView, CCryDXGLResource* pRTVResource, uint32 uSRVIndex, CCryDXGLShaderResourceView* pSRView, CCryDXGLResource* pSRVResource, uint32 uStage) { if (pRTVResource == pSRVResource) { DXGL_WARNING("Hazard detected: render target view %d and shader resource view %d in stage %d refer to the same resource", uRTVIndex, uSRVIndex, uStage); } } void CheckHazard(uint32 uDSVIndex, CCryDXGLDepthStencilView* pDSView, CCryDXGLResource* pDSVResource, uint32 uSRVIndex, CCryDXGLShaderResourceView* pSRView, CCryDXGLResource* pSRVResource, uint32 uStage) { if (pDSVResource == pSRVResource) { D3D11_DEPTH_STENCIL_VIEW_DESC kDSVDesc; pDSView->GetDesc(&kDSVDesc); if ((kDSVDesc.Flags & D3D11_DSV_READ_ONLY_DEPTH) == 0 || (kDSVDesc.Flags & D3D11_DSV_READ_ONLY_STENCIL) == 0) { DXGL_ERROR("Hazard detected: writable depth stencil view and shader resource view %d in stage %d refer to the same resource", uSRVIndex, uStage); } } } template void CheckHazards(_smart_ptr* pOMViews, uint32 uNumOMViews, _smart_ptr* pSRViews, uint32 uNumSRViews, uint32 uStage) { uint32 uOMView; for (uOMView = 0; uOMView < uNumOMViews; ++uOMView) { OMView* pOMView(pOMViews[uOMView]); if (pOMView != NULL) { ID3D11Resource* pOMVResource(NULL); pOMView->GetResource(&pOMVResource); uint32 uSRView; for (uSRView = 0; uSRView < uNumSRViews; ++uSRView) { CCryDXGLShaderResourceView* pSRView(pSRViews[uSRView]); if (pSRView != NULL) { ID3D11Resource* pSRVResource(NULL); pSRView->GetResource(&pSRVResource); CheckHazard(uOMView, pOMView, pOMVResource, uSRView, pSRView, pSRVResource, uStage); pSRVResource->Release(); } } pOMVResource->Release(); } } } #endif //DXGL_CHECK_HAZARDS #if DXGL_CHECK_PIPELINE template void CheckRequiredStage(std::vector& kStages, uint32 uRequiredStage) { if (kStages.size() <= uRequiredStage || kStages.at(uRequiredStage).m_spShader == NULL) { DXGL_ERROR("Required pipeline stage %d is not bound to a valid shader"); } } template void CheckPipeline(std::vector& kStages) { CheckRequiredStage(kStages, NCryOpenGL::eST_Vertex); CheckRequiredStage(kStages, NCryOpenGL::eST_Fragment); } #else template ILINE void CheckPipeline(std::vector& kStages) {} #endif //DXGL_CHECK_PIPELINE #if DXGL_FULL_EMULATION void CheckCurrentContext(NCryOpenGL::CContext* pContext) { if (pContext->GetDevice()->GetCurrentContext() != pContext) { pContext->GetDevice()->BindContext(pContext); } } #elif DXGL_CHECK_CURRENT_CONTEXT void CheckCurrentContext(NCryOpenGL::CContext* pContext) { if (pContext->GetDevice()->GetCurrentContext() != pContext) { DXGL_ERROR("Device context has not been bound to this thread"); } } #else ILINE void CheckCurrentContext(NCryOpenGL::CContext*) {} #endif //////////////////////////////////////////////////////////////////////////////// // ID3D11DeviceContext implementation //////////////////////////////////////////////////////////////////////////////// void CCryDXGLDeviceContext::SetShaderResources(uint32 uStage, UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { CheckCurrentContext(m_pContext); if (uStage >= m_kStages.size()) { for (uint32 uView = 0; uView < NumViews; ++uView) { if (ppShaderResourceViews[uView] != NULL) { DXGL_ERROR("CCryDXGLDeviceContext::SetShaderResources: shader stage is not supported, setting will be ignored"); break; } } return; } SStage& kStage(m_kStages[uStage]); for (uint32 uView = 0; uView < NumViews; ++uView) { uint32 uSlot(StartSlot + uView); CCryDXGLShaderResourceView* pDXGLShaderResourceView(CCryDXGLShaderResourceView::FromInterface(ppShaderResourceViews[uView])); if (kStage.m_aspShaderResourceViews[uSlot] != pDXGLShaderResourceView) { kStage.m_aspShaderResourceViews[uSlot] = pDXGLShaderResourceView; m_pContext->SetShaderResourceView(pDXGLShaderResourceView == NULL ? NULL : pDXGLShaderResourceView->GetGLView(), uStage, uSlot); } } #if DXGL_CHECK_HAZARDS CheckHazards(m_aspRenderTargetViews, DXGL_ARRAY_SIZE(m_aspRenderTargetViews), kStage.m_aspShaderResourceViews, DXGL_ARRAY_SIZE(kStage.m_aspShaderResourceViews), uStage); CheckHazards(&m_spDepthStencilView, 1, kStage.m_aspShaderResourceViews, DXGL_ARRAY_SIZE(kStage.m_aspShaderResourceViews), uStage); #endif //DXGL_CHECK_HAZARDS } void CCryDXGLDeviceContext::SetUnorderedAccessViews(uint32 uStage, UINT StartSlot, UINT NumViews, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews) { CheckCurrentContext(m_pContext); if (uStage >= m_kStages.size()) { for (uint32 uView = 0; uView < NumViews; ++uView) { if (ppUnorderedAccessViews[uView] != NULL) { DXGL_ERROR("CCryDXGLDeviceContext::SetUnorderedAccessViews: shader stage is not supported, setting will be ignored"); break; } } return; } SStage& kStage(m_kStages[uStage]); for (uint32 uView = 0; uView < NumViews; ++uView) { uint32 uSlot(StartSlot + uView); CCryDXGLUnorderedAccessView* pDXGLUnorderedAccessView(CCryDXGLUnorderedAccessView::FromInterface(ppUnorderedAccessViews[uView])); if (kStage.m_aspUnorderedAccessViews[uSlot] != pDXGLUnorderedAccessView) { kStage.m_aspUnorderedAccessViews[uSlot] = pDXGLUnorderedAccessView; m_pContext->SetUnorderedAccessView(pDXGLUnorderedAccessView == NULL ? NULL : pDXGLUnorderedAccessView->GetGLView(), uStage, uSlot); } } #if DXGL_CHECK_HAZARDS CheckHazards(m_aspRenderTargetViews, DXGL_ARRAY_SIZE(m_aspRenderTargetViews), kStage.m_aspUnorderedAccessViews, DXGL_ARRAY_SIZE(kStage.m_aspUnorderedAccessViews), uStage); CheckHazards(&m_spDepthStencilView, 1, kStage.m_aspUnorderedAccessViews, DXGL_ARRAY_SIZE(kStage.m_aspUnorderedAccessViews), uStage); #endif //DXGL_CHECK_HAZARDS } void CCryDXGLDeviceContext::SetShader(uint32 uStage, CCryDXGLShader* pShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) { if (ppClassInstances != NULL && NumClassInstances != 0) { DXGL_WARNING("Class instances not supported"); } if (uStage >= m_kStages.size()) { if (pShader != NULL) { DXGL_ERROR("CCryDXGLDeviceContext::SetShader: shader stage is not supported, setting will be ignored"); } return; } if (m_kStages[uStage].m_spShader != pShader) { CheckCurrentContext(m_pContext); m_kStages[uStage].m_spShader = pShader; m_pContext->SetShader(pShader == NULL ? NULL : pShader->GetGLShader(), uStage); } } void CCryDXGLDeviceContext::SetSamplers(uint32 uStage, UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { CheckCurrentContext(m_pContext); if (uStage >= m_kStages.size()) { for (uint32 uSampler = 0; uSampler < NumSamplers; ++uSampler) { if (ppSamplers[uSampler] != NULL) { DXGL_ERROR("CCryDXGLDeviceContext::SetSamplers: shader stage is not supported, setting will be ignored"); break; } } return; } SStage& kStage(m_kStages[uStage]); for (uint32 uSampler = 0; uSampler < NumSamplers; ++uSampler) { uint32 uSlot(uSampler + StartSlot); CCryDXGLSamplerState* pSamplerState(CCryDXGLSamplerState::FromInterface(ppSamplers[uSampler])); if (pSamplerState == NULL) { pSamplerState = m_spDefaultSamplerState.get(); } if (pSamplerState != kStage.m_aspSamplerStates[uSlot]) { kStage.m_aspSamplerStates[uSlot] = pSamplerState; pSamplerState->Apply(uStage, uSlot, m_pContext); } } } void CCryDXGLDeviceContext::SetConstantBuffers(uint32 uStage, UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) { CheckCurrentContext(m_pContext); if (uStage >= m_kStages.size()) { //shader stage is not supported, setting will be ignored return; } assert(uStage < m_kStages.size()); SStage& kStage(m_kStages[uStage]); for (uint32 uBuffer = 0; uBuffer < NumBuffers; ++uBuffer) { uint32 uSlot(StartSlot + uBuffer); CCryDXGLBuffer* pConstantBuffer(CCryDXGLBuffer::FromInterface(ppConstantBuffers[uBuffer])); uint32 uOffset(pFirstConstant == NULL ? 0 : pFirstConstant[uBuffer] * 16); uint32 uSize(pNumConstants == NULL ? 0 : pNumConstants[uBuffer] * 16); if (kStage.m_aspConstantBuffers[uSlot] != pConstantBuffer || kStage.m_auConstantBufferOffsets[uSlot] != uOffset || kStage.m_auConstantBufferSizes[uSlot] != uSize) { kStage.m_aspConstantBuffers[uSlot] = pConstantBuffer; kStage.m_auConstantBufferOffsets[uSlot] = uOffset; kStage.m_auConstantBufferSizes[uSlot] = uSize; if (pConstantBuffer == NULL) { m_pContext->SetConstantBuffer(NULL, NCryOpenGL::SBufferRange(uOffset, uSize), uStage, uSlot); } else { NCryOpenGL::SBuffer* pGLBuffer(pConstantBuffer->GetGLBuffer()); if (uSize == 0) { uSize = pGLBuffer->m_uSize; } m_pContext->SetConstantBuffer(pGLBuffer, NCryOpenGL::SBufferRange(uOffset, uSize), uStage, uSlot); } } } } void CCryDXGLDeviceContext::GetShaderResources(uint32 uStage, UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) { if (uStage >= m_kStages.size()) { DXGL_ERROR("CCryDXGLDeviceContext::GetShaderResources: shader stage is not supported, no entries returned"); for (uint32 uView = 0; uView < NumViews; ++uView) { ppShaderResourceViews[uView] = NULL; } return; } SStage& kStage(m_kStages[uStage]); for (uint32 uView = 0; uView < NumViews; ++uView) { uint32 uSlot(StartSlot + uView); CCryDXGLShaderResourceView::ToInterface(ppShaderResourceViews + uView, kStage.m_aspShaderResourceViews[uSlot]); if (ppShaderResourceViews[uView] != NULL) { ppShaderResourceViews[uView]->AddRef(); } } } void CCryDXGLDeviceContext::GetUnorderedAccesses(uint32 uStage, UINT StartSlot, UINT NumViews, ID3D11UnorderedAccessView** ppUnorderedAccessViews) { if (uStage >= m_kStages.size()) { DXGL_ERROR("CCryDXGLDeviceContext::GetUnorderedAccesses: shader stage is not supported, no entries returned"); for (uint32 uView = 0; uView < NumViews; ++uView) { ppUnorderedAccessViews[uView] = NULL; } return; } SStage& kStage(m_kStages[uStage]); for (uint32 uView = 0; uView < NumViews; ++uView) { uint32 uSlot(StartSlot + uView); CCryDXGLUnorderedAccessView::ToInterface(ppUnorderedAccessViews + uView, kStage.m_aspUnorderedAccessViews[uSlot]); if (ppUnorderedAccessViews[uView] != NULL) { ppUnorderedAccessViews[uView]->AddRef(); } } } void CCryDXGLDeviceContext::GetShader(uint32 uStage, CCryDXGLShader** ppShader, ID3D11ClassInstance** ppClassInstances, UINT* NumClassInstances) { if (ppClassInstances != NULL) { DXGL_WARNING("Class instances not supported"); } if (NumClassInstances != NULL) { *NumClassInstances = 0; } if (uStage >= m_kStages.size()) { DXGL_ERROR("CCryDXGLDeviceContext::GetShader: shader stage is not supported, no shader returned"); *ppShader = NULL; return; } *ppShader = m_kStages[uStage].m_spShader.get(); if (*ppShader != NULL) { (*ppShader)->AddRef(); } } void CCryDXGLDeviceContext::GetSamplers(uint32 uStage, UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) { if (uStage >= m_kStages.size()) { DXGL_ERROR("CCryDXGLDeviceContext::GetSamplers: shader stage is not supported, no entries returned"); for (uint32 uSampler = 0; uSampler < NumSamplers; ++uSampler) { ppSamplers[uSampler] = NULL; } return; } SStage& kStage(m_kStages[uStage]); for (uint32 uSampler = 0; uSampler < NumSamplers; ++uSampler) { uint32 uSlot(uSampler + StartSlot); CCryDXGLSamplerState::ToInterface(ppSamplers + uSampler, kStage.m_aspSamplerStates[uSlot]); if (ppSamplers[uSampler] != NULL) { ppSamplers[uSampler]->AddRef(); } } } void CCryDXGLDeviceContext::GetConstantBuffers(uint32 uStage, UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) { if (uStage >= m_kStages.size()) { DXGL_ERROR("CCryDXGLDeviceContext::GetConstantBuffers: shader stage is not supported, no entries returned"); for (uint32 uBuffer = 0; uBuffer < NumBuffers; ++uBuffer) { ppConstantBuffers[uBuffer] = NULL; if (pFirstConstant != NULL) { pFirstConstant[uBuffer] = 0; } if (pNumConstants != NULL) { pNumConstants[uBuffer] = 0; } } return; } assert(uStage < m_kStages.size()); SStage& kStage(m_kStages[uStage]); for (uint32 uBuffer = 0; uBuffer < NumBuffers; ++uBuffer) { uint32 uSlot(StartSlot + uBuffer); CCryDXGLBuffer::ToInterface(ppConstantBuffers + uBuffer, kStage.m_aspConstantBuffers[uSlot]); if (pFirstConstant != NULL) { pFirstConstant[uBuffer] = kStage.m_auConstantBufferOffsets[uSlot]; } if (pNumConstants != NULL) { pNumConstants[uBuffer] = kStage.m_auConstantBufferSizes[uSlot]; } if (ppConstantBuffers[uBuffer] != NULL) { ppConstantBuffers[uBuffer]->AddRef(); } } } #define _IMPLEMENT_COMMON_SHADER_SETTERS(_Prefix, _ShaderInterface, _ShaderType, _Stage) \ void CCryDXGLDeviceContext::_Prefix##SetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView * const* ppShaderResourceViews) \ { \ SetShaderResources(_Stage, StartSlot, NumViews, ppShaderResourceViews); \ } \ void CCryDXGLDeviceContext::_Prefix##SetShader(_ShaderInterface * pShader, ID3D11ClassInstance * const* ppClassInstances, UINT NumClassInstances) \ { \ SetShader(_Stage, _ShaderType::FromInterface(pShader), ppClassInstances, NumClassInstances); \ } \ void CCryDXGLDeviceContext::_Prefix##SetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState * const* ppSamplers) \ { \ SetSamplers(_Stage, StartSlot, NumSamplers, ppSamplers); \ } \ void CCryDXGLDeviceContext::_Prefix##SetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer * const* ppConstantBuffers) \ { \ SetConstantBuffers(_Stage, StartSlot, NumBuffers, ppConstantBuffers); \ } \ void CCryDXGLDeviceContext::_Prefix##SetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer * const* ppConstantBuffers, const UINT * pFirstConstant, const UINT * pNumConstants) \ { \ SetConstantBuffers(_Stage, StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants); \ } \ void CCryDXGLDeviceContext::_Prefix##GetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView * *ppShaderResourceViews) \ { \ GetShaderResources(_Stage, StartSlot, NumViews, ppShaderResourceViews); \ } \ void CCryDXGLDeviceContext::_Prefix##GetShader(_ShaderInterface * *ppShader, ID3D11ClassInstance * *ppClassInstances, UINT * NumClassInstances) \ { \ CCryDXGLShader* pShader(NULL); \ GetShader(_Stage, &pShader, ppClassInstances, NumClassInstances); \ _ShaderType::ToInterface(ppShader, static_cast<_ShaderType*>(pShader)); \ } \ void CCryDXGLDeviceContext::_Prefix##GetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState * *ppSamplers) \ { \ GetSamplers(_Stage, StartSlot, NumSamplers, ppSamplers); \ } \ void CCryDXGLDeviceContext::_Prefix##GetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer * *ppConstantBuffers) \ { \ GetConstantBuffers(_Stage, StartSlot, NumBuffers, ppConstantBuffers); \ } \ void CCryDXGLDeviceContext::_Prefix##GetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer * *ppConstantBuffers, UINT * pFirstConstant, UINT * pNumConstants) \ { \ GetConstantBuffers(_Stage, StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants); \ } _IMPLEMENT_COMMON_SHADER_SETTERS(VS, ID3D11VertexShader, CCryDXGLVertexShader, NCryOpenGL::eST_Vertex) _IMPLEMENT_COMMON_SHADER_SETTERS(PS, ID3D11PixelShader, CCryDXGLPixelShader, NCryOpenGL::eST_Fragment) #if DXGL_SUPPORT_GEOMETRY_SHADERS _IMPLEMENT_COMMON_SHADER_SETTERS(GS, ID3D11GeometryShader, CCryDXGLGeometryShader, NCryOpenGL::eST_Geometry) #else _IMPLEMENT_COMMON_SHADER_SETTERS(GS, ID3D11GeometryShader, CCryDXGLGeometryShader, NCryOpenGL::eST_NUM) #endif #if DXGL_SUPPORT_TESSELLATION _IMPLEMENT_COMMON_SHADER_SETTERS(HS, ID3D11HullShader, CCryDXGLHullShader, NCryOpenGL::eST_TessControl) _IMPLEMENT_COMMON_SHADER_SETTERS(DS, ID3D11DomainShader, CCryDXGLDomainShader, NCryOpenGL::eST_TessEvaluation) #else _IMPLEMENT_COMMON_SHADER_SETTERS(HS, ID3D11HullShader, CCryDXGLHullShader, NCryOpenGL::eST_NUM) _IMPLEMENT_COMMON_SHADER_SETTERS(DS, ID3D11DomainShader, CCryDXGLDomainShader, NCryOpenGL::eST_NUM) #endif #if DXGL_SUPPORT_COMPUTE _IMPLEMENT_COMMON_SHADER_SETTERS(CS, ID3D11ComputeShader, CCryDXGLComputeShader, NCryOpenGL::eST_Compute) #else _IMPLEMENT_COMMON_SHADER_SETTERS(CS, ID3D11ComputeShader, CCryDXGLComputeShader, NCryOpenGL::eST_NUM) #endif #undef _IMPLEMENT_COMMON_SHADER_SETTERS void CCryDXGLDeviceContext::DrawIndexed(UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation) { CheckCurrentContext(m_pContext); CheckPipeline(m_kStages); m_pContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); } void CCryDXGLDeviceContext::Draw(UINT VertexCount, UINT StartVertexLocation) { CheckCurrentContext(m_pContext); CheckPipeline(m_kStages); m_pContext->Draw(VertexCount, StartVertexLocation); } HRESULT CCryDXGLDeviceContext::Map(ID3D11Resource* pResource, UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMappedResource) { CheckCurrentContext(m_pContext); NCryOpenGL::SResource* pGLResource(CCryDXGLResource::FromInterface(pResource)->GetGLResource()); if (pGLResource->m_pfMapSubresource) { return (*pGLResource->m_pfMapSubresource)(pGLResource, Subresource, MapType, MapFlags, pMappedResource, m_pContext) ? S_OK : E_FAIL; } else { DXGL_NOT_IMPLEMENTED return E_FAIL; } } void CCryDXGLDeviceContext::Unmap(ID3D11Resource* pResource, UINT Subresource) { CheckCurrentContext(m_pContext); NCryOpenGL::SResource* pGLResource(CCryDXGLResource::FromInterface(pResource)->GetGLResource()); if (pGLResource->m_pfUnmapSubresource) { (*pGLResource->m_pfUnmapSubresource)(pGLResource, Subresource, m_pContext); } else { DXGL_NOT_IMPLEMENTED } } void CCryDXGLDeviceContext::IASetInputLayout(ID3D11InputLayout* pInputLayout) { CCryDXGLInputLayout* pDXGLInputLayout(CCryDXGLInputLayout::FromInterface(pInputLayout)); if (m_spInputLayout != pDXGLInputLayout) { CheckCurrentContext(m_pContext); m_pContext->SetInputLayout(pDXGLInputLayout == NULL ? NULL : pDXGLInputLayout->GetGLLayout()); m_spInputLayout = pDXGLInputLayout; } } void CCryDXGLDeviceContext::IASetVertexBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppVertexBuffers, const UINT* pStrides, const UINT* pOffsets) { CheckCurrentContext(m_pContext); uint32 uSlot; for (uSlot = 0; uSlot < NumBuffers; ++uSlot) { uint32 uSlotIndex(StartSlot + uSlot); CCryDXGLBuffer* pDXGLVertexBuffer(CCryDXGLBuffer::FromInterface(ppVertexBuffers[uSlot])); if (m_aspVertexBuffers[uSlotIndex] != pDXGLVertexBuffer || m_auVertexBufferStrides[uSlotIndex] != pStrides[uSlot] || m_auVertexBufferOffsets[uSlotIndex] != pOffsets[uSlot]) { m_aspVertexBuffers[uSlotIndex] = pDXGLVertexBuffer; m_auVertexBufferStrides[uSlotIndex] = pStrides[uSlot]; m_auVertexBufferOffsets[uSlotIndex] = pOffsets[uSlot]; m_pContext->SetVertexBuffer(uSlotIndex, pDXGLVertexBuffer == NULL ? 0 : pDXGLVertexBuffer->GetGLBuffer(), pStrides[uSlot], pOffsets[uSlot]); } } } void CCryDXGLDeviceContext::IASetIndexBuffer(ID3D11Buffer* pIndexBuffer, DXGI_FORMAT Format, UINT Offset) { CCryDXGLBuffer* pDXGLIndexBuffer(CCryDXGLBuffer::FromInterface(pIndexBuffer)); m_spIndexBuffer = pDXGLIndexBuffer; m_eIndexBufferFormat = Format; m_uIndexBufferOffset = Offset; CheckCurrentContext(m_pContext); if (pDXGLIndexBuffer == NULL) { m_pContext->SetIndexBuffer(NULL, GL_NONE, 0, 0); } else { const NCryOpenGL::SGIFormatInfo* pFormatInfo; NCryOpenGL::EGIFormat eGIFormat(NCryOpenGL::GetGIFormat(Format)); if (eGIFormat == NCryOpenGL::eGIF_NUM || (pFormatInfo = NCryOpenGL::GetGIFormatInfo(eGIFormat)) == NULL || pFormatInfo->m_pTexture == NULL || pFormatInfo->m_pUncompressed == NULL) { DXGL_ERROR("Invalid format for index buffer"); return; } m_pContext->SetIndexBuffer(pDXGLIndexBuffer->GetGLBuffer(), pFormatInfo->m_pTexture->m_eDataType, pFormatInfo->m_pUncompressed->GetPixelBytes(), Offset); } } void CCryDXGLDeviceContext::DrawIndexedInstanced(UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, INT BaseVertexLocation, UINT StartInstanceLocation) { CheckCurrentContext(m_pContext); CheckPipeline(m_kStages); m_pContext->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); } void CCryDXGLDeviceContext::DrawInstanced(UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation) { CheckCurrentContext(m_pContext); CheckPipeline(m_kStages); m_pContext->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); } void CCryDXGLDeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology) { CheckCurrentContext(m_pContext); m_ePrimitiveTopology = Topology; m_pContext->SetPrimitiveTopology(Topology); } void CCryDXGLDeviceContext::Begin(ID3D11Asynchronous* pAsync) { CheckCurrentContext(m_pContext); NCryOpenGL::SQuery* pQuery(CCryDXGLQuery::FromInterface(pAsync)->GetGLQuery()); if (pQuery) { pQuery->Begin(); } } void CCryDXGLDeviceContext::End(ID3D11Asynchronous* pAsync) { CheckCurrentContext(m_pContext); NCryOpenGL::SQuery* pQuery(CCryDXGLQuery::FromInterface(pAsync)->GetGLQuery()); if (pQuery) { pQuery->End(); } } HRESULT CCryDXGLDeviceContext::GetData(ID3D11Asynchronous* pAsync, void* pData, UINT DataSize, UINT GetDataFlags) { CheckCurrentContext(m_pContext); NCryOpenGL::SQuery* pQuery(CCryDXGLQuery::FromInterface(pAsync)->GetGLQuery()); if (pQuery) { return pQuery->GetData(pData, DataSize, (GetDataFlags & D3D11_ASYNC_GETDATA_DONOTFLUSH) == 0 ? true : false) ? S_OK : E_FAIL; } return E_FAIL; } void CCryDXGLDeviceContext::SetPredication(ID3D11Predicate* pPredicate, BOOL PredicateValue) { if (pPredicate != NULL) { DXGL_NOT_IMPLEMENTED } m_spPredicate = CCryDXGLQuery::FromInterface(pPredicate); m_bPredicateValue = PredicateValue == TRUE; } void CCryDXGLDeviceContext::OMSetRenderTargets(UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, ID3D11DepthStencilView* pDepthStencilView) { OMSetRenderTargetsAndUnorderedAccessViews(NumViews, ppRenderTargetViews, pDepthStencilView, NumViews, 0, NULL, NULL); } void CCryDXGLDeviceContext::OMSetRenderTargetsAndUnorderedAccessViews(UINT NumRTVs, ID3D11RenderTargetView* const* ppRenderTargetViews, ID3D11DepthStencilView* pDepthStencilView, UINT UAVStartSlot, UINT NumUAVs, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts) { NCryOpenGL::SOutputMergerView* apGLRenderTargetViews[DXGL_ARRAY_SIZE(m_aspRenderTargetViews)]; NCryOpenGL::SOutputMergerView* pGLDepthStencilView(NULL); for (uint32 uRTV = 0; uRTV < NumRTVs; ++uRTV) { CCryDXGLRenderTargetView* pDXGLRenderTargetView(CCryDXGLRenderTargetView::FromInterface(ppRenderTargetViews[uRTV])); m_aspRenderTargetViews[uRTV] = pDXGLRenderTargetView; apGLRenderTargetViews[uRTV] = pDXGLRenderTargetView == NULL ? NULL : pDXGLRenderTargetView->GetGLView(); } if (UAVStartSlot == NumRTVs) { SetUnorderedAccessViews(NCryOpenGL::eST_Fragment, 0, NumUAVs, ppUnorderedAccessViews); } else { DXGL_ERROR("CCryDXGLDeviceContext::OMSetRenderTargetsAndUnorderedAccessViews - UAVStartSlot is expected to be equal to NumRTVs"); NumUAVs = 0; } for (uint32 uRTV = NumRTVs; uRTV < DXGL_ARRAY_SIZE(m_aspRenderTargetViews); ++uRTV) { m_aspRenderTargetViews[uRTV] = NULL; apGLRenderTargetViews[uRTV] = NULL; } CCryDXGLDepthStencilView* pDXGLDepthStencilView(CCryDXGLDepthStencilView::FromInterface(pDepthStencilView)); m_spDepthStencilView = pDXGLDepthStencilView; if (pDXGLDepthStencilView != NULL) { pGLDepthStencilView = pDXGLDepthStencilView->GetGLView(); } #if DXGL_CHECK_HAZARDS for (uint32 uStage = 0; uStage < m_kStages.size(); ++uStage) { CheckHazards(m_aspRenderTargetViews, DXGL_ARRAY_SIZE(m_aspRenderTargetViews), m_kStages.at(uStage).m_aspShaderResourceViews, DXGL_ARRAY_SIZE(m_kStages.at(uStage).m_aspShaderResourceViews), uStage); CheckHazards(&m_spDepthStencilView, 1, m_kStages.at(uStage).m_aspShaderResourceViews, DXGL_ARRAY_SIZE(m_kStages.at(uStage).m_aspShaderResourceViews), uStage); } #endif //DXGL_CHECK_HAZARDS CheckCurrentContext(m_pContext); m_pContext->SetRenderTargets(NumRTVs, apGLRenderTargetViews, pGLDepthStencilView); } void CCryDXGLDeviceContext::OMSetBlendState(ID3D11BlendState* pBlendState, const FLOAT BlendFactor[ 4 ], UINT SampleMask) { CheckCurrentContext(m_pContext); CCryDXGLBlendState* pDXGLBlendState( pBlendState == NULL ? m_spDefaultBlendState.get() : CCryDXGLBlendState::FromInterface(pBlendState)); if (pDXGLBlendState != m_spBlendState) { m_spBlendState = pDXGLBlendState; pDXGLBlendState->Apply(m_pContext); } m_uSampleMask = SampleMask; if (BlendFactor == NULL) { m_auBlendFactor[0] = 1.0f; m_auBlendFactor[1] = 1.0f; m_auBlendFactor[2] = 1.0f; m_auBlendFactor[3] = 1.0f; } else { m_auBlendFactor[0] = BlendFactor[0]; m_auBlendFactor[1] = BlendFactor[1]; m_auBlendFactor[2] = BlendFactor[2]; m_auBlendFactor[3] = BlendFactor[3]; } m_pContext->SetBlendColor(m_auBlendFactor[0], m_auBlendFactor[1], m_auBlendFactor[2], m_auBlendFactor[3]); m_pContext->SetSampleMask(m_uSampleMask); } void CCryDXGLDeviceContext::OMSetDepthStencilState(ID3D11DepthStencilState* pDepthStencilState, UINT StencilRef) { CheckCurrentContext(m_pContext); CCryDXGLDepthStencilState* pDXGLDepthStencilState( pDepthStencilState == NULL ? m_spDefaultDepthStencilState.get() : CCryDXGLDepthStencilState::FromInterface(pDepthStencilState)); if (pDXGLDepthStencilState != m_spDepthStencilState || m_uStencilRef != StencilRef) { m_spDepthStencilState = pDXGLDepthStencilState; m_uStencilRef = StencilRef; pDXGLDepthStencilState->Apply(StencilRef, m_pContext); } } void CCryDXGLDeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer* const* ppSOTargets, const UINT* pOffsets) { for (uint32 uBuffer = 0; uBuffer < D3D11_SO_BUFFER_SLOT_COUNT; ++uBuffer) { CCryDXGLBuffer* pDXGLSOBuffer(NULL); uint32 uOffset(0); if (uBuffer < NumBuffers) { pDXGLSOBuffer = CCryDXGLBuffer::FromInterface(ppSOTargets[uBuffer]); uOffset = pOffsets[uBuffer]; } if (m_aspStreamOutputBuffers[uBuffer] != pDXGLSOBuffer || m_auStreamOutputBufferOffsets[uBuffer] != uOffset) { DXGL_NOT_IMPLEMENTED m_aspStreamOutputBuffers[uBuffer] = pDXGLSOBuffer; m_auStreamOutputBufferOffsets[uBuffer] = uOffset; } } } void CCryDXGLDeviceContext::DrawAuto(void) { DXGL_NOT_IMPLEMENTED } void CCryDXGLDeviceContext::DrawIndexedInstancedIndirect(ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) { DXGL_NOT_IMPLEMENTED } void CCryDXGLDeviceContext::DrawInstancedIndirect(ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) { DXGL_NOT_IMPLEMENTED } void CCryDXGLDeviceContext::Dispatch(UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ) { #if DXGL_SUPPORT_COMPUTE CheckCurrentContext(m_pContext); m_pContext->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); #else DXGL_ERROR("CCryDXGLDeviceContext::Dispatch is not supported in this configuration"); #endif } void CCryDXGLDeviceContext::DispatchIndirect(ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) { DXGL_NOT_IMPLEMENTED } void CCryDXGLDeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) { CCryDXGLRasterizerState* pDXGLRasterizerState( pRasterizerState == NULL ? m_spDefaultRasterizerState.get() : CCryDXGLRasterizerState::FromInterface(pRasterizerState)); if (pDXGLRasterizerState != m_spRasterizerState) { CheckCurrentContext(m_pContext); m_spRasterizerState = pDXGLRasterizerState; m_spRasterizerState->Apply(m_pContext); } } void CCryDXGLDeviceContext::RSSetViewports(UINT NumViewports, const D3D11_VIEWPORT* pViewports) { m_uNumViewports = NumViewports; cryMemcpy(m_akViewports, pViewports, min(sizeof(m_akViewports), sizeof(pViewports[0]) * NumViewports)); CheckCurrentContext(m_pContext); m_pContext->SetViewports(NumViewports, pViewports); } void CCryDXGLDeviceContext::RSSetScissorRects(UINT NumRects, const D3D11_RECT* pRects) { m_uNumScissorRects = NumRects; if (NumRects > 0) { cryMemcpy(m_akScissorRects, pRects, min(sizeof(m_akScissorRects), sizeof(pRects[0]) * NumRects)); } CheckCurrentContext(m_pContext); m_pContext->SetScissorRects(NumRects, pRects); } void CCryDXGLDeviceContext::CopySubresourceRegion(ID3D11Resource* pDstResource, UINT DstSubresource, UINT DstX, UINT DstY, UINT DstZ, ID3D11Resource* pSrcResource, UINT SrcSubresource, const D3D11_BOX* pSrcBox) { CCryDXGLResource* pDXGLDstResource(CCryDXGLResource::FromInterface(pDstResource)); CCryDXGLResource* pDXGLSrcResource(CCryDXGLResource::FromInterface(pSrcResource)); CheckCurrentContext(m_pContext); D3D11_RESOURCE_DIMENSION kDstType, kSrcType; pDXGLDstResource->GetType(&kDstType); pDXGLSrcResource->GetType(&kSrcType); if (kDstType == kSrcType) { switch (kDstType) { case D3D11_RESOURCE_DIMENSION_TEXTURE1D: case D3D11_RESOURCE_DIMENSION_TEXTURE2D: case D3D11_RESOURCE_DIMENSION_TEXTURE3D: NCryOpenGL::CopySubTexture( static_cast(pDXGLDstResource->GetGLResource()), DstSubresource, DstX, DstY, DstZ, static_cast(pDXGLSrcResource->GetGLResource()), SrcSubresource, pSrcBox, m_pContext); break; case D3D11_RESOURCE_DIMENSION_BUFFER: NCryOpenGL::CopySubBuffer( static_cast(pDXGLDstResource->GetGLResource()), DstSubresource, DstX, DstY, DstZ, static_cast(pDXGLSrcResource->GetGLResource()), SrcSubresource, pSrcBox, m_pContext); break; default: assert(false); break; } } } void CCryDXGLDeviceContext::CopyResource(ID3D11Resource* pDstResource, ID3D11Resource* pSrcResource) { CCryDXGLResource* pDXGLDstResource(CCryDXGLResource::FromInterface(pDstResource)); CCryDXGLResource* pDXGLSrcResource(CCryDXGLResource::FromInterface(pSrcResource)); D3D11_RESOURCE_DIMENSION kDstType, kSrcType; pDXGLDstResource->GetType(&kDstType); pDXGLSrcResource->GetType(&kSrcType); if (kDstType == kSrcType) { CheckCurrentContext(m_pContext); switch (kDstType) { case D3D11_RESOURCE_DIMENSION_TEXTURE1D: case D3D11_RESOURCE_DIMENSION_TEXTURE2D: case D3D11_RESOURCE_DIMENSION_TEXTURE3D: NCryOpenGL::CopyTexture( static_cast(pDXGLDstResource->GetGLResource()), static_cast(pDXGLSrcResource->GetGLResource()), m_pContext); break; case D3D11_RESOURCE_DIMENSION_BUFFER: NCryOpenGL::CopyBuffer( static_cast(pDXGLDstResource->GetGLResource()), static_cast(pDXGLSrcResource->GetGLResource()), m_pContext); break; default: assert(false); break; } } else { DXGL_ERROR("CopyResource failed - source and destination are resources of different type"); } } void CCryDXGLDeviceContext::UpdateSubresource(ID3D11Resource* pDstResource, UINT DstSubresource, const D3D11_BOX* pDstBox, const void* pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch) { CheckCurrentContext(m_pContext); NCryOpenGL::SResource* pGLResource(CCryDXGLResource::FromInterface(pDstResource)->GetGLResource()); if (pGLResource->m_pfUpdateSubresource) { (*pGLResource->m_pfUpdateSubresource)(pGLResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, m_pContext); } else { DXGL_NOT_IMPLEMENTED } } void CCryDXGLDeviceContext::CopyStructureCount(ID3D11Buffer* pDstBuffer, UINT DstAlignedByteOffset, ID3D11UnorderedAccessView* pSrcView) { DXGL_NOT_IMPLEMENTED } void CCryDXGLDeviceContext::ClearRenderTargetView(ID3D11RenderTargetView* pRenderTargetView, const FLOAT ColorRGBA[ 4 ]) { CheckCurrentContext(m_pContext); CCryDXGLRenderTargetView* pDXGLRenderTargetView(CCryDXGLRenderTargetView::FromInterface(pRenderTargetView)); m_pContext->ClearRenderTarget(pDXGLRenderTargetView == NULL ? NULL : pDXGLRenderTargetView->GetGLView(), ColorRGBA); } void CCryDXGLDeviceContext::ClearUnorderedAccessViewUint(ID3D11UnorderedAccessView* pUnorderedAccessView, const UINT Values[ 4 ]) { DXGL_NOT_IMPLEMENTED } void CCryDXGLDeviceContext::ClearUnorderedAccessViewFloat(ID3D11UnorderedAccessView* pUnorderedAccessView, const FLOAT Values[ 4 ]) { DXGL_NOT_IMPLEMENTED } void CCryDXGLDeviceContext::ClearDepthStencilView(ID3D11DepthStencilView* pDepthStencilView, UINT ClearFlags, FLOAT Depth, UINT8 Stencil) { CheckCurrentContext(m_pContext); CCryDXGLDepthStencilView* pDXGLDepthStencilView(CCryDXGLDepthStencilView::FromInterface(pDepthStencilView)); m_pContext->ClearDepthStencil(pDXGLDepthStencilView == NULL ? NULL : pDXGLDepthStencilView->GetGLView(), (ClearFlags & D3D11_CLEAR_DEPTH) != 0, (ClearFlags & D3D11_CLEAR_STENCIL) != 0, Depth, Stencil); } void CCryDXGLDeviceContext::GenerateMips(ID3D11ShaderResourceView* pShaderResourceView) { CheckCurrentContext(m_pContext); NCryOpenGL::SShaderView* pGLView(CCryDXGLShaderResourceView::FromInterface(pShaderResourceView)->GetGLView()); switch (pGLView->m_eType) { case NCryOpenGL::SShaderView::eSVT_Texture: static_cast(pGLView)->GenerateMipmaps(m_pContext); break; default: DXGL_ERROR("Generation of mipmaps for this type of resource view is not supported"); break; } } void CCryDXGLDeviceContext::SetResourceMinLOD(ID3D11Resource* pResource, FLOAT MinLOD) { CCryDXGLResource* pDXGLDstResource(CCryDXGLResource::FromInterface(pResource)); static_cast(pDXGLDstResource->GetGLResource())->SetMinLod(MinLOD); } FLOAT CCryDXGLDeviceContext::GetResourceMinLOD(ID3D11Resource* pResource) { CCryDXGLResource* pDXGLDstResource(CCryDXGLResource::FromInterface(pResource)); return static_cast(pDXGLDstResource->GetGLResource())->GetMinLod(); } void CCryDXGLDeviceContext::ResolveSubresource(ID3D11Resource* pDstResource, UINT DstSubresource, ID3D11Resource* pSrcResource, UINT SrcSubresource, DXGI_FORMAT Format) { DXGL_NOT_IMPLEMENTED } void CCryDXGLDeviceContext::ExecuteCommandList(ID3D11CommandList* pCommandList, BOOL RestoreContextState) { DXGL_NOT_IMPLEMENTED } void CCryDXGLDeviceContext::CSSetUnorderedAccessViews(UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts) { #if DXGL_SUPPORT_COMPUTE SetUnorderedAccessViews(NCryOpenGL::eST_Compute, StartSlot, NumUAVs, ppUnorderedAccessViews); #else DXGL_ERROR("CCryDXGLDeviceContext::CSSetUnorderedAccessViews is not supported in this configuration"); #endif //DXGL_SUPPORT_COMPUTE } void CCryDXGLDeviceContext::IAGetInputLayout(ID3D11InputLayout** ppInputLayout) { CCryDXGLInputLayout::ToInterface(ppInputLayout, m_spInputLayout); if ((*ppInputLayout) != NULL) { (*ppInputLayout)->AddRef(); } } void CCryDXGLDeviceContext::IAGetVertexBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppVertexBuffers, UINT* pStrides, UINT* pOffsets) { uint32 uSlot; for (uSlot = 0; uSlot < NumBuffers; ++uSlot) { uint32 uSlotIndex(StartSlot + uSlot); CCryDXGLBuffer::ToInterface(ppVertexBuffers + uSlot, m_aspVertexBuffers[uSlotIndex]); if (ppVertexBuffers[uSlot] != NULL) { ppVertexBuffers[uSlot]->AddRef(); } pStrides[uSlot] = m_auVertexBufferStrides[uSlotIndex]; pOffsets[uSlot] = m_auVertexBufferOffsets[uSlotIndex]; } } void CCryDXGLDeviceContext::IAGetIndexBuffer(ID3D11Buffer** pIndexBuffer, DXGI_FORMAT* Format, UINT* Offset) { CCryDXGLBuffer::ToInterface(pIndexBuffer, m_spIndexBuffer); if ((*pIndexBuffer) != NULL) { (*pIndexBuffer)->AddRef(); } *Format = m_eIndexBufferFormat; *Offset = m_uIndexBufferOffset; } void CCryDXGLDeviceContext::IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY* pTopology) { *pTopology = m_ePrimitiveTopology; } void CCryDXGLDeviceContext::GetPredication(ID3D11Predicate** ppPredicate, BOOL* pPredicateValue) { ID3D11Query* pQuery; CCryDXGLQuery::ToInterface(&pQuery, m_spPredicate); *ppPredicate = static_cast(pQuery); *pPredicateValue = (m_bPredicateValue ? TRUE : FALSE); } void CCryDXGLDeviceContext::OMGetRenderTargets(UINT NumViews, ID3D11RenderTargetView** ppRenderTargetViews, ID3D11DepthStencilView** ppDepthStencilView) { OMGetRenderTargetsAndUnorderedAccessViews(NumViews, ppRenderTargetViews, ppDepthStencilView, 0, 0, NULL); } void CCryDXGLDeviceContext::OMGetRenderTargetsAndUnorderedAccessViews(UINT NumRTVs, ID3D11RenderTargetView** ppRenderTargetViews, ID3D11DepthStencilView** ppDepthStencilView, UINT UAVStartSlot, UINT NumUAVs, ID3D11UnorderedAccessView** ppUnorderedAccessViews) { for (uint32 uRTV = 0; uRTV < NumRTVs; ++uRTV) { CCryDXGLRenderTargetView::ToInterface(ppRenderTargetViews + uRTV, m_aspRenderTargetViews[uRTV]); if (ppRenderTargetViews[uRTV] != NULL) { ppRenderTargetViews[uRTV]->AddRef(); } } CCryDXGLDepthStencilView::ToInterface(ppDepthStencilView, m_spDepthStencilView); if ((*ppDepthStencilView) != NULL) { (*ppDepthStencilView)->AddRef(); } GetUnorderedAccesses(NCryOpenGL::eST_Fragment, 0, NumUAVs, ppUnorderedAccessViews); } void CCryDXGLDeviceContext::OMGetBlendState(ID3D11BlendState** ppBlendState, FLOAT BlendFactor[ 4 ], UINT* pSampleMask) { CCryDXGLBlendState::ToInterface(ppBlendState, m_spBlendState); if ((*ppBlendState) != NULL) { (*ppBlendState)->AddRef(); } BlendFactor[0] = m_auBlendFactor[0]; BlendFactor[1] = m_auBlendFactor[1]; BlendFactor[2] = m_auBlendFactor[2]; BlendFactor[3] = m_auBlendFactor[3]; *pSampleMask = m_uSampleMask; } void CCryDXGLDeviceContext::OMGetDepthStencilState(ID3D11DepthStencilState** ppDepthStencilState, UINT* pStencilRef) { CCryDXGLDepthStencilState::ToInterface(ppDepthStencilState, m_spDepthStencilState); if ((*ppDepthStencilState) != NULL) { (*ppDepthStencilState)->AddRef(); } *pStencilRef = m_uStencilRef; } void CCryDXGLDeviceContext::SOGetTargets(UINT NumBuffers, ID3D11Buffer** ppSOTargets) { for (uint32 uBuffer = 0; uBuffer < NumBuffers; ++uBuffer) { CCryDXGLBuffer::ToInterface(ppSOTargets + uBuffer, m_aspStreamOutputBuffers[uBuffer]); if (ppSOTargets[uBuffer] != NULL) { ppSOTargets[uBuffer]->AddRef(); } } } void CCryDXGLDeviceContext::RSGetState(ID3D11RasterizerState** ppRasterizerState) { CCryDXGLRasterizerState::ToInterface(ppRasterizerState, m_spRasterizerState); if ((*ppRasterizerState) != NULL) { (*ppRasterizerState)->AddRef(); } } void CCryDXGLDeviceContext::RSGetViewports(UINT* pNumViewports, D3D11_VIEWPORT* pViewports) { if (pViewports != NULL) { cryMemcpy(pViewports, m_akViewports, min(sizeof(m_akViewports), sizeof(pViewports[0]) * *pNumViewports)); } *pNumViewports = m_uNumViewports; } void CCryDXGLDeviceContext::RSGetScissorRects(UINT* pNumRects, D3D11_RECT* pRects) { if (pRects != NULL) { cryMemcpy(pRects, m_akScissorRects, min(sizeof(m_akScissorRects), sizeof(pRects[0]) * *pNumRects)); } *pNumRects = m_uNumScissorRects; } void CCryDXGLDeviceContext::CSGetUnorderedAccessViews(UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView** ppUnorderedAccessViews) { #if DXGL_SUPPORT_COMPUTE GetUnorderedAccesses(NCryOpenGL::eST_Compute, StartSlot, NumUAVs, ppUnorderedAccessViews); #else DXGL_ERROR("CCryDXGLDeviceContext::CSGetUnorderedAccessViews is not supported in this configuration"); #endif //DXGL_SUPPORT_COMPUTE } void CCryDXGLDeviceContext::ClearState(void) { CheckCurrentContext(m_pContext); // Common shader state for (uint32 uStage = 0; uStage < m_kStages.size(); ++uStage) { SStage& kStage(m_kStages.at(uStage)); for (uint32 uSRV = 0; uSRV < DXGL_ARRAY_SIZE(kStage.m_aspShaderResourceViews); ++uSRV) { if (kStage.m_aspShaderResourceViews[uSRV] != NULL) { m_pContext->SetShaderTexture(NULL, uStage, uSRV); kStage.m_aspShaderResourceViews[uSRV] = NULL; } } #if DXGL_SUPPORT_SHADER_IMAGES if (m_pContext->GetDevice()->IsFeatureSupported(NCryOpenGL::eF_ShaderImages)) { for (uint32 uUAV = 0; uUAV < DXGL_ARRAY_SIZE(kStage.m_aspUnorderedAccessViews); ++uUAV) { if (kStage.m_aspUnorderedAccessViews[uUAV] != NULL) { m_pContext->SetShaderImage(NULL, uStage, uUAV); kStage.m_aspUnorderedAccessViews[uUAV] = NULL; } } } #endif //DXGL_SUPPORT_SHADER_IMAGES for (uint32 uSampler = 0; uSampler < DXGL_ARRAY_SIZE(kStage.m_aspSamplerStates); ++uSampler) { if (kStage.m_aspSamplerStates[uSampler] != m_spDefaultSamplerState) { m_spDefaultSamplerState->Apply(uStage, uSampler, m_pContext); kStage.m_aspSamplerStates[uSampler] = m_spDefaultSamplerState; } } for (uint32 uCB = 0; uCB < DXGL_ARRAY_SIZE(kStage.m_aspConstantBuffers); ++uCB) { if (kStage.m_aspConstantBuffers[uCB] != NULL) { m_pContext->SetConstantBuffer(NULL, NCryOpenGL::SBufferRange(0, 0), uStage, uCB); kStage.m_aspConstantBuffers[uCB] = NULL; kStage.m_auConstantBufferOffsets[uCB] = 0; kStage.m_auConstantBufferSizes[uCB] = 0; } } if (m_kStages[uStage].m_spShader != NULL) { m_pContext->SetShader(NULL, uStage); m_kStages[uStage].m_spShader = NULL; } } // Vertex buffers for (uint32 uVB = 0; uVB < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++uVB) { if (m_aspVertexBuffers[uVB] != NULL || m_auVertexBufferStrides[uVB] != 0 || m_auVertexBufferOffsets[uVB] != 0) { m_pContext->SetVertexBuffer(uVB, NULL, 0, 0); m_aspVertexBuffers[uVB] = NULL; m_auVertexBufferStrides[uVB] = 0; m_auVertexBufferOffsets[uVB] = 0; } } // Index buffer if (m_spIndexBuffer != NULL || m_eIndexBufferFormat != DXGI_FORMAT_UNKNOWN || m_uIndexBufferOffset != 0) { m_pContext->SetIndexBuffer(NULL, GL_NONE, 0, 0); m_spIndexBuffer = NULL; m_eIndexBufferFormat = DXGI_FORMAT_UNKNOWN; m_uIndexBufferOffset = 0; } // Input layout if (m_spInputLayout != NULL) { m_pContext->SetInputLayout(NULL); m_spInputLayout = NULL; } // Primitive topology if (m_ePrimitiveTopology != D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED) { m_pContext->SetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED); m_ePrimitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; } // Output merger state OMSetBlendState(NULL, NULL, 0xFFFFFFFF); OMSetDepthStencilState(NULL, 0); OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, 0, NULL, NULL); // Rasterizer state m_uNumScissorRects = 0; m_pContext->SetScissorRects(0, NULL); m_uNumViewports; m_pContext->SetViewports(0, NULL); RSSetState(NULL); // Predication SetPredication(NULL, FALSE); // Stream output SOSetTargets(0, NULL, NULL); } void CCryDXGLDeviceContext::Flush(void) { CheckCurrentContext(m_pContext); m_pContext->Flush(); } D3D11_DEVICE_CONTEXT_TYPE CCryDXGLDeviceContext::GetType(void) { DXGL_TODO("Modify when deferred contexts are supported") return D3D11_DEVICE_CONTEXT_IMMEDIATE; } UINT CCryDXGLDeviceContext::GetContextFlags(void) { return 0; } HRESULT CCryDXGLDeviceContext::FinishCommandList(BOOL RestoreDeferredContextState, ID3D11CommandList** ppCommandList) { DXGL_NOT_IMPLEMENTED return E_FAIL; }