You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1485 lines
60 KiB
C++
1485 lines
60 KiB
C++
/*
|
|
* 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 "RenderDll_precompiled.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<SStage>::iterator kStageIter(m_kStages.begin());
|
|
const std::vector<SStage>::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<CCryDXGLBlendState> 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<CCryDXGLDepthStencilState> 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<CCryDXGLRasterizerState> 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<CCryDXGLSamplerState> 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 <typename OMView>
|
|
void CheckHazards(_smart_ptr<OMView>* pOMViews, uint32 uNumOMViews, _smart_ptr<CCryDXGLShaderResourceView>* 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 <typename Stage>
|
|
void CheckRequiredStage(std::vector<Stage>& 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 <typename Stage>
|
|
void CheckPipeline(std::vector<Stage>& kStages)
|
|
{
|
|
CheckRequiredStage(kStages, NCryOpenGL::eST_Vertex);
|
|
CheckRequiredStage(kStages, NCryOpenGL::eST_Fragment);
|
|
}
|
|
#else
|
|
template <typename Stage>
|
|
ILINE void CheckPipeline(std::vector<Stage>& 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<NCryOpenGL::STexture*>(pDXGLDstResource->GetGLResource()), DstSubresource, DstX, DstY, DstZ,
|
|
static_cast<NCryOpenGL::STexture*>(pDXGLSrcResource->GetGLResource()), SrcSubresource, pSrcBox, m_pContext);
|
|
break;
|
|
case D3D11_RESOURCE_DIMENSION_BUFFER:
|
|
NCryOpenGL::CopySubBuffer(
|
|
static_cast<NCryOpenGL::SBuffer*>(pDXGLDstResource->GetGLResource()), DstSubresource, DstX, DstY, DstZ,
|
|
static_cast<NCryOpenGL::SBuffer*>(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<NCryOpenGL::STexture*>(pDXGLDstResource->GetGLResource()),
|
|
static_cast<NCryOpenGL::STexture*>(pDXGLSrcResource->GetGLResource()),
|
|
m_pContext);
|
|
break;
|
|
case D3D11_RESOURCE_DIMENSION_BUFFER:
|
|
NCryOpenGL::CopyBuffer(
|
|
static_cast<NCryOpenGL::SBuffer*>(pDXGLDstResource->GetGLResource()),
|
|
static_cast<NCryOpenGL::SBuffer*>(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<NCryOpenGL::SShaderTextureBasedView*>(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<NCryOpenGL::STexture*>(pDXGLDstResource->GetGLResource())->SetMinLod(MinLOD);
|
|
}
|
|
|
|
FLOAT CCryDXGLDeviceContext::GetResourceMinLOD(ID3D11Resource* pResource)
|
|
{
|
|
CCryDXGLResource* pDXGLDstResource(CCryDXGLResource::FromInterface(pResource));
|
|
return static_cast<NCryOpenGL::STexture*>(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<ID3D11Predicate*>(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;
|
|
}
|