#pragma once #include "../dxvk/dxvk_adapter.h" #include "../dxvk/dxvk_cs.h" #include "../dxvk/dxvk_device.h" #include "../dxvk/dxvk_staging.h" #include "../d3d10/d3d10_multithread.h" #include "d3d11_annotation.h" #include "d3d11_cmd.h" #include "d3d11_context_ext.h" #include "d3d11_context_state.h" #include "d3d11_device_child.h" #include "d3d11_texture.h" namespace dxvk { class D3D11Device; class D3D11DeviceContext : public D3D11DeviceChild { template friend class D3D11DeviceContextExt; // Needed in order to call EmitCs for pushing markers template friend class D3D11UserDefinedAnnotation; constexpr static VkDeviceSize StagingBufferSize = 4ull << 20; public: D3D11DeviceContext( D3D11Device* pParent, const Rc& Device, DxvkCsChunkFlags CsFlags); ~D3D11DeviceContext(); D3D10DeviceLock LockContext() { return m_multithread.AcquireLock(); } protected: D3D10Multithread m_multithread; Rc m_device; Rc m_updateBuffer; DxvkStagingBuffer m_staging; DxvkCsChunkFlags m_csFlags; DxvkCsChunkRef m_csChunk; D3D11ContextState m_state; D3D11CmdData* m_cmdData; VkClearValue ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo); DxvkDataSlice AllocUpdateBufferSlice(size_t Size); DxvkBufferSlice AllocStagingBuffer( VkDeviceSize Size); void ResetStagingBuffer(); DxvkCsChunkRef AllocCsChunk(); static void InitDefaultPrimitiveTopology( DxvkInputAssemblyState* pIaState); static void InitDefaultRasterizerState( DxvkRasterizerState* pRsState); static void InitDefaultDepthStencilState( DxvkDepthStencilState* pDsState); static void InitDefaultBlendState( DxvkBlendMode* pCbState, DxvkLogicOpState* pLoState, DxvkMultisampleState* pMsState, UINT SampleMask); template const D3D11CommonShader* GetCommonShader(T* pShader) const { return pShader != nullptr ? pShader->GetCommonShader() : nullptr; } static uint32_t GetIndirectCommandStride(const D3D11CmdDrawIndirectData* cmdData, uint32_t offset, uint32_t minStride) { if (likely(cmdData->stride)) return cmdData->offset + cmdData->count * cmdData->stride == offset ? cmdData->stride : 0; uint32_t stride = offset - cmdData->offset; return stride >= minStride && stride <= 32 ? stride : 0; } static bool ValidateDrawBufferSize(ID3D11Buffer* pBuffer, UINT Offset, UINT Size) { UINT bufferSize = 0; if (likely(pBuffer != nullptr)) bufferSize = static_cast(pBuffer)->Desc()->ByteWidth; return bufferSize >= Offset + Size; } template void EmitCs(Cmd&& command) { m_cmdData = nullptr; if (unlikely(!m_csChunk->push(command))) { EmitCsChunk(std::move(m_csChunk)); m_csChunk = AllocCsChunk(); m_csChunk->push(command); } } template M* EmitCsCmd(Cmd&& command, Args&&... args) { M* data = m_csChunk->pushCmd( command, std::forward(args)...); if (unlikely(!data)) { EmitCsChunk(std::move(m_csChunk)); m_csChunk = AllocCsChunk(); data = m_csChunk->pushCmd( command, std::forward(args)...); } m_cmdData = data; return data; } void FlushCsChunk() { if (likely(!m_csChunk->empty())) { EmitCsChunk(std::move(m_csChunk)); m_csChunk = AllocCsChunk(); m_cmdData = nullptr; } } void TrackResourceSequenceNumber( ID3D11Resource* pResource); virtual void EmitCsChunk(DxvkCsChunkRef&& chunk) = 0; virtual void TrackTextureSequenceNumber( D3D11CommonTexture* pResource, UINT Subresource) = 0; virtual void TrackBufferSequenceNumber( D3D11Buffer* pResource) = 0; }; }