2022-08-03 16:33:54 +02:00
|
|
|
#include "d3d11_context_common.h"
|
|
|
|
#include "d3d11_context_def.h"
|
|
|
|
#include "d3d11_context_imm.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
D3D11CommonContext<ContextType>::D3D11CommonContext(
|
|
|
|
D3D11Device* pParent,
|
|
|
|
const Rc<DxvkDevice>& Device,
|
|
|
|
DxvkCsChunkFlags CsFlags)
|
2022-08-03 17:13:32 +02:00
|
|
|
: D3D11DeviceContext(pParent, Device, CsFlags),
|
2022-08-03 18:07:03 +02:00
|
|
|
m_contextExt(GetTypedContext()),
|
|
|
|
m_annotation(GetTypedContext(), Device) {
|
2022-08-03 16:33:54 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
D3D11CommonContext<ContextType>::~D3D11CommonContext() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-03 16:41:50 +02:00
|
|
|
|
2022-08-03 17:09:30 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11CommonContext<ContextType>::QueryInterface(REFIID riid, void** ppvObject) {
|
|
|
|
if (ppvObject == nullptr)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
*ppvObject = nullptr;
|
|
|
|
|
|
|
|
if (riid == __uuidof(IUnknown)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceChild)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceContext)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceContext1)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceContext2)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceContext3)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceContext4)) {
|
|
|
|
*ppvObject = ref(this);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (riid == __uuidof(ID3D11VkExtContext)
|
|
|
|
|| riid == __uuidof(ID3D11VkExtContext1)) {
|
|
|
|
*ppvObject = ref(&m_contextExt);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (riid == __uuidof(ID3DUserDefinedAnnotation)
|
|
|
|
|| riid == __uuidof(IDXVKUserDefinedAnnotation)) {
|
|
|
|
*ppvObject = ref(&m_annotation);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (riid == __uuidof(ID3D10Multithread)) {
|
|
|
|
*ppvObject = ref(&m_multithread);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query");
|
|
|
|
Logger::warn(str::format(riid));
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:27:33 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::ClearState() {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
// Default shaders
|
|
|
|
m_state.vs.shader = nullptr;
|
|
|
|
m_state.hs.shader = nullptr;
|
|
|
|
m_state.ds.shader = nullptr;
|
|
|
|
m_state.gs.shader = nullptr;
|
|
|
|
m_state.ps.shader = nullptr;
|
|
|
|
m_state.cs.shader = nullptr;
|
|
|
|
|
|
|
|
// Default constant buffers
|
|
|
|
for (uint32_t i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) {
|
|
|
|
m_state.vs.constantBuffers[i] = { nullptr, 0, 0 };
|
|
|
|
m_state.hs.constantBuffers[i] = { nullptr, 0, 0 };
|
|
|
|
m_state.ds.constantBuffers[i] = { nullptr, 0, 0 };
|
|
|
|
m_state.gs.constantBuffers[i] = { nullptr, 0, 0 };
|
|
|
|
m_state.ps.constantBuffers[i] = { nullptr, 0, 0 };
|
|
|
|
m_state.cs.constantBuffers[i] = { nullptr, 0, 0 };
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default samplers
|
|
|
|
for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) {
|
|
|
|
m_state.vs.samplers[i] = nullptr;
|
|
|
|
m_state.hs.samplers[i] = nullptr;
|
|
|
|
m_state.ds.samplers[i] = nullptr;
|
|
|
|
m_state.gs.samplers[i] = nullptr;
|
|
|
|
m_state.ps.samplers[i] = nullptr;
|
|
|
|
m_state.cs.samplers[i] = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default shader resources
|
|
|
|
for (uint32_t i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) {
|
|
|
|
m_state.vs.shaderResources.views[i] = nullptr;
|
|
|
|
m_state.hs.shaderResources.views[i] = nullptr;
|
|
|
|
m_state.ds.shaderResources.views[i] = nullptr;
|
|
|
|
m_state.gs.shaderResources.views[i] = nullptr;
|
|
|
|
m_state.ps.shaderResources.views[i] = nullptr;
|
|
|
|
m_state.cs.shaderResources.views[i] = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_state.vs.shaderResources.hazardous.clear();
|
|
|
|
m_state.hs.shaderResources.hazardous.clear();
|
|
|
|
m_state.ds.shaderResources.hazardous.clear();
|
|
|
|
m_state.gs.shaderResources.hazardous.clear();
|
|
|
|
m_state.ps.shaderResources.hazardous.clear();
|
|
|
|
m_state.cs.shaderResources.hazardous.clear();
|
|
|
|
|
|
|
|
// Default UAVs
|
|
|
|
for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) {
|
|
|
|
m_state.ps.unorderedAccessViews[i] = nullptr;
|
|
|
|
m_state.cs.unorderedAccessViews[i] = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_state.cs.uavMask.clear();
|
|
|
|
|
|
|
|
// Default ID state
|
|
|
|
m_state.id.argBuffer = nullptr;
|
|
|
|
|
|
|
|
// Default IA state
|
|
|
|
m_state.ia.inputLayout = nullptr;
|
|
|
|
m_state.ia.primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) {
|
|
|
|
m_state.ia.vertexBuffers[i].buffer = nullptr;
|
|
|
|
m_state.ia.vertexBuffers[i].offset = 0;
|
|
|
|
m_state.ia.vertexBuffers[i].stride = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_state.ia.indexBuffer.buffer = nullptr;
|
|
|
|
m_state.ia.indexBuffer.offset = 0;
|
|
|
|
m_state.ia.indexBuffer.format = DXGI_FORMAT_UNKNOWN;
|
|
|
|
|
|
|
|
// Default OM State
|
|
|
|
for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
|
|
|
m_state.om.renderTargetViews[i] = nullptr;
|
|
|
|
m_state.om.depthStencilView = nullptr;
|
|
|
|
|
|
|
|
m_state.om.cbState = nullptr;
|
|
|
|
m_state.om.dsState = nullptr;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < 4; i++)
|
|
|
|
m_state.om.blendFactor[i] = 1.0f;
|
|
|
|
|
|
|
|
m_state.om.sampleCount = 0;
|
|
|
|
m_state.om.sampleMask = D3D11_DEFAULT_SAMPLE_MASK;
|
|
|
|
m_state.om.stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE;
|
|
|
|
|
|
|
|
m_state.om.maxRtv = 0;
|
|
|
|
m_state.om.maxUav = 0;
|
|
|
|
|
|
|
|
// Default RS state
|
|
|
|
m_state.rs.state = nullptr;
|
|
|
|
m_state.rs.numViewports = 0;
|
|
|
|
m_state.rs.numScissors = 0;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) {
|
|
|
|
m_state.rs.viewports[i] = D3D11_VIEWPORT { };
|
|
|
|
m_state.rs.scissors [i] = D3D11_RECT { };
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default SO state
|
|
|
|
for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) {
|
|
|
|
m_state.so.targets[i].buffer = nullptr;
|
|
|
|
m_state.so.targets[i].offset = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default predication
|
|
|
|
m_state.pr.predicateObject = nullptr;
|
|
|
|
m_state.pr.predicateValue = FALSE;
|
|
|
|
|
|
|
|
// Make sure to apply all state
|
|
|
|
ResetState();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 16:41:50 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::UpdateSubresource(
|
|
|
|
ID3D11Resource* pDstResource,
|
|
|
|
UINT DstSubresource,
|
|
|
|
const D3D11_BOX* pDstBox,
|
|
|
|
const void* pSrcData,
|
|
|
|
UINT SrcRowPitch,
|
|
|
|
UINT SrcDepthPitch) {
|
|
|
|
UpdateResource(pDstResource, DstSubresource, pDstBox,
|
|
|
|
pSrcData, SrcRowPitch, SrcDepthPitch, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::UpdateSubresource1(
|
|
|
|
ID3D11Resource* pDstResource,
|
|
|
|
UINT DstSubresource,
|
|
|
|
const D3D11_BOX* pDstBox,
|
|
|
|
const void* pSrcData,
|
|
|
|
UINT SrcRowPitch,
|
|
|
|
UINT SrcDepthPitch,
|
|
|
|
UINT CopyFlags) {
|
|
|
|
UpdateResource(pDstResource, DstSubresource, pDstBox,
|
|
|
|
pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 18:15:32 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::IASetInputLayout(ID3D11InputLayout* pInputLayout) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto inputLayout = static_cast<D3D11InputLayout*>(pInputLayout);
|
|
|
|
|
|
|
|
if (m_state.ia.inputLayout != inputLayout) {
|
|
|
|
bool equal = false;
|
|
|
|
|
|
|
|
// Some games (e.g. Grim Dawn) create lots and lots of
|
|
|
|
// identical input layouts, so we'll only apply the state
|
|
|
|
// if the input layouts has actually changed between calls.
|
|
|
|
if (m_state.ia.inputLayout != nullptr && inputLayout != nullptr)
|
|
|
|
equal = m_state.ia.inputLayout->Compare(inputLayout);
|
|
|
|
|
|
|
|
m_state.ia.inputLayout = inputLayout;
|
|
|
|
|
|
|
|
if (!equal)
|
|
|
|
ApplyInputLayout();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (m_state.ia.primitiveTopology != Topology) {
|
|
|
|
m_state.ia.primitiveTopology = Topology;
|
|
|
|
ApplyPrimitiveTopology();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::IASetVertexBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppVertexBuffers,
|
|
|
|
const UINT* pStrides,
|
|
|
|
const UINT* pOffsets) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++) {
|
|
|
|
auto newBuffer = static_cast<D3D11Buffer*>(ppVertexBuffers[i]);
|
|
|
|
bool needsUpdate = m_state.ia.vertexBuffers[StartSlot + i].buffer != newBuffer;
|
|
|
|
|
|
|
|
if (needsUpdate)
|
|
|
|
m_state.ia.vertexBuffers[StartSlot + i].buffer = newBuffer;
|
|
|
|
|
|
|
|
needsUpdate |= m_state.ia.vertexBuffers[StartSlot + i].offset != pOffsets[i]
|
|
|
|
|| m_state.ia.vertexBuffers[StartSlot + i].stride != pStrides[i];
|
|
|
|
|
|
|
|
if (needsUpdate) {
|
|
|
|
m_state.ia.vertexBuffers[StartSlot + i].offset = pOffsets[i];
|
|
|
|
m_state.ia.vertexBuffers[StartSlot + i].stride = pStrides[i];
|
|
|
|
|
|
|
|
BindVertexBuffer(StartSlot + i, newBuffer, pOffsets[i], pStrides[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::IASetIndexBuffer(
|
|
|
|
ID3D11Buffer* pIndexBuffer,
|
|
|
|
DXGI_FORMAT Format,
|
|
|
|
UINT Offset) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto newBuffer = static_cast<D3D11Buffer*>(pIndexBuffer);
|
|
|
|
bool needsUpdate = m_state.ia.indexBuffer.buffer != newBuffer;
|
|
|
|
|
|
|
|
if (needsUpdate)
|
|
|
|
m_state.ia.indexBuffer.buffer = newBuffer;
|
|
|
|
|
|
|
|
needsUpdate |= m_state.ia.indexBuffer.offset != Offset
|
|
|
|
|| m_state.ia.indexBuffer.format != Format;
|
|
|
|
|
|
|
|
if (needsUpdate) {
|
|
|
|
m_state.ia.indexBuffer.offset = Offset;
|
|
|
|
m_state.ia.indexBuffer.format = Format;
|
|
|
|
|
|
|
|
BindIndexBuffer(newBuffer, Offset, Format);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::IAGetInputLayout(ID3D11InputLayout** ppInputLayout) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
*ppInputLayout = m_state.ia.inputLayout.ref();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY* pTopology) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
*pTopology = m_state.ia.primitiveTopology;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::IAGetVertexBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppVertexBuffers,
|
|
|
|
UINT* pStrides,
|
|
|
|
UINT* pOffsets) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++) {
|
|
|
|
const bool inRange = StartSlot + i < m_state.ia.vertexBuffers.size();
|
|
|
|
|
|
|
|
if (ppVertexBuffers) {
|
|
|
|
ppVertexBuffers[i] = inRange
|
|
|
|
? m_state.ia.vertexBuffers[StartSlot + i].buffer.ref()
|
|
|
|
: nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pStrides) {
|
|
|
|
pStrides[i] = inRange
|
|
|
|
? m_state.ia.vertexBuffers[StartSlot + i].stride
|
|
|
|
: 0u;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pOffsets) {
|
|
|
|
pOffsets[i] = inRange
|
|
|
|
? m_state.ia.vertexBuffers[StartSlot + i].offset
|
|
|
|
: 0u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::IAGetIndexBuffer(
|
|
|
|
ID3D11Buffer** ppIndexBuffer,
|
|
|
|
DXGI_FORMAT* pFormat,
|
|
|
|
UINT* pOffset) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppIndexBuffer)
|
|
|
|
*ppIndexBuffer = m_state.ia.indexBuffer.buffer.ref();
|
|
|
|
|
|
|
|
if (pFormat)
|
|
|
|
*pFormat = m_state.ia.indexBuffer.format;
|
|
|
|
|
|
|
|
if (pOffset)
|
|
|
|
*pOffset = m_state.ia.indexBuffer.offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSSetShader(
|
|
|
|
ID3D11VertexShader* pVertexShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto shader = static_cast<D3D11VertexShader*>(pVertexShader);
|
|
|
|
|
|
|
|
if (NumClassInstances)
|
|
|
|
Logger::err("D3D11: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.vs.shader != shader) {
|
|
|
|
m_state.vs.shader = shader;
|
|
|
|
|
|
|
|
BindShader<DxbcProgramType::VertexShader>(GetCommonShader(shader));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSSetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers<DxbcProgramType::VertexShader>(
|
|
|
|
m_state.vs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSSetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers,
|
|
|
|
const UINT* pFirstConstant,
|
|
|
|
const UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers1<DxbcProgramType::VertexShader>(
|
|
|
|
m_state.vs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSSetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetShaderResources<DxbcProgramType::VertexShader>(
|
|
|
|
m_state.vs.shaderResources,
|
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSSetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetSamplers<DxbcProgramType::VertexShader>(
|
|
|
|
m_state.vs.samplers,
|
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSGetShader(
|
|
|
|
ID3D11VertexShader** ppVertexShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppVertexShader)
|
|
|
|
*ppVertexShader = m_state.vs.shader.ref();
|
|
|
|
|
|
|
|
if (pNumClassInstances)
|
|
|
|
*pNumClassInstances = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSGetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.vs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSGetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers,
|
|
|
|
UINT* pFirstConstant,
|
|
|
|
UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.vs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSGetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetShaderResources(m_state.vs.shaderResources,
|
|
|
|
StartSlot, NumViews, ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::VSGetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetSamplers(m_state.vs.samplers,
|
|
|
|
StartSlot, NumSamplers, ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSSetShader(
|
|
|
|
ID3D11HullShader* pHullShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto shader = static_cast<D3D11HullShader*>(pHullShader);
|
|
|
|
|
|
|
|
if (NumClassInstances)
|
|
|
|
Logger::err("D3D11: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.hs.shader != shader) {
|
|
|
|
m_state.hs.shader = shader;
|
|
|
|
|
|
|
|
BindShader<DxbcProgramType::HullShader>(GetCommonShader(shader));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSSetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers<DxbcProgramType::HullShader>(
|
|
|
|
m_state.hs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSSetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers,
|
|
|
|
const UINT* pFirstConstant,
|
|
|
|
const UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers1<DxbcProgramType::HullShader>(
|
|
|
|
m_state.hs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSSetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetShaderResources<DxbcProgramType::HullShader>(
|
|
|
|
m_state.hs.shaderResources,
|
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSSetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetSamplers<DxbcProgramType::HullShader>(
|
|
|
|
m_state.hs.samplers,
|
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSGetShader(
|
|
|
|
ID3D11HullShader** ppHullShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppHullShader)
|
|
|
|
*ppHullShader = m_state.hs.shader.ref();
|
|
|
|
|
|
|
|
if (pNumClassInstances)
|
|
|
|
*pNumClassInstances = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSGetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.hs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSGetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers,
|
|
|
|
UINT* pFirstConstant,
|
|
|
|
UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.hs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSGetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetShaderResources(m_state.hs.shaderResources,
|
|
|
|
StartSlot, NumViews, ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::HSGetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetSamplers(m_state.hs.samplers,
|
|
|
|
StartSlot, NumSamplers, ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSSetShader(
|
|
|
|
ID3D11DomainShader* pDomainShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto shader = static_cast<D3D11DomainShader*>(pDomainShader);
|
|
|
|
|
|
|
|
if (NumClassInstances)
|
|
|
|
Logger::err("D3D11: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.ds.shader != shader) {
|
|
|
|
m_state.ds.shader = shader;
|
|
|
|
|
|
|
|
BindShader<DxbcProgramType::DomainShader>(GetCommonShader(shader));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSSetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers<DxbcProgramType::DomainShader>(
|
|
|
|
m_state.ds.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSSetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers,
|
|
|
|
const UINT* pFirstConstant,
|
|
|
|
const UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers1<DxbcProgramType::DomainShader>(
|
|
|
|
m_state.ds.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSSetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetShaderResources<DxbcProgramType::DomainShader>(
|
|
|
|
m_state.ds.shaderResources,
|
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSSetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetSamplers<DxbcProgramType::DomainShader>(
|
|
|
|
m_state.ds.samplers,
|
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSGetShader(
|
|
|
|
ID3D11DomainShader** ppDomainShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppDomainShader)
|
|
|
|
*ppDomainShader = m_state.ds.shader.ref();
|
|
|
|
|
|
|
|
if (pNumClassInstances)
|
|
|
|
*pNumClassInstances = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSGetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.ds.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSGetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers,
|
|
|
|
UINT* pFirstConstant,
|
|
|
|
UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.ds.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSGetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetShaderResources(m_state.ds.shaderResources,
|
|
|
|
StartSlot, NumViews, ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::DSGetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetSamplers(m_state.ds.samplers,
|
|
|
|
StartSlot, NumSamplers, ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSSetShader(
|
|
|
|
ID3D11GeometryShader* pShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto shader = static_cast<D3D11GeometryShader*>(pShader);
|
|
|
|
|
|
|
|
if (NumClassInstances)
|
|
|
|
Logger::err("D3D11: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.gs.shader != shader) {
|
|
|
|
m_state.gs.shader = shader;
|
|
|
|
|
|
|
|
BindShader<DxbcProgramType::GeometryShader>(GetCommonShader(shader));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSSetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers<DxbcProgramType::GeometryShader>(
|
|
|
|
m_state.gs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSSetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers,
|
|
|
|
const UINT* pFirstConstant,
|
|
|
|
const UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers1<DxbcProgramType::GeometryShader>(
|
|
|
|
m_state.gs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSSetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetShaderResources<DxbcProgramType::GeometryShader>(
|
|
|
|
m_state.gs.shaderResources,
|
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSSetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetSamplers<DxbcProgramType::GeometryShader>(
|
|
|
|
m_state.gs.samplers,
|
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSGetShader(
|
|
|
|
ID3D11GeometryShader** ppGeometryShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppGeometryShader)
|
|
|
|
*ppGeometryShader = m_state.gs.shader.ref();
|
|
|
|
|
|
|
|
if (pNumClassInstances)
|
|
|
|
*pNumClassInstances = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSGetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.gs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSGetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers,
|
|
|
|
UINT* pFirstConstant,
|
|
|
|
UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.gs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSGetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetShaderResources(m_state.gs.shaderResources,
|
|
|
|
StartSlot, NumViews, ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::GSGetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetSamplers(m_state.gs.samplers,
|
|
|
|
StartSlot, NumSamplers, ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSSetShader(
|
|
|
|
ID3D11PixelShader* pPixelShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto shader = static_cast<D3D11PixelShader*>(pPixelShader);
|
|
|
|
|
|
|
|
if (NumClassInstances)
|
|
|
|
Logger::err("D3D11: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.ps.shader != shader) {
|
|
|
|
m_state.ps.shader = shader;
|
|
|
|
|
|
|
|
BindShader<DxbcProgramType::PixelShader>(GetCommonShader(shader));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSSetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers<DxbcProgramType::PixelShader>(
|
|
|
|
m_state.ps.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSSetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers,
|
|
|
|
const UINT* pFirstConstant,
|
|
|
|
const UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers1<DxbcProgramType::PixelShader>(
|
|
|
|
m_state.ps.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSSetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetShaderResources<DxbcProgramType::PixelShader>(
|
|
|
|
m_state.ps.shaderResources,
|
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSSetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetSamplers<DxbcProgramType::PixelShader>(
|
|
|
|
m_state.ps.samplers,
|
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSGetShader(
|
|
|
|
ID3D11PixelShader** ppPixelShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppPixelShader)
|
|
|
|
*ppPixelShader = m_state.ps.shader.ref();
|
|
|
|
|
|
|
|
if (pNumClassInstances)
|
|
|
|
*pNumClassInstances = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSGetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.ps.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSGetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers,
|
|
|
|
UINT* pFirstConstant,
|
|
|
|
UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.ps.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSGetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetShaderResources(m_state.ps.shaderResources,
|
|
|
|
StartSlot, NumViews, ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::PSGetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetSamplers(m_state.ps.samplers,
|
|
|
|
StartSlot, NumSamplers, ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSSetShader(
|
|
|
|
ID3D11ComputeShader* pComputeShader,
|
|
|
|
ID3D11ClassInstance* const* ppClassInstances,
|
|
|
|
UINT NumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto shader = static_cast<D3D11ComputeShader*>(pComputeShader);
|
|
|
|
|
|
|
|
if (NumClassInstances)
|
|
|
|
Logger::err("D3D11: Class instances not supported");
|
|
|
|
|
|
|
|
if (m_state.cs.shader != shader) {
|
|
|
|
m_state.cs.shader = shader;
|
|
|
|
|
|
|
|
BindShader<DxbcProgramType::ComputeShader>(GetCommonShader(shader));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSSetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers<DxbcProgramType::ComputeShader>(
|
|
|
|
m_state.cs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSSetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers,
|
|
|
|
const UINT* pFirstConstant,
|
|
|
|
const UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetConstantBuffers1<DxbcProgramType::ComputeShader>(
|
|
|
|
m_state.cs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSSetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView* const* ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetShaderResources<DxbcProgramType::ComputeShader>(
|
|
|
|
m_state.cs.shaderResources,
|
|
|
|
StartSlot, NumViews,
|
|
|
|
ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSSetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
SetSamplers<DxbcProgramType::ComputeShader>(
|
|
|
|
m_state.cs.samplers,
|
|
|
|
StartSlot, NumSamplers,
|
|
|
|
ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:21:02 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSSetUnorderedAccessViews(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
|
|
|
const UINT* pUAVInitialCounts) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (TestRtvUavHazards(0, nullptr, NumUAVs, ppUnorderedAccessViews))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Unbind previously bound conflicting UAVs
|
|
|
|
uint32_t uavSlotId = computeUavBinding (DxbcProgramType::ComputeShader, 0);
|
|
|
|
uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::ComputeShader, 0);
|
|
|
|
|
|
|
|
int32_t uavId = m_state.cs.uavMask.findNext(0);
|
|
|
|
|
|
|
|
while (uavId >= 0) {
|
|
|
|
if (uint32_t(uavId) < StartSlot || uint32_t(uavId) >= StartSlot + NumUAVs) {
|
|
|
|
for (uint32_t i = 0; i < NumUAVs; i++) {
|
|
|
|
auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]);
|
|
|
|
|
|
|
|
if (CheckViewOverlap(uav, m_state.cs.unorderedAccessViews[uavId].ptr())) {
|
|
|
|
m_state.cs.unorderedAccessViews[uavId] = nullptr;
|
|
|
|
m_state.cs.uavMask.clr(uavId);
|
|
|
|
|
|
|
|
BindUnorderedAccessView<DxbcProgramType::ComputeShader>(
|
|
|
|
uavSlotId + uavId, nullptr,
|
|
|
|
ctrSlotId + uavId, ~0u);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uavId = m_state.cs.uavMask.findNext(uavId + 1);
|
|
|
|
} else {
|
|
|
|
uavId = m_state.cs.uavMask.findNext(StartSlot + NumUAVs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Actually bind the given UAVs
|
|
|
|
for (uint32_t i = 0; i < NumUAVs; i++) {
|
|
|
|
auto uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i]);
|
|
|
|
auto ctr = pUAVInitialCounts ? pUAVInitialCounts[i] : ~0u;
|
|
|
|
|
|
|
|
if (m_state.cs.unorderedAccessViews[StartSlot + i] != uav || ctr != ~0u) {
|
|
|
|
m_state.cs.unorderedAccessViews[StartSlot + i] = uav;
|
|
|
|
m_state.cs.uavMask.set(StartSlot + i, uav != nullptr);
|
|
|
|
|
|
|
|
BindUnorderedAccessView<DxbcProgramType::ComputeShader>(
|
|
|
|
uavSlotId + StartSlot + i, uav,
|
|
|
|
ctrSlotId + StartSlot + i, ctr);
|
|
|
|
|
|
|
|
ResolveCsSrvHazards(uav);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:13:41 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSGetShader(
|
|
|
|
ID3D11ComputeShader** ppComputeShader,
|
|
|
|
ID3D11ClassInstance** ppClassInstances,
|
|
|
|
UINT* pNumClassInstances) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppComputeShader)
|
|
|
|
*ppComputeShader = m_state.cs.shader.ref();
|
|
|
|
|
|
|
|
if (pNumClassInstances)
|
|
|
|
*pNumClassInstances = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSGetConstantBuffers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.cs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSGetConstantBuffers1(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers,
|
|
|
|
UINT* pFirstConstant,
|
|
|
|
UINT* pNumConstants) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetConstantBuffers(
|
|
|
|
m_state.cs.constantBuffers,
|
|
|
|
StartSlot, NumBuffers,
|
|
|
|
ppConstantBuffers,
|
|
|
|
pFirstConstant,
|
|
|
|
pNumConstants);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSGetShaderResources(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetShaderResources(m_state.cs.shaderResources,
|
|
|
|
StartSlot, NumViews, ppShaderResourceViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSGetSamplers(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
GetSamplers(m_state.cs.samplers,
|
|
|
|
StartSlot, NumSamplers, ppSamplers);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:21:02 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::CSGetUnorderedAccessViews(
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView** ppUnorderedAccessViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumUAVs; i++) {
|
|
|
|
ppUnorderedAccessViews[i] = StartSlot + i < m_state.cs.unorderedAccessViews.size()
|
|
|
|
? m_state.cs.unorderedAccessViews[StartSlot + i].ref()
|
|
|
|
: nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 18:07:03 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::OMSetRenderTargets(
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView* pDepthStencilView) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if constexpr (!IsDeferred)
|
|
|
|
GetTypedContext()->FlushImplicit(true);
|
|
|
|
|
|
|
|
SetRenderTargetsAndUnorderedAccessViews(
|
|
|
|
NumViews, ppRenderTargetViews, pDepthStencilView,
|
|
|
|
NumViews, 0, nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::OMSetRenderTargetsAndUnorderedAccessViews(
|
|
|
|
UINT NumRTVs,
|
|
|
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView* pDepthStencilView,
|
|
|
|
UINT UAVStartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
|
|
|
const UINT* pUAVInitialCounts) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if constexpr (!IsDeferred)
|
|
|
|
GetTypedContext()->FlushImplicit(true);
|
|
|
|
|
|
|
|
SetRenderTargetsAndUnorderedAccessViews(
|
|
|
|
NumRTVs, ppRenderTargetViews, pDepthStencilView,
|
|
|
|
UAVStartSlot, NumUAVs, ppUnorderedAccessViews, pUAVInitialCounts);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::OMSetBlendState(
|
|
|
|
ID3D11BlendState* pBlendState,
|
|
|
|
const FLOAT BlendFactor[4],
|
|
|
|
UINT SampleMask) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto blendState = static_cast<D3D11BlendState*>(pBlendState);
|
|
|
|
|
|
|
|
if (m_state.om.cbState != blendState
|
|
|
|
|| m_state.om.sampleMask != SampleMask) {
|
|
|
|
m_state.om.cbState = blendState;
|
|
|
|
m_state.om.sampleMask = SampleMask;
|
|
|
|
|
|
|
|
ApplyBlendState();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (BlendFactor != nullptr) {
|
|
|
|
for (uint32_t i = 0; i < 4; i++)
|
|
|
|
m_state.om.blendFactor[i] = BlendFactor[i];
|
|
|
|
|
|
|
|
ApplyBlendFactor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::OMSetDepthStencilState(
|
|
|
|
ID3D11DepthStencilState* pDepthStencilState,
|
|
|
|
UINT StencilRef) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto depthStencilState = static_cast<D3D11DepthStencilState*>(pDepthStencilState);
|
|
|
|
|
|
|
|
if (m_state.om.dsState != depthStencilState) {
|
|
|
|
m_state.om.dsState = depthStencilState;
|
|
|
|
ApplyDepthStencilState();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_state.om.stencilRef != StencilRef) {
|
|
|
|
m_state.om.stencilRef = StencilRef;
|
|
|
|
ApplyStencilRef();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::OMGetRenderTargets(
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11RenderTargetView** ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView** ppDepthStencilView) {
|
|
|
|
OMGetRenderTargetsAndUnorderedAccessViews(
|
|
|
|
NumViews, ppRenderTargetViews, ppDepthStencilView,
|
|
|
|
NumViews, 0, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::OMGetRenderTargetsAndUnorderedAccessViews(
|
|
|
|
UINT NumRTVs,
|
|
|
|
ID3D11RenderTargetView** ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView** ppDepthStencilView,
|
|
|
|
UINT UAVStartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView** ppUnorderedAccessViews) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppRenderTargetViews) {
|
|
|
|
for (UINT i = 0; i < NumRTVs; i++) {
|
|
|
|
ppRenderTargetViews[i] = i < m_state.om.renderTargetViews.size()
|
|
|
|
? m_state.om.renderTargetViews[i].ref()
|
|
|
|
: nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ppDepthStencilView)
|
|
|
|
*ppDepthStencilView = m_state.om.depthStencilView.ref();
|
|
|
|
|
|
|
|
if (ppUnorderedAccessViews) {
|
|
|
|
for (UINT i = 0; i < NumUAVs; i++) {
|
|
|
|
ppUnorderedAccessViews[i] = UAVStartSlot + i < m_state.ps.unorderedAccessViews.size()
|
|
|
|
? m_state.ps.unorderedAccessViews[UAVStartSlot + i].ref()
|
|
|
|
: nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::OMGetBlendState(
|
|
|
|
ID3D11BlendState** ppBlendState,
|
|
|
|
FLOAT BlendFactor[4],
|
|
|
|
UINT* pSampleMask) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppBlendState)
|
|
|
|
*ppBlendState = ref(m_state.om.cbState);
|
|
|
|
|
|
|
|
if (BlendFactor)
|
|
|
|
std::memcpy(BlendFactor, m_state.om.blendFactor, sizeof(FLOAT) * 4);
|
|
|
|
|
|
|
|
if (pSampleMask)
|
|
|
|
*pSampleMask = m_state.om.sampleMask;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::OMGetDepthStencilState(
|
|
|
|
ID3D11DepthStencilState** ppDepthStencilState,
|
|
|
|
UINT* pStencilRef) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppDepthStencilState)
|
|
|
|
*ppDepthStencilState = ref(m_state.om.dsState);
|
|
|
|
|
|
|
|
if (pStencilRef)
|
|
|
|
*pStencilRef = m_state.om.stencilRef;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:30:11 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::RSSetState(ID3D11RasterizerState* pRasterizerState) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
auto currRasterizerState = m_state.rs.state;
|
|
|
|
auto nextRasterizerState = static_cast<D3D11RasterizerState*>(pRasterizerState);
|
|
|
|
|
|
|
|
if (m_state.rs.state != nextRasterizerState) {
|
|
|
|
m_state.rs.state = nextRasterizerState;
|
|
|
|
ApplyRasterizerState();
|
|
|
|
|
|
|
|
// If necessary, update the rasterizer sample count push constant
|
|
|
|
uint32_t currSampleCount = currRasterizerState != nullptr ? currRasterizerState->Desc()->ForcedSampleCount : 0;
|
|
|
|
uint32_t nextSampleCount = nextRasterizerState != nullptr ? nextRasterizerState->Desc()->ForcedSampleCount : 0;
|
|
|
|
|
|
|
|
if (currSampleCount != nextSampleCount)
|
|
|
|
ApplyRasterizerSampleCount();
|
|
|
|
|
|
|
|
// In D3D11, the rasterizer state defines whether the scissor test is
|
|
|
|
// enabled, so if that changes, we need to update scissor rects as well.
|
|
|
|
bool currScissorEnable = currRasterizerState != nullptr ? currRasterizerState->Desc()->ScissorEnable : false;
|
|
|
|
bool nextScissorEnable = nextRasterizerState != nullptr ? nextRasterizerState->Desc()->ScissorEnable : false;
|
|
|
|
|
|
|
|
if (currScissorEnable != nextScissorEnable)
|
|
|
|
ApplyViewportState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::RSSetViewports(
|
|
|
|
UINT NumViewports,
|
|
|
|
const D3D11_VIEWPORT* pViewports) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (unlikely(NumViewports > m_state.rs.viewports.size()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
bool dirty = m_state.rs.numViewports != NumViewports;
|
|
|
|
m_state.rs.numViewports = NumViewports;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumViewports; i++) {
|
|
|
|
const D3D11_VIEWPORT& vp = m_state.rs.viewports[i];
|
|
|
|
|
|
|
|
dirty |= vp.TopLeftX != pViewports[i].TopLeftX
|
|
|
|
|| vp.TopLeftY != pViewports[i].TopLeftY
|
|
|
|
|| vp.Width != pViewports[i].Width
|
|
|
|
|| vp.Height != pViewports[i].Height
|
|
|
|
|| vp.MinDepth != pViewports[i].MinDepth
|
|
|
|
|| vp.MaxDepth != pViewports[i].MaxDepth;
|
|
|
|
|
|
|
|
m_state.rs.viewports[i] = pViewports[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dirty)
|
|
|
|
ApplyViewportState();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::RSSetScissorRects(
|
|
|
|
UINT NumRects,
|
|
|
|
const D3D11_RECT* pRects) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (unlikely(NumRects > m_state.rs.scissors.size()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
bool dirty = m_state.rs.numScissors != NumRects;
|
|
|
|
m_state.rs.numScissors = NumRects;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumRects; i++) {
|
|
|
|
if (pRects[i].bottom >= pRects[i].top
|
|
|
|
&& pRects[i].right >= pRects[i].left) {
|
|
|
|
const D3D11_RECT& sr = m_state.rs.scissors[i];
|
|
|
|
|
|
|
|
dirty |= sr.top != pRects[i].top
|
|
|
|
|| sr.left != pRects[i].left
|
|
|
|
|| sr.bottom != pRects[i].bottom
|
|
|
|
|| sr.right != pRects[i].right;
|
|
|
|
|
|
|
|
m_state.rs.scissors[i] = pRects[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_state.rs.state != nullptr && dirty) {
|
|
|
|
D3D11_RASTERIZER_DESC rsDesc;
|
|
|
|
m_state.rs.state->GetDesc(&rsDesc);
|
|
|
|
|
|
|
|
if (rsDesc.ScissorEnable)
|
|
|
|
ApplyViewportState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::RSGetState(ID3D11RasterizerState** ppRasterizerState) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (ppRasterizerState)
|
|
|
|
*ppRasterizerState = ref(m_state.rs.state);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::RSGetViewports(
|
|
|
|
UINT* pNumViewports,
|
|
|
|
D3D11_VIEWPORT* pViewports) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
uint32_t numWritten = m_state.rs.numViewports;
|
|
|
|
|
|
|
|
if (pViewports) {
|
|
|
|
numWritten = std::min(numWritten, *pNumViewports);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < *pNumViewports; i++) {
|
|
|
|
if (i < m_state.rs.numViewports) {
|
|
|
|
pViewports[i] = m_state.rs.viewports[i];
|
|
|
|
} else {
|
|
|
|
pViewports[i].TopLeftX = 0.0f;
|
|
|
|
pViewports[i].TopLeftY = 0.0f;
|
|
|
|
pViewports[i].Width = 0.0f;
|
|
|
|
pViewports[i].Height = 0.0f;
|
|
|
|
pViewports[i].MinDepth = 0.0f;
|
|
|
|
pViewports[i].MaxDepth = 0.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*pNumViewports = numWritten;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::RSGetScissorRects(
|
|
|
|
UINT* pNumRects,
|
|
|
|
D3D11_RECT* pRects) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
uint32_t numWritten = m_state.rs.numScissors;
|
|
|
|
|
|
|
|
if (pRects) {
|
|
|
|
numWritten = std::min(numWritten, *pNumRects);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < *pNumRects; i++) {
|
|
|
|
if (i < m_state.rs.numScissors) {
|
|
|
|
pRects[i] = m_state.rs.scissors[i];
|
|
|
|
} else {
|
|
|
|
pRects[i].left = 0;
|
|
|
|
pRects[i].top = 0;
|
|
|
|
pRects[i].right = 0;
|
|
|
|
pRects[i].bottom = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*pNumRects = m_state.rs.numScissors;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 17:13:32 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
BOOL STDMETHODCALLTYPE D3D11CommonContext<ContextType>::IsAnnotationEnabled() {
|
|
|
|
return m_annotation.GetStatus();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 17:55:39 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::BindShader(
|
|
|
|
const D3D11CommonShader* pShaderModule) {
|
|
|
|
// Bind the shader and the ICB at once
|
|
|
|
EmitCs([
|
|
|
|
cSlice = pShaderModule != nullptr
|
|
|
|
&& pShaderModule->GetIcb() != nullptr
|
|
|
|
? DxvkBufferSlice(pShaderModule->GetIcb())
|
|
|
|
: DxvkBufferSlice(),
|
|
|
|
cShader = pShaderModule != nullptr
|
|
|
|
? pShaderModule->GetShader()
|
|
|
|
: nullptr
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage);
|
|
|
|
|
|
|
|
uint32_t slotId = computeConstantBufferBinding(ShaderStage,
|
|
|
|
D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
|
|
|
|
|
|
|
|
ctx->bindShader(stage,
|
|
|
|
Forwarder::move(cShader));
|
|
|
|
ctx->bindResourceBuffer(stage, slotId,
|
|
|
|
Forwarder::move(cSlice));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::BindFramebuffer() {
|
|
|
|
DxvkRenderTargets attachments;
|
|
|
|
uint32_t sampleCount = 0;
|
|
|
|
|
|
|
|
// D3D11 doesn't have the concept of a framebuffer object,
|
|
|
|
// so we'll just create a new one every time the render
|
|
|
|
// target bindings are updated. Set up the attachments.
|
|
|
|
for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
|
|
|
if (m_state.om.renderTargetViews[i] != nullptr) {
|
|
|
|
attachments.color[i] = {
|
|
|
|
m_state.om.renderTargetViews[i]->GetImageView(),
|
|
|
|
m_state.om.renderTargetViews[i]->GetRenderLayout() };
|
|
|
|
sampleCount = m_state.om.renderTargetViews[i]->GetSampleCount();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_state.om.depthStencilView != nullptr) {
|
|
|
|
attachments.depth = {
|
|
|
|
m_state.om.depthStencilView->GetImageView(),
|
|
|
|
m_state.om.depthStencilView->GetRenderLayout() };
|
|
|
|
sampleCount = m_state.om.depthStencilView->GetSampleCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create and bind the framebuffer object to the context
|
|
|
|
EmitCs([
|
|
|
|
cAttachments = std::move(attachments)
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
ctx->bindRenderTargets(Forwarder::move(cAttachments));
|
|
|
|
});
|
|
|
|
|
|
|
|
// If necessary, update push constant for the sample count
|
|
|
|
if (m_state.om.sampleCount != sampleCount) {
|
|
|
|
m_state.om.sampleCount = sampleCount;
|
|
|
|
ApplyRasterizerSampleCount();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::BindDrawBuffers(
|
|
|
|
D3D11Buffer* pBufferForArgs,
|
|
|
|
D3D11Buffer* pBufferForCount) {
|
|
|
|
EmitCs([
|
|
|
|
cArgBuffer = pBufferForArgs ? pBufferForArgs->GetBufferSlice() : DxvkBufferSlice(),
|
|
|
|
cCntBuffer = pBufferForCount ? pBufferForCount->GetBufferSlice() : DxvkBufferSlice()
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
ctx->bindDrawBuffers(
|
|
|
|
Forwarder::move(cArgBuffer),
|
|
|
|
Forwarder::move(cCntBuffer));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::BindVertexBuffer(
|
|
|
|
UINT Slot,
|
|
|
|
D3D11Buffer* pBuffer,
|
|
|
|
UINT Offset,
|
|
|
|
UINT Stride) {
|
|
|
|
if (likely(pBuffer != nullptr)) {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cBufferSlice = pBuffer->GetBufferSlice(Offset),
|
|
|
|
cStride = Stride
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
ctx->bindVertexBuffer(cSlotId,
|
|
|
|
Forwarder::move(cBufferSlice),
|
|
|
|
cStride);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->bindVertexBuffer(cSlotId, DxvkBufferSlice(), 0);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::BindIndexBuffer(
|
|
|
|
D3D11Buffer* pBuffer,
|
|
|
|
UINT Offset,
|
|
|
|
DXGI_FORMAT Format) {
|
|
|
|
VkIndexType indexType = Format == DXGI_FORMAT_R16_UINT
|
|
|
|
? VK_INDEX_TYPE_UINT16
|
|
|
|
: VK_INDEX_TYPE_UINT32;
|
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice(Offset) : DxvkBufferSlice(),
|
|
|
|
cIndexType = indexType
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
ctx->bindIndexBuffer(
|
|
|
|
Forwarder::move(cBufferSlice),
|
|
|
|
cIndexType);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::BindXfbBuffer(
|
|
|
|
UINT Slot,
|
|
|
|
D3D11Buffer* pBuffer,
|
|
|
|
UINT Offset) {
|
|
|
|
DxvkBufferSlice bufferSlice;
|
|
|
|
DxvkBufferSlice counterSlice;
|
|
|
|
|
|
|
|
if (pBuffer != nullptr) {
|
|
|
|
bufferSlice = pBuffer->GetBufferSlice();
|
|
|
|
counterSlice = pBuffer->GetSOCounter();
|
|
|
|
}
|
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cOffset = Offset,
|
|
|
|
cBufferSlice = bufferSlice,
|
|
|
|
cCounterSlice = counterSlice
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
if (cCounterSlice.defined() && cOffset != ~0u) {
|
|
|
|
ctx->updateBuffer(
|
|
|
|
cCounterSlice.buffer(),
|
|
|
|
cCounterSlice.offset(),
|
|
|
|
sizeof(cOffset),
|
|
|
|
&cOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->bindXfbBuffer(cSlotId,
|
|
|
|
Forwarder::move(cBufferSlice),
|
|
|
|
Forwarder::move(cCounterSlice));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::BindConstantBuffer(
|
|
|
|
UINT Slot,
|
|
|
|
D3D11Buffer* pBuffer,
|
|
|
|
UINT Offset,
|
|
|
|
UINT Length) {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cBufferSlice = pBuffer ? pBuffer->GetBufferSlice(16 * Offset, 16 * Length) : DxvkBufferSlice()
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage);
|
|
|
|
ctx->bindResourceBuffer(stage, cSlotId,
|
|
|
|
Forwarder::move(cBufferSlice));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::BindConstantBufferRange(
|
|
|
|
UINT Slot,
|
|
|
|
UINT Offset,
|
|
|
|
UINT Length) {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cOffset = 16 * Offset,
|
|
|
|
cLength = 16 * Length
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage);
|
|
|
|
ctx->bindResourceBufferRange(stage, cSlotId, cOffset, cLength);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::BindSampler(
|
|
|
|
UINT Slot,
|
|
|
|
D3D11SamplerState* pSampler) {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cSampler = pSampler != nullptr ? pSampler->GetDXVKSampler() : nullptr
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage);
|
|
|
|
ctx->bindResourceSampler(stage, cSlotId,
|
|
|
|
Forwarder::move(cSampler));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::BindShaderResource(
|
|
|
|
UINT Slot,
|
|
|
|
D3D11ShaderResourceView* pResource) {
|
|
|
|
EmitCs([
|
|
|
|
cSlotId = Slot,
|
|
|
|
cImageView = pResource != nullptr ? pResource->GetImageView() : nullptr,
|
|
|
|
cBufferView = pResource != nullptr ? pResource->GetBufferView() : nullptr
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage);
|
|
|
|
ctx->bindResourceView(stage, cSlotId,
|
|
|
|
Forwarder::move(cImageView),
|
|
|
|
Forwarder::move(cBufferView));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::BindUnorderedAccessView(
|
|
|
|
UINT UavSlot,
|
|
|
|
D3D11UnorderedAccessView* pUav,
|
|
|
|
UINT CtrSlot,
|
|
|
|
UINT Counter) {
|
|
|
|
EmitCs([
|
|
|
|
cUavSlotId = UavSlot,
|
|
|
|
cCtrSlotId = CtrSlot,
|
|
|
|
cImageView = pUav != nullptr ? pUav->GetImageView() : nullptr,
|
|
|
|
cBufferView = pUav != nullptr ? pUav->GetBufferView() : nullptr,
|
|
|
|
cCounterSlice = pUav != nullptr ? pUav->GetCounterSlice() : DxvkBufferSlice(),
|
|
|
|
cCounterValue = Counter
|
|
|
|
] (DxvkContext* ctx) mutable {
|
|
|
|
VkShaderStageFlags stages = ShaderStage == DxbcProgramType::PixelShader
|
|
|
|
? VK_SHADER_STAGE_ALL_GRAPHICS
|
|
|
|
: VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
|
|
|
|
|
if (cCounterSlice.defined() && cCounterValue != ~0u) {
|
|
|
|
ctx->updateBuffer(
|
|
|
|
cCounterSlice.buffer(),
|
|
|
|
cCounterSlice.offset(),
|
|
|
|
sizeof(uint32_t),
|
|
|
|
&cCounterValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->bindResourceView(stages, cUavSlotId,
|
|
|
|
Forwarder::move(cImageView),
|
|
|
|
Forwarder::move(cBufferView));
|
|
|
|
ctx->bindResourceBuffer(stages, cCtrSlotId,
|
|
|
|
Forwarder::move(cCounterSlice));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::GetConstantBuffers(
|
|
|
|
const D3D11ConstantBufferBindings& Bindings,
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer** ppConstantBuffers,
|
|
|
|
UINT* pFirstConstant,
|
|
|
|
UINT* pNumConstants) {
|
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++) {
|
|
|
|
const bool inRange = StartSlot + i < Bindings.size();
|
|
|
|
|
|
|
|
if (ppConstantBuffers) {
|
|
|
|
ppConstantBuffers[i] = inRange
|
|
|
|
? Bindings[StartSlot + i].buffer.ref()
|
|
|
|
: nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pFirstConstant) {
|
|
|
|
pFirstConstant[i] = inRange
|
|
|
|
? Bindings[StartSlot + i].constantOffset
|
|
|
|
: 0u;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pNumConstants) {
|
|
|
|
pNumConstants[i] = inRange
|
|
|
|
? Bindings[StartSlot + i].constantCount
|
|
|
|
: 0u;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::GetShaderResources(
|
|
|
|
const D3D11ShaderResourceBindings& Bindings,
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11ShaderResourceView** ppShaderResourceViews) {
|
|
|
|
for (uint32_t i = 0; i < NumViews; i++) {
|
|
|
|
ppShaderResourceViews[i] = StartSlot + i < Bindings.views.size()
|
|
|
|
? Bindings.views[StartSlot + i].ref()
|
|
|
|
: nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::GetSamplers(
|
|
|
|
const D3D11SamplerBindings& Bindings,
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState** ppSamplers) {
|
|
|
|
for (uint32_t i = 0; i < NumSamplers; i++) {
|
|
|
|
ppSamplers[i] = StartSlot + i < Bindings.size()
|
|
|
|
? ref(Bindings[StartSlot + i])
|
|
|
|
: nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:27:33 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::ResetState() {
|
|
|
|
EmitCs([] (DxvkContext* ctx) {
|
|
|
|
// Reset render targets
|
|
|
|
ctx->bindRenderTargets(DxvkRenderTargets());
|
|
|
|
|
|
|
|
// Reset vertex input state
|
|
|
|
ctx->setInputLayout(0, nullptr, 0, nullptr);
|
|
|
|
|
|
|
|
// Reset render states
|
|
|
|
DxvkInputAssemblyState iaState;
|
|
|
|
InitDefaultPrimitiveTopology(&iaState);
|
|
|
|
|
|
|
|
DxvkDepthStencilState dsState;
|
|
|
|
InitDefaultDepthStencilState(&dsState);
|
|
|
|
|
|
|
|
DxvkRasterizerState rsState;
|
|
|
|
InitDefaultRasterizerState(&rsState);
|
|
|
|
|
|
|
|
DxvkBlendMode cbState;
|
|
|
|
DxvkLogicOpState loState;
|
|
|
|
DxvkMultisampleState msState;
|
|
|
|
InitDefaultBlendState(&cbState, &loState, &msState, D3D11_DEFAULT_SAMPLE_MASK);
|
|
|
|
|
|
|
|
ctx->setInputAssemblyState(iaState);
|
|
|
|
ctx->setDepthStencilState(dsState);
|
|
|
|
ctx->setRasterizerState(rsState);
|
|
|
|
ctx->setLogicOpState(loState);
|
|
|
|
ctx->setMultisampleState(msState);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
|
|
|
ctx->setBlendMode(i, cbState);
|
|
|
|
|
|
|
|
// Reset dynamic states
|
|
|
|
ctx->setBlendConstants(DxvkBlendConstants { 1.0f, 1.0f, 1.0f, 1.0f });
|
|
|
|
ctx->setStencilReference(D3D11_DEFAULT_STENCIL_REFERENCE);
|
|
|
|
|
|
|
|
// Reset viewports
|
|
|
|
auto viewport = VkViewport();
|
|
|
|
auto scissor = VkRect2D();
|
|
|
|
|
|
|
|
ctx->setViewports(1, &viewport, &scissor);
|
|
|
|
|
|
|
|
// Unbind indirect draw buffer
|
|
|
|
ctx->bindDrawBuffers(DxvkBufferSlice(), DxvkBufferSlice());
|
|
|
|
|
|
|
|
// Unbind index and vertex buffers
|
|
|
|
ctx->bindIndexBuffer(DxvkBufferSlice(), VK_INDEX_TYPE_UINT32);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++)
|
|
|
|
ctx->bindVertexBuffer(i, DxvkBufferSlice(), 0);
|
|
|
|
|
|
|
|
// Unbind transform feedback buffers
|
|
|
|
for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++)
|
|
|
|
ctx->bindXfbBuffer(i, DxvkBufferSlice(), DxvkBufferSlice());
|
|
|
|
|
|
|
|
// Unbind per-shader stage resources
|
|
|
|
for (uint32_t i = 0; i < 6; i++) {
|
|
|
|
auto programType = DxbcProgramType(i);
|
|
|
|
auto stage = GetShaderStage(programType);
|
|
|
|
|
|
|
|
ctx->bindShader(stage, nullptr);
|
|
|
|
|
|
|
|
// Unbind constant buffers, including the shader's ICB
|
|
|
|
auto cbSlotId = computeConstantBufferBinding(programType, 0);
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; j++)
|
|
|
|
ctx->bindResourceBuffer(stage, cbSlotId + j, DxvkBufferSlice());
|
|
|
|
|
|
|
|
// Unbind shader resource views
|
|
|
|
auto srvSlotId = computeSrvBinding(programType, 0);
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; j++)
|
|
|
|
ctx->bindResourceView(stage, srvSlotId + j, nullptr, nullptr);
|
|
|
|
|
|
|
|
// Unbind texture samplers
|
|
|
|
auto samplerSlotId = computeSamplerBinding(programType, 0);
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; j++)
|
|
|
|
ctx->bindResourceSampler(stage, samplerSlotId + j, nullptr);
|
|
|
|
|
|
|
|
// Unbind UAVs for supported stages
|
|
|
|
if (programType == DxbcProgramType::PixelShader
|
|
|
|
|| programType == DxbcProgramType::ComputeShader) {
|
|
|
|
VkShaderStageFlags stages = programType == DxbcProgramType::PixelShader
|
|
|
|
? VK_SHADER_STAGE_ALL_GRAPHICS
|
|
|
|
: VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
|
|
|
|
|
auto uavSlotId = computeUavBinding(programType, 0);
|
|
|
|
auto ctrSlotId = computeUavCounterBinding(programType, 0);
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < D3D11_1_UAV_SLOT_COUNT; j++) {
|
|
|
|
ctx->bindResourceView (stages, uavSlotId, nullptr, nullptr);
|
|
|
|
ctx->bindResourceBuffer (stages, ctrSlotId, DxvkBufferSlice());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize push constants
|
|
|
|
DxbcPushConstants pc;
|
|
|
|
pc.rasterizerSampleCount = 1;
|
|
|
|
ctx->pushConstants(0, sizeof(pc), &pc);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 17:58:42 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage, typename T>
|
|
|
|
void D3D11CommonContext<ContextType>::ResolveSrvHazards(
|
|
|
|
T* pView,
|
|
|
|
D3D11ShaderResourceBindings& Bindings) {
|
|
|
|
uint32_t slotId = computeSrvBinding(ShaderStage, 0);
|
|
|
|
int32_t srvId = Bindings.hazardous.findNext(0);
|
|
|
|
|
|
|
|
while (srvId >= 0) {
|
|
|
|
auto srv = Bindings.views[srvId].ptr();
|
|
|
|
|
|
|
|
if (likely(srv && srv->TestHazards())) {
|
|
|
|
bool hazard = CheckViewOverlap(pView, srv);
|
|
|
|
|
|
|
|
if (unlikely(hazard)) {
|
|
|
|
Bindings.views[srvId] = nullptr;
|
|
|
|
Bindings.hazardous.clr(srvId);
|
|
|
|
|
|
|
|
BindShaderResource<ShaderStage>(slotId + srvId, nullptr);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Avoid further redundant iterations
|
|
|
|
Bindings.hazardous.clr(srvId);
|
|
|
|
}
|
|
|
|
|
|
|
|
srvId = Bindings.hazardous.findNext(srvId + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<typename T>
|
|
|
|
void D3D11CommonContext<ContextType>::ResolveCsSrvHazards(
|
|
|
|
T* pView) {
|
|
|
|
if (!pView) return;
|
|
|
|
ResolveSrvHazards<DxbcProgramType::ComputeShader> (pView, m_state.cs.shaderResources);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<typename T>
|
|
|
|
void D3D11CommonContext<ContextType>::ResolveOmSrvHazards(
|
|
|
|
T* pView) {
|
|
|
|
if (!pView) return;
|
|
|
|
ResolveSrvHazards<DxbcProgramType::VertexShader> (pView, m_state.vs.shaderResources);
|
|
|
|
ResolveSrvHazards<DxbcProgramType::HullShader> (pView, m_state.hs.shaderResources);
|
|
|
|
ResolveSrvHazards<DxbcProgramType::DomainShader> (pView, m_state.ds.shaderResources);
|
|
|
|
ResolveSrvHazards<DxbcProgramType::GeometryShader> (pView, m_state.gs.shaderResources);
|
|
|
|
ResolveSrvHazards<DxbcProgramType::PixelShader> (pView, m_state.ps.shaderResources);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
bool D3D11CommonContext<ContextType>::ResolveOmRtvHazards(
|
|
|
|
D3D11UnorderedAccessView* pView) {
|
|
|
|
if (!pView || !pView->HasBindFlag(D3D11_BIND_RENDER_TARGET))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
bool hazard = false;
|
|
|
|
|
|
|
|
if (CheckViewOverlap(pView, m_state.om.depthStencilView.ptr())) {
|
|
|
|
m_state.om.depthStencilView = nullptr;
|
|
|
|
hazard = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < m_state.om.maxRtv; i++) {
|
|
|
|
if (CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr())) {
|
|
|
|
m_state.om.renderTargetViews[i] = nullptr;
|
|
|
|
hazard = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return hazard;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::ResolveOmUavHazards(
|
|
|
|
D3D11RenderTargetView* pView) {
|
|
|
|
if (!pView || !pView->HasBindFlag(D3D11_BIND_UNORDERED_ACCESS))
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint32_t uavSlotId = computeUavBinding (DxbcProgramType::PixelShader, 0);
|
|
|
|
uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < m_state.om.maxUav; i++) {
|
|
|
|
if (CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr())) {
|
|
|
|
m_state.ps.unorderedAccessViews[i] = nullptr;
|
|
|
|
|
|
|
|
BindUnorderedAccessView<DxbcProgramType::PixelShader>(
|
|
|
|
uavSlotId + i, nullptr,
|
|
|
|
ctrSlotId + i, ~0u);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:49:15 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::SetConstantBuffers(
|
|
|
|
D3D11ConstantBufferBindings& Bindings,
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers) {
|
|
|
|
uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++) {
|
|
|
|
auto newBuffer = static_cast<D3D11Buffer*>(ppConstantBuffers[i]);
|
|
|
|
|
|
|
|
UINT constantCount = 0;
|
|
|
|
|
|
|
|
if (likely(newBuffer != nullptr))
|
|
|
|
constantCount = std::min(newBuffer->Desc()->ByteWidth / 16, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT));
|
|
|
|
|
|
|
|
if (Bindings[StartSlot + i].buffer != newBuffer
|
|
|
|
|| Bindings[StartSlot + i].constantBound != constantCount) {
|
|
|
|
Bindings[StartSlot + i].buffer = newBuffer;
|
|
|
|
Bindings[StartSlot + i].constantOffset = 0;
|
|
|
|
Bindings[StartSlot + i].constantCount = constantCount;
|
|
|
|
Bindings[StartSlot + i].constantBound = constantCount;
|
|
|
|
|
|
|
|
BindConstantBuffer<ShaderStage>(slotId + i, newBuffer, 0, constantCount);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::SetConstantBuffers1(
|
|
|
|
D3D11ConstantBufferBindings& Bindings,
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumBuffers,
|
|
|
|
ID3D11Buffer* const* ppConstantBuffers,
|
|
|
|
const UINT* pFirstConstant,
|
|
|
|
const UINT* pNumConstants) {
|
|
|
|
uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumBuffers; i++) {
|
|
|
|
auto newBuffer = static_cast<D3D11Buffer*>(ppConstantBuffers[i]);
|
|
|
|
|
|
|
|
UINT constantOffset;
|
|
|
|
UINT constantCount;
|
|
|
|
UINT constantBound;
|
|
|
|
|
|
|
|
if (likely(newBuffer != nullptr)) {
|
|
|
|
UINT bufferConstantsCount = newBuffer->Desc()->ByteWidth / 16;
|
|
|
|
constantBound = std::min(bufferConstantsCount, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT));
|
|
|
|
|
|
|
|
if (likely(pFirstConstant && pNumConstants)) {
|
|
|
|
constantOffset = pFirstConstant[i];
|
|
|
|
constantCount = pNumConstants [i];
|
|
|
|
|
|
|
|
if (unlikely(constantCount > D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
constantBound = (constantOffset + constantCount > bufferConstantsCount)
|
|
|
|
? bufferConstantsCount - std::min(constantOffset, bufferConstantsCount)
|
|
|
|
: constantCount;
|
|
|
|
} else {
|
|
|
|
constantOffset = 0;
|
|
|
|
constantCount = constantBound;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
constantOffset = 0;
|
|
|
|
constantCount = 0;
|
|
|
|
constantBound = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do a full rebind if either the buffer changes, or if either the current or
|
|
|
|
// the previous number of bound constants were zero, since we're binding a null
|
|
|
|
// buffer to the backend in that case.
|
|
|
|
bool needsUpdate = Bindings[StartSlot + i].buffer != newBuffer;
|
|
|
|
|
|
|
|
if (!needsUpdate) {
|
|
|
|
needsUpdate |= !constantBound;
|
|
|
|
needsUpdate |= !Bindings[StartSlot + i].constantBound;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (needsUpdate) {
|
|
|
|
Bindings[StartSlot + i].buffer = newBuffer;
|
|
|
|
Bindings[StartSlot + i].constantOffset = constantOffset;
|
|
|
|
Bindings[StartSlot + i].constantCount = constantCount;
|
|
|
|
Bindings[StartSlot + i].constantBound = constantBound;
|
|
|
|
|
|
|
|
BindConstantBuffer<ShaderStage>(slotId + i, newBuffer, constantOffset, constantBound);
|
|
|
|
} else if (Bindings[StartSlot + i].constantOffset != constantOffset
|
|
|
|
|| Bindings[StartSlot + i].constantCount != constantCount) {
|
|
|
|
Bindings[StartSlot + i].constantOffset = constantOffset;
|
|
|
|
Bindings[StartSlot + i].constantCount = constantCount;
|
|
|
|
Bindings[StartSlot + i].constantBound = constantBound;
|
|
|
|
|
|
|
|
BindConstantBufferRange<ShaderStage>(slotId + i, constantOffset, constantBound);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 19:58:55 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::SetShaderResources(
|
|
|
|
D3D11ShaderResourceBindings& Bindings,
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumResources,
|
|
|
|
ID3D11ShaderResourceView* const* ppResources) {
|
|
|
|
uint32_t slotId = computeSrvBinding(ShaderStage, StartSlot);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumResources; i++) {
|
|
|
|
auto resView = static_cast<D3D11ShaderResourceView*>(ppResources[i]);
|
|
|
|
|
|
|
|
if (Bindings.views[StartSlot + i] != resView) {
|
|
|
|
if (unlikely(resView && resView->TestHazards())) {
|
|
|
|
if (TestSrvHazards<ShaderStage>(resView))
|
|
|
|
resView = nullptr;
|
|
|
|
|
|
|
|
// Only set if necessary, but don't reset it on every
|
|
|
|
// bind as this would be more expensive than a few
|
|
|
|
// redundant checks in OMSetRenderTargets and friends.
|
|
|
|
Bindings.hazardous.set(StartSlot + i, resView);
|
|
|
|
}
|
|
|
|
|
|
|
|
Bindings.views[StartSlot + i] = resView;
|
|
|
|
BindShaderResource<ShaderStage>(slotId + i, resView);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:02:23 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
void D3D11CommonContext<ContextType>::SetSamplers(
|
|
|
|
D3D11SamplerBindings& Bindings,
|
|
|
|
UINT StartSlot,
|
|
|
|
UINT NumSamplers,
|
|
|
|
ID3D11SamplerState* const* ppSamplers) {
|
|
|
|
uint32_t slotId = computeSamplerBinding(ShaderStage, StartSlot);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumSamplers; i++) {
|
|
|
|
auto sampler = static_cast<D3D11SamplerState*>(ppSamplers[i]);
|
|
|
|
|
|
|
|
if (Bindings[StartSlot + i] != sampler) {
|
|
|
|
Bindings[StartSlot + i] = sampler;
|
|
|
|
BindSampler<ShaderStage>(slotId + i, sampler);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 18:07:03 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::SetRenderTargetsAndUnorderedAccessViews(
|
|
|
|
UINT NumRTVs,
|
|
|
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView* pDepthStencilView,
|
|
|
|
UINT UAVStartSlot,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
|
|
|
|
const UINT* pUAVInitialCounts) {
|
|
|
|
if (TestRtvUavHazards(NumRTVs, ppRenderTargetViews, NumUAVs, ppUnorderedAccessViews))
|
|
|
|
return;
|
|
|
|
|
|
|
|
bool needsUpdate = false;
|
|
|
|
|
|
|
|
if (likely(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)) {
|
|
|
|
// Native D3D11 does not change the render targets if
|
|
|
|
// the parameters passed to this method are invalid.
|
|
|
|
if (!ValidateRenderTargets(NumRTVs, ppRenderTargetViews, pDepthStencilView))
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < m_state.om.renderTargetViews.size(); i++) {
|
|
|
|
auto rtv = i < NumRTVs
|
|
|
|
? static_cast<D3D11RenderTargetView*>(ppRenderTargetViews[i])
|
|
|
|
: nullptr;
|
|
|
|
|
|
|
|
if (m_state.om.renderTargetViews[i] != rtv) {
|
|
|
|
m_state.om.renderTargetViews[i] = rtv;
|
|
|
|
needsUpdate = true;
|
|
|
|
ResolveOmSrvHazards(rtv);
|
|
|
|
|
|
|
|
if (NumUAVs == D3D11_KEEP_UNORDERED_ACCESS_VIEWS)
|
|
|
|
ResolveOmUavHazards(rtv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto dsv = static_cast<D3D11DepthStencilView*>(pDepthStencilView);
|
|
|
|
|
|
|
|
if (m_state.om.depthStencilView != dsv) {
|
|
|
|
m_state.om.depthStencilView = dsv;
|
|
|
|
needsUpdate = true;
|
|
|
|
ResolveOmSrvHazards(dsv);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_state.om.maxRtv = NumRTVs;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unlikely(NumUAVs || m_state.om.maxUav)) {
|
|
|
|
uint32_t uavSlotId = computeUavBinding (DxbcProgramType::PixelShader, 0);
|
|
|
|
uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0);
|
|
|
|
|
|
|
|
if (likely(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS)) {
|
|
|
|
uint32_t newMaxUav = NumUAVs ? UAVStartSlot + NumUAVs : 0;
|
|
|
|
uint32_t oldMaxUav = std::exchange(m_state.om.maxUav, newMaxUav);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < std::max(oldMaxUav, newMaxUav); i++) {
|
|
|
|
D3D11UnorderedAccessView* uav = nullptr;
|
|
|
|
uint32_t ctr = ~0u;
|
|
|
|
|
|
|
|
if (i >= UAVStartSlot && i < UAVStartSlot + NumUAVs) {
|
|
|
|
uav = static_cast<D3D11UnorderedAccessView*>(ppUnorderedAccessViews[i - UAVStartSlot]);
|
|
|
|
ctr = pUAVInitialCounts ? pUAVInitialCounts[i - UAVStartSlot] : ~0u;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_state.ps.unorderedAccessViews[i] != uav || ctr != ~0u) {
|
|
|
|
m_state.ps.unorderedAccessViews[i] = uav;
|
|
|
|
|
|
|
|
BindUnorderedAccessView<DxbcProgramType::PixelShader>(
|
|
|
|
uavSlotId + i, uav,
|
|
|
|
ctrSlotId + i, ctr);
|
|
|
|
|
|
|
|
ResolveOmSrvHazards(uav);
|
|
|
|
|
|
|
|
if (NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)
|
|
|
|
needsUpdate |= ResolveOmRtvHazards(uav);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (needsUpdate)
|
|
|
|
BindFramebuffer();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 20:27:33 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::RestoreState() {
|
|
|
|
BindFramebuffer();
|
|
|
|
|
|
|
|
BindShader<DxbcProgramType::VertexShader> (GetCommonShader(m_state.vs.shader.ptr()));
|
|
|
|
BindShader<DxbcProgramType::HullShader> (GetCommonShader(m_state.hs.shader.ptr()));
|
|
|
|
BindShader<DxbcProgramType::DomainShader> (GetCommonShader(m_state.ds.shader.ptr()));
|
|
|
|
BindShader<DxbcProgramType::GeometryShader> (GetCommonShader(m_state.gs.shader.ptr()));
|
|
|
|
BindShader<DxbcProgramType::PixelShader> (GetCommonShader(m_state.ps.shader.ptr()));
|
|
|
|
BindShader<DxbcProgramType::ComputeShader> (GetCommonShader(m_state.cs.shader.ptr()));
|
|
|
|
|
|
|
|
ApplyInputLayout();
|
|
|
|
ApplyPrimitiveTopology();
|
|
|
|
ApplyBlendState();
|
|
|
|
ApplyBlendFactor();
|
|
|
|
ApplyDepthStencilState();
|
|
|
|
ApplyStencilRef();
|
|
|
|
ApplyRasterizerState();
|
|
|
|
ApplyRasterizerSampleCount();
|
|
|
|
ApplyViewportState();
|
|
|
|
|
|
|
|
BindDrawBuffers(
|
|
|
|
m_state.id.argBuffer.ptr(),
|
|
|
|
m_state.id.cntBuffer.ptr());
|
|
|
|
|
|
|
|
BindIndexBuffer(
|
|
|
|
m_state.ia.indexBuffer.buffer.ptr(),
|
|
|
|
m_state.ia.indexBuffer.offset,
|
|
|
|
m_state.ia.indexBuffer.format);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < m_state.ia.vertexBuffers.size(); i++) {
|
|
|
|
BindVertexBuffer(i,
|
|
|
|
m_state.ia.vertexBuffers[i].buffer.ptr(),
|
|
|
|
m_state.ia.vertexBuffers[i].offset,
|
|
|
|
m_state.ia.vertexBuffers[i].stride);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < m_state.so.targets.size(); i++)
|
|
|
|
BindXfbBuffer(i, m_state.so.targets[i].buffer.ptr(), ~0u);
|
|
|
|
|
|
|
|
RestoreConstantBuffers<DxbcProgramType::VertexShader> (m_state.vs.constantBuffers);
|
|
|
|
RestoreConstantBuffers<DxbcProgramType::HullShader> (m_state.hs.constantBuffers);
|
|
|
|
RestoreConstantBuffers<DxbcProgramType::DomainShader> (m_state.ds.constantBuffers);
|
|
|
|
RestoreConstantBuffers<DxbcProgramType::GeometryShader> (m_state.gs.constantBuffers);
|
|
|
|
RestoreConstantBuffers<DxbcProgramType::PixelShader> (m_state.ps.constantBuffers);
|
|
|
|
RestoreConstantBuffers<DxbcProgramType::ComputeShader> (m_state.cs.constantBuffers);
|
|
|
|
|
|
|
|
RestoreSamplers<DxbcProgramType::VertexShader> (m_state.vs.samplers);
|
|
|
|
RestoreSamplers<DxbcProgramType::HullShader> (m_state.hs.samplers);
|
|
|
|
RestoreSamplers<DxbcProgramType::DomainShader> (m_state.ds.samplers);
|
|
|
|
RestoreSamplers<DxbcProgramType::GeometryShader>(m_state.gs.samplers);
|
|
|
|
RestoreSamplers<DxbcProgramType::PixelShader> (m_state.ps.samplers);
|
|
|
|
RestoreSamplers<DxbcProgramType::ComputeShader> (m_state.cs.samplers);
|
|
|
|
|
|
|
|
RestoreShaderResources<DxbcProgramType::VertexShader> (m_state.vs.shaderResources);
|
|
|
|
RestoreShaderResources<DxbcProgramType::HullShader> (m_state.hs.shaderResources);
|
|
|
|
RestoreShaderResources<DxbcProgramType::DomainShader> (m_state.ds.shaderResources);
|
|
|
|
RestoreShaderResources<DxbcProgramType::GeometryShader> (m_state.gs.shaderResources);
|
|
|
|
RestoreShaderResources<DxbcProgramType::PixelShader> (m_state.ps.shaderResources);
|
|
|
|
RestoreShaderResources<DxbcProgramType::ComputeShader> (m_state.cs.shaderResources);
|
|
|
|
|
|
|
|
RestoreUnorderedAccessViews<DxbcProgramType::PixelShader> (m_state.ps.unorderedAccessViews);
|
|
|
|
RestoreUnorderedAccessViews<DxbcProgramType::ComputeShader> (m_state.cs.unorderedAccessViews);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType Stage>
|
|
|
|
void D3D11CommonContext<ContextType>::RestoreConstantBuffers(
|
|
|
|
D3D11ConstantBufferBindings& Bindings) {
|
|
|
|
uint32_t slotId = computeConstantBufferBinding(Stage, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < Bindings.size(); i++) {
|
|
|
|
BindConstantBuffer<Stage>(slotId + i, Bindings[i].buffer.ptr(),
|
|
|
|
Bindings[i].constantOffset, Bindings[i].constantBound);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType Stage>
|
|
|
|
void D3D11CommonContext<ContextType>::RestoreSamplers(
|
|
|
|
D3D11SamplerBindings& Bindings) {
|
|
|
|
uint32_t slotId = computeSamplerBinding(Stage, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < Bindings.size(); i++)
|
|
|
|
BindSampler<Stage>(slotId + i, Bindings[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType Stage>
|
|
|
|
void D3D11CommonContext<ContextType>::RestoreShaderResources(
|
|
|
|
D3D11ShaderResourceBindings& Bindings) {
|
|
|
|
uint32_t slotId = computeSrvBinding(Stage, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < Bindings.views.size(); i++)
|
|
|
|
BindShaderResource<Stage>(slotId + i, Bindings.views[i].ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType Stage>
|
|
|
|
void D3D11CommonContext<ContextType>::RestoreUnorderedAccessViews(
|
|
|
|
D3D11UnorderedAccessBindings& Bindings) {
|
|
|
|
uint32_t uavSlotId = computeUavBinding (Stage, 0);
|
|
|
|
uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < Bindings.size(); i++) {
|
|
|
|
BindUnorderedAccessView<Stage>(
|
|
|
|
uavSlotId + i,
|
|
|
|
Bindings[i].ptr(),
|
|
|
|
ctrSlotId + i, ~0u);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 17:58:42 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
bool D3D11CommonContext<ContextType>::TestRtvUavHazards(
|
|
|
|
UINT NumRTVs,
|
|
|
|
ID3D11RenderTargetView* const* ppRTVs,
|
|
|
|
UINT NumUAVs,
|
|
|
|
ID3D11UnorderedAccessView* const* ppUAVs) {
|
|
|
|
if (NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) NumRTVs = 0;
|
|
|
|
if (NumUAVs == D3D11_KEEP_UNORDERED_ACCESS_VIEWS) NumUAVs = 0;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumRTVs; i++) {
|
|
|
|
auto rtv = static_cast<D3D11RenderTargetView*>(ppRTVs[i]);
|
|
|
|
|
|
|
|
if (!rtv)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < i; j++) {
|
|
|
|
if (CheckViewOverlap(rtv, static_cast<D3D11RenderTargetView*>(ppRTVs[j])))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rtv->HasBindFlag(D3D11_BIND_UNORDERED_ACCESS)) {
|
|
|
|
for (uint32_t j = 0; j < NumUAVs; j++) {
|
|
|
|
if (CheckViewOverlap(rtv, static_cast<D3D11UnorderedAccessView*>(ppUAVs[j])))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumUAVs; i++) {
|
|
|
|
auto uav = static_cast<D3D11UnorderedAccessView*>(ppUAVs[i]);
|
|
|
|
|
|
|
|
if (!uav)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < i; j++) {
|
|
|
|
if (CheckViewOverlap(uav, static_cast<D3D11UnorderedAccessView*>(ppUAVs[j])))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<typename ContextType>
|
|
|
|
template<DxbcProgramType ShaderStage>
|
|
|
|
bool D3D11CommonContext<ContextType>::TestSrvHazards(
|
|
|
|
D3D11ShaderResourceView* pView) {
|
|
|
|
bool hazard = false;
|
|
|
|
|
|
|
|
if (ShaderStage == DxbcProgramType::ComputeShader) {
|
|
|
|
int32_t uav = m_state.cs.uavMask.findNext(0);
|
|
|
|
|
|
|
|
while (uav >= 0 && !hazard) {
|
|
|
|
hazard = CheckViewOverlap(pView, m_state.cs.unorderedAccessViews[uav].ptr());
|
|
|
|
uav = m_state.cs.uavMask.findNext(uav + 1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
hazard = CheckViewOverlap(pView, m_state.om.depthStencilView.ptr());
|
|
|
|
|
|
|
|
for (uint32_t i = 0; !hazard && i < m_state.om.maxRtv; i++)
|
|
|
|
hazard = CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr());
|
|
|
|
|
|
|
|
for (uint32_t i = 0; !hazard && i < m_state.om.maxUav; i++)
|
|
|
|
hazard = CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
return hazard;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 16:41:50 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
void D3D11CommonContext<ContextType>::UpdateResource(
|
|
|
|
ID3D11Resource* pDstResource,
|
|
|
|
UINT DstSubresource,
|
|
|
|
const D3D11_BOX* pDstBox,
|
|
|
|
const void* pSrcData,
|
|
|
|
UINT SrcRowPitch,
|
|
|
|
UINT SrcDepthPitch,
|
|
|
|
UINT CopyFlags) {
|
|
|
|
auto context = static_cast<ContextType*>(this);
|
|
|
|
D3D10DeviceLock lock = context->LockContext();
|
|
|
|
|
|
|
|
if (!pDstResource)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// We need a different code path for buffers
|
|
|
|
D3D11_RESOURCE_DIMENSION resourceType;
|
|
|
|
pDstResource->GetType(&resourceType);
|
|
|
|
|
|
|
|
if (likely(resourceType == D3D11_RESOURCE_DIMENSION_BUFFER)) {
|
|
|
|
const auto bufferResource = static_cast<D3D11Buffer*>(pDstResource);
|
|
|
|
uint64_t bufferSize = bufferResource->Desc()->ByteWidth;
|
|
|
|
|
|
|
|
// Provide a fast path for mapped buffer updates since some
|
|
|
|
// games use UpdateSubresource to update constant buffers.
|
|
|
|
if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT) && likely(!pDstBox)) {
|
|
|
|
context->UpdateMappedBuffer(bufferResource, 0, bufferSize, pSrcData, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate buffer range to update
|
|
|
|
uint64_t offset = 0;
|
|
|
|
uint64_t length = bufferSize;
|
|
|
|
|
|
|
|
if (pDstBox) {
|
|
|
|
offset = pDstBox->left;
|
|
|
|
length = pDstBox->right - offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unlikely(offset + length > bufferSize))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Still try to be fast if a box is provided but we update the full buffer
|
|
|
|
if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT)) {
|
|
|
|
CopyFlags &= D3D11_COPY_DISCARD | D3D11_COPY_NO_OVERWRITE;
|
|
|
|
|
|
|
|
if (likely(length == bufferSize) || unlikely(CopyFlags != 0)) {
|
|
|
|
context->UpdateMappedBuffer(bufferResource, offset, length, pSrcData, CopyFlags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise we can't really do anything fancy, so just do a GPU copy
|
|
|
|
context->UpdateBuffer(bufferResource, offset, length, pSrcData);
|
|
|
|
} else {
|
|
|
|
D3D11CommonTexture* textureResource = GetCommonTexture(pDstResource);
|
|
|
|
|
|
|
|
context->UpdateTexture(textureResource,
|
|
|
|
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 18:07:03 +02:00
|
|
|
template<typename ContextType>
|
|
|
|
bool D3D11CommonContext<ContextType>::ValidateRenderTargets(
|
|
|
|
UINT NumViews,
|
|
|
|
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
|
|
|
ID3D11DepthStencilView* pDepthStencilView) {
|
|
|
|
Rc<DxvkImageView> refView;
|
|
|
|
|
|
|
|
VkExtent3D dsvExtent = { 0u, 0u, 0u };
|
|
|
|
VkExtent3D rtvExtent = { 0u, 0u, 0u };
|
|
|
|
|
|
|
|
if (pDepthStencilView != nullptr) {
|
|
|
|
refView = static_cast<D3D11DepthStencilView*>(
|
|
|
|
pDepthStencilView)->GetImageView();
|
|
|
|
dsvExtent = refView->mipLevelExtent(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < NumViews; i++) {
|
|
|
|
if (ppRenderTargetViews[i] != nullptr) {
|
|
|
|
auto curView = static_cast<D3D11RenderTargetView*>(
|
|
|
|
ppRenderTargetViews[i])->GetImageView();
|
|
|
|
|
|
|
|
if (!rtvExtent.width)
|
|
|
|
rtvExtent = curView->mipLevelExtent(0);
|
|
|
|
|
|
|
|
if (refView != nullptr) {
|
|
|
|
// Render target views must all have the same sample count,
|
|
|
|
// layer count, and type. The size can mismatch under certain
|
|
|
|
// conditions, the D3D11 documentation is wrong here.
|
|
|
|
if (curView->info().type != refView->info().type
|
|
|
|
|| curView->info().numLayers != refView->info().numLayers)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (curView->imageInfo().sampleCount
|
|
|
|
!= refView->imageInfo().sampleCount)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Color targets must all be the same size
|
|
|
|
VkExtent3D curExtent = curView->mipLevelExtent(0);
|
|
|
|
|
|
|
|
if (curExtent.width != rtvExtent.width
|
|
|
|
|| curExtent.height != rtvExtent.height)
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
// Set reference view. All remaining views
|
|
|
|
// must be compatible to the reference view.
|
|
|
|
refView = curView;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Based on testing, the depth-stencil target is allowed
|
|
|
|
// to be larger than all color targets, but not smaller
|
|
|
|
if (rtvExtent.width && dsvExtent.width) {
|
|
|
|
if (rtvExtent.width > dsvExtent.width
|
|
|
|
|| rtvExtent.height > dsvExtent.height)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-03 16:33:54 +02:00
|
|
|
// Explicitly instantiate here
|
|
|
|
template class D3D11CommonContext<D3D11DeferredContext>;
|
|
|
|
template class D3D11CommonContext<D3D11ImmediateContext>;
|
|
|
|
|
|
|
|
}
|