text: #pragma once
  
  #include "../dxvk/dxvk_adapter.h"
  #include "../dxvk/dxvk_cs.h"
  #include "../dxvk/dxvk_device.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<ID3D11DeviceContext1> {
      friend class D3D11DeviceContextExt;
    public:
      
      D3D11DeviceContext(
              D3D11Device*            pParent,
        const Rc<DxvkDevice>&         Device,
              DxvkCsChunkFlags        CsFlags);
      ~D3D11DeviceContext();
      
      HRESULT STDMETHODCALLTYPE QueryInterface(
              REFIID  riid,
              void**  ppvObject);
      
      void STDMETHODCALLTYPE DiscardResource(ID3D11Resource *pResource);
  
      void STDMETHODCALLTYPE DiscardView(ID3D11View* pResourceView);
  
      void STDMETHODCALLTYPE DiscardView1(
              ID3D11View*                      pResourceView,
        const D3D11_RECT*                      pRects,
              UINT                             NumRects);
  
      void STDMETHODCALLTYPE GetDevice(ID3D11Device **ppDevice);
      
      void STDMETHODCALLTYPE ClearState();
      
      void STDMETHODCALLTYPE Begin(ID3D11Asynchronous *pAsync);
      
      void STDMETHODCALLTYPE End(ID3D11Asynchronous *pAsync);
      
      void STDMETHODCALLTYPE SetPredication(
              ID3D11Predicate*                  pPredicate,
              BOOL                              PredicateValue);
      
      void STDMETHODCALLTYPE GetPredication(
              ID3D11Predicate**                 ppPredicate,
              BOOL*                             pPredicateValue);
      
      void STDMETHODCALLTYPE CopySubresourceRegion(
              ID3D11Resource*                   pDstResource,
              UINT                              DstSubresource,
              UINT                              DstX,
              UINT                              DstY,
              UINT                              DstZ,
              ID3D11Resource*                   pSrcResource,
              UINT                              SrcSubresource,
        const D3D11_BOX*                        pSrcBox);
      
      void STDMETHODCALLTYPE CopySubresourceRegion1(
              ID3D11Resource*                   pDstResource,
              UINT                              DstSubresource,
              UINT                              DstX,
              UINT                              DstY,
              UINT                              DstZ,
              ID3D11Resource*                   pSrcResource,
              UINT                              SrcSubresource,
        const D3D11_BOX*                        pSrcBox,
              UINT                              CopyFlags);
      
      void STDMETHODCALLTYPE CopyResource(
              ID3D11Resource*                   pDstResource,
              ID3D11Resource*                   pSrcResource);
      
      void STDMETHODCALLTYPE CopyStructureCount(
              ID3D11Buffer*                     pDstBuffer,
              UINT                              DstAlignedByteOffset,
              ID3D11UnorderedAccessView*        pSrcView);
      
      void STDMETHODCALLTYPE ClearRenderTargetView(
              ID3D11RenderTargetView*           pRenderTargetView,
        const FLOAT                             ColorRGBA[4]);
      
      void STDMETHODCALLTYPE ClearUnorderedAccessViewUint(
              ID3D11UnorderedAccessView*        pUnorderedAccessView,
        const UINT                              Values[4]);
      
      void STDMETHODCALLTYPE ClearUnorderedAccessViewFloat(
              ID3D11UnorderedAccessView*        pUnorderedAccessView,
        const FLOAT                             Values[4]);
      
      void STDMETHODCALLTYPE ClearDepthStencilView(
              ID3D11DepthStencilView*           pDepthStencilView,
              UINT                              ClearFlags,
              FLOAT                             Depth,
              UINT8                             Stencil);
      
      void STDMETHODCALLTYPE ClearView(
              ID3D11View                        *pView,
        const FLOAT                             Color[4],
        const D3D11_RECT                        *pRect,
              UINT                              NumRects);
  
      void STDMETHODCALLTYPE GenerateMips(
              ID3D11ShaderResourceView*         pShaderResourceView);
      
      void STDMETHODCALLTYPE UpdateSubresource(
              ID3D11Resource*                   pDstResource,
              UINT                              DstSubresource,
        const D3D11_BOX*                        pDstBox,
        const void*                             pSrcData,
              UINT                              SrcRowPitch,
              UINT                              SrcDepthPitch);
      
      void STDMETHODCALLTYPE UpdateSubresource1(
              ID3D11Resource*                   pDstResource,
              UINT                              DstSubresource,
        const D3D11_BOX*                        pDstBox,
        const void*                             pSrcData,
              UINT                              SrcRowPitch,
              UINT                              SrcDepthPitch,
              UINT                              CopyFlags);
      
      void STDMETHODCALLTYPE SetResourceMinLOD(
              ID3D11Resource*                   pResource,
              FLOAT                             MinLOD);
      
      FLOAT STDMETHODCALLTYPE GetResourceMinLOD(
              ID3D11Resource*                   pResource);
      
      void STDMETHODCALLTYPE ResolveSubresource(
              ID3D11Resource*                   pDstResource,
              UINT                              DstSubresource,
              ID3D11Resource*                   pSrcResource,
              UINT                              SrcSubresource,
              DXGI_FORMAT                       Format);
      
      void STDMETHODCALLTYPE DrawAuto();
      
      void STDMETHODCALLTYPE Draw(
              UINT            VertexCount,
              UINT            StartVertexLocation);
      
      void STDMETHODCALLTYPE DrawIndexed(
              UINT            IndexCount,
              UINT            StartIndexLocation,
              INT             BaseVertexLocation);
      
      void STDMETHODCALLTYPE DrawInstanced(
              UINT            VertexCountPerInstance,
              UINT            InstanceCount,
              UINT            StartVertexLocation,
              UINT            StartInstanceLocation);
      
      void STDMETHODCALLTYPE DrawIndexedInstanced(
              UINT            IndexCountPerInstance,
              UINT            InstanceCount,
              UINT            StartIndexLocation,
              INT             BaseVertexLocation,
              UINT            StartInstanceLocation);
      
      void STDMETHODCALLTYPE DrawIndexedInstancedIndirect(
              ID3D11Buffer*   pBufferForArgs,
              UINT            AlignedByteOffsetForArgs);
      
      void STDMETHODCALLTYPE DrawInstancedIndirect(
              ID3D11Buffer*   pBufferForArgs,
              UINT            AlignedByteOffsetForArgs);
      
      void STDMETHODCALLTYPE Dispatch(
              UINT            ThreadGroupCountX,
              UINT            ThreadGroupCountY,
              UINT            ThreadGroupCountZ);
      
      void STDMETHODCALLTYPE DispatchIndirect(
              ID3D11Buffer*   pBufferForArgs,
              UINT            AlignedByteOffsetForArgs);
      
      void STDMETHODCALLTYPE IASetInputLayout(
              ID3D11InputLayout*                pInputLayout);
      
      void STDMETHODCALLTYPE IASetPrimitiveTopology(
              D3D11_PRIMITIVE_TOPOLOGY          Topology);
      
      void STDMETHODCALLTYPE IASetVertexBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppVertexBuffers,
        const UINT*                             pStrides,
        const UINT*                             pOffsets);
      
      void STDMETHODCALLTYPE IASetIndexBuffer(
              ID3D11Buffer*                     pIndexBuffer,
              DXGI_FORMAT                       Format,
              UINT                              Offset);
      
      void STDMETHODCALLTYPE IAGetInputLayout(
              ID3D11InputLayout**               ppInputLayout);
      
      void STDMETHODCALLTYPE IAGetPrimitiveTopology(
              D3D11_PRIMITIVE_TOPOLOGY*         pTopology);
      
      void STDMETHODCALLTYPE IAGetVertexBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppVertexBuffers,
              UINT*                             pStrides,
              UINT*                             pOffsets);
      
      void STDMETHODCALLTYPE IAGetIndexBuffer(
              ID3D11Buffer**                    ppIndexBuffer,
              DXGI_FORMAT*                      pFormat,
              UINT*                             pOffset);
      
      void STDMETHODCALLTYPE VSSetShader(
              ID3D11VertexShader*               pVertexShader,
              ID3D11ClassInstance* const*       ppClassInstances,
              UINT                              NumClassInstances);
      
      void STDMETHODCALLTYPE VSSetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers);
  
       void STDMETHODCALLTYPE VSSetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers,
        const UINT*                             pFirstConstant,
        const UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE VSSetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView* const*  ppShaderResourceViews);
      
      void STDMETHODCALLTYPE VSSetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState* const*        ppSamplers);
      
      void STDMETHODCALLTYPE VSGetShader(
              ID3D11VertexShader**              ppVertexShader,
              ID3D11ClassInstance**             ppClassInstances,
              UINT*                             pNumClassInstances);
      
      void STDMETHODCALLTYPE VSGetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers);
  
      void STDMETHODCALLTYPE VSGetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers,
              UINT*                             pFirstConstant,
              UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE VSGetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView**        ppShaderResourceViews);
      
      void STDMETHODCALLTYPE VSGetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState**              ppSamplers);
      
      void STDMETHODCALLTYPE HSSetShader(
              ID3D11HullShader*                 pHullShader,
              ID3D11ClassInstance* const*       ppClassInstances,
              UINT                              NumClassInstances);
      
      void STDMETHODCALLTYPE HSSetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView* const*  ppShaderResourceViews);
      
      void STDMETHODCALLTYPE HSSetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers);
      
      void STDMETHODCALLTYPE HSSetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers,
        const UINT*                             pFirstConstant,
        const UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE HSSetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState* const*        ppSamplers);
      
      void STDMETHODCALLTYPE HSGetShader(
              ID3D11HullShader**                ppHullShader,
              ID3D11ClassInstance**             ppClassInstances,
              UINT*                             pNumClassInstances);
      
      void STDMETHODCALLTYPE HSGetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers);
  
       void STDMETHODCALLTYPE HSGetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers,
              UINT*                             pFirstConstant,
              UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE HSGetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView**        ppShaderResourceViews);
      
      void STDMETHODCALLTYPE HSGetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState**              ppSamplers);
      
      void STDMETHODCALLTYPE DSSetShader(
              ID3D11DomainShader*               pDomainShader,
              ID3D11ClassInstance* const*       ppClassInstances,
              UINT                              NumClassInstances);
      
      void STDMETHODCALLTYPE DSSetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView* const*  ppShaderResourceViews);
      
      void STDMETHODCALLTYPE DSSetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers);
  
      void STDMETHODCALLTYPE DSSetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers,
        const UINT*                             pFirstConstant,
        const UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE DSSetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState* const*        ppSamplers);
      
      void STDMETHODCALLTYPE DSGetShader(
              ID3D11DomainShader**              ppDomainShader,
              ID3D11ClassInstance**             ppClassInstances,
              UINT*                             pNumClassInstances);
      
      void STDMETHODCALLTYPE DSGetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers);
      
       void STDMETHODCALLTYPE DSGetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers,
              UINT*                             pFirstConstant,
              UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE DSGetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView**        ppShaderResourceViews);
      
      void STDMETHODCALLTYPE DSGetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState**              ppSamplers);
      
      void STDMETHODCALLTYPE GSSetShader(
              ID3D11GeometryShader*             pShader,
              ID3D11ClassInstance* const*       ppClassInstances,
              UINT                              NumClassInstances);
      
      void STDMETHODCALLTYPE GSSetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers);
      
      virtual void STDMETHODCALLTYPE GSSetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers,
        const UINT*                             pFirstConstant,
        const UINT*                             pNumConstants);
  
      void STDMETHODCALLTYPE GSSetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView* const*  ppShaderResourceViews);
      
      void STDMETHODCALLTYPE GSSetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState* const*        ppSamplers);
      
      void STDMETHODCALLTYPE GSGetShader(
              ID3D11GeometryShader**            ppGeometryShader,
              ID3D11ClassInstance**             ppClassInstances,
              UINT*                             pNumClassInstances);
      
      void STDMETHODCALLTYPE GSGetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers);
      
       void STDMETHODCALLTYPE GSGetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers,
              UINT*                             pFirstConstant,
              UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE GSGetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView**        ppShaderResourceViews);
      
      void STDMETHODCALLTYPE GSGetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState**              ppSamplers);
      
      void STDMETHODCALLTYPE PSSetShader(
              ID3D11PixelShader*                pPixelShader,
              ID3D11ClassInstance* const*       ppClassInstances,
              UINT                              NumClassInstances);
      
      void STDMETHODCALLTYPE PSSetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers);
  
      void STDMETHODCALLTYPE PSSetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers,
        const UINT*                             pFirstConstant,
        const UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE PSSetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView* const*  ppShaderResourceViews);
      
      void STDMETHODCALLTYPE PSSetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState* const*        ppSamplers);
      
      void STDMETHODCALLTYPE PSGetShader(
              ID3D11PixelShader**               ppPixelShader,
              ID3D11ClassInstance**             ppClassInstances,
              UINT*                             pNumClassInstances);
      
      void STDMETHODCALLTYPE PSGetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers);
      
      void STDMETHODCALLTYPE PSGetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers,
              UINT*                             pFirstConstant,
              UINT*                             pNumConstants);
  
      void STDMETHODCALLTYPE PSGetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView**        ppShaderResourceViews);
      
      void STDMETHODCALLTYPE PSGetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState**              ppSamplers);
      
      void STDMETHODCALLTYPE CSSetShader(
              ID3D11ComputeShader*              pComputeShader,
              ID3D11ClassInstance* const*       ppClassInstances,
              UINT                              NumClassInstances);
      
      void STDMETHODCALLTYPE CSSetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers);
      
      void STDMETHODCALLTYPE CSSetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers,
        const UINT*                             pFirstConstant,
        const UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE CSSetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView* const*  ppShaderResourceViews);
      
      void STDMETHODCALLTYPE CSSetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState* const*        ppSamplers);
      
      void STDMETHODCALLTYPE CSSetUnorderedAccessViews(
              UINT                              StartSlot,
              UINT                              NumUAVs,
              ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
        const UINT*                             pUAVInitialCounts);
      
      void STDMETHODCALLTYPE CSGetShader(
              ID3D11ComputeShader**             ppComputeShader,
              ID3D11ClassInstance**             ppClassInstances,
              UINT*                             pNumClassInstances);
      
      void STDMETHODCALLTYPE CSGetConstantBuffers(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers);
      
      void STDMETHODCALLTYPE CSGetConstantBuffers1(
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers,
              UINT*                             pFirstConstant,
              UINT*                             pNumConstants);
      
      void STDMETHODCALLTYPE CSGetShaderResources(
              UINT                              StartSlot,
              UINT                              NumViews,
              ID3D11ShaderResourceView**        ppShaderResourceViews);
      
      void STDMETHODCALLTYPE CSGetSamplers(
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState**              ppSamplers);
      
      void STDMETHODCALLTYPE CSGetUnorderedAccessViews(
              UINT                              StartSlot,
              UINT                              NumUAVs,
              ID3D11UnorderedAccessView**       ppUnorderedAccessViews);
      
      void STDMETHODCALLTYPE OMSetRenderTargets(
              UINT                              NumViews,
              ID3D11RenderTargetView* const*    ppRenderTargetViews,
              ID3D11DepthStencilView*           pDepthStencilView);
      
      void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews(
              UINT                              NumRTVs,
              ID3D11RenderTargetView* const*    ppRenderTargetViews,
              ID3D11DepthStencilView*           pDepthStencilView,
              UINT                              UAVStartSlot,
              UINT                              NumUAVs,
              ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
        const UINT*                             pUAVInitialCounts);
      
      void STDMETHODCALLTYPE OMSetBlendState(
              ID3D11BlendState*                 pBlendState,
        const FLOAT                             BlendFactor[4],
              UINT                              SampleMask);
      
      void STDMETHODCALLTYPE OMSetDepthStencilState(
              ID3D11DepthStencilState*          pDepthStencilState,
              UINT                              StencilRef);
      
      void STDMETHODCALLTYPE OMGetRenderTargets(
              UINT                              NumViews,
              ID3D11RenderTargetView**          ppRenderTargetViews,
              ID3D11DepthStencilView**          ppDepthStencilView);
      
      void STDMETHODCALLTYPE OMGetRenderTargetsAndUnorderedAccessViews(
              UINT                              NumRTVs,
              ID3D11RenderTargetView**          ppRenderTargetViews,
              ID3D11DepthStencilView**          ppDepthStencilView,
              UINT                              UAVStartSlot,
              UINT                              NumUAVs,
              ID3D11UnorderedAccessView**       ppUnorderedAccessViews);
      
      void STDMETHODCALLTYPE OMGetBlendState(
              ID3D11BlendState**                ppBlendState,
              FLOAT                             BlendFactor[4],
              UINT*                             pSampleMask);
      
      void STDMETHODCALLTYPE OMGetDepthStencilState(
              ID3D11DepthStencilState**         ppDepthStencilState,
              UINT*                             pStencilRef);
      
      void STDMETHODCALLTYPE RSSetState(
              ID3D11RasterizerState*            pRasterizerState);
      
      void STDMETHODCALLTYPE RSSetViewports(
              UINT                              NumViewports,
        const D3D11_VIEWPORT*                   pViewports);
      
      void STDMETHODCALLTYPE RSSetScissorRects(
              UINT                              NumRects,
        const D3D11_RECT*                       pRects);
      
      void STDMETHODCALLTYPE RSGetState(
              ID3D11RasterizerState**           ppRasterizerState);
      
      void STDMETHODCALLTYPE RSGetViewports(
              UINT*                             pNumViewports,
              D3D11_VIEWPORT*                   pViewports);
      
      void STDMETHODCALLTYPE RSGetScissorRects(
              UINT*                             pNumRects,
              D3D11_RECT*                       pRects);
      
      void STDMETHODCALLTYPE SOSetTargets(
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppSOTargets,
        const UINT*                             pOffsets);
      
      void STDMETHODCALLTYPE SOGetTargets(
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppSOTargets);
      
      void STDMETHODCALLTYPE SOGetTargetsWithOffsets(
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppSOTargets,
              UINT*                             pOffsets);
      
      void STDMETHODCALLTYPE TransitionSurfaceLayout(
              IDXGIVkInteropSurface*    pSurface,
        const VkImageSubresourceRange*  pSubresources,
              VkImageLayout             OldLayout,
              VkImageLayout             NewLayout);
  
    protected:
      
      D3D11Device* const          m_parent;
      D3D11DeviceContextExt       m_contextExt;
      D3D11UserDefinedAnnotation  m_annotation;
      D3D10Multithread            m_multithread;
      
      Rc<DxvkDevice>              m_device;
      Rc<DxvkDataBuffer>          m_updateBuffer;
      
      DxvkCsChunkFlags            m_csFlags;
      DxvkCsChunkRef              m_csChunk;
      
      Com<D3D11BlendState>        m_defaultBlendState;
      Com<D3D11DepthStencilState> m_defaultDepthStencilState;
      Com<D3D11RasterizerState>   m_defaultRasterizerState;
      
      D3D11ContextState           m_state;
      D3D11CmdData*               m_cmdData;
      
      void ApplyInputLayout();
      
      void ApplyPrimitiveTopology();
      
      void ApplyBlendState();
      
      void ApplyBlendFactor();
      
      void ApplyDepthStencilState();
      
      void ApplyStencilRef();
      
      void ApplyRasterizerState();
      
      void ApplyViewportState();
  
      void BindShader(
              DxbcProgramType                   ShaderStage,
        const D3D11CommonShader*                pShaderModule);
      
      void BindFramebuffer(
              BOOL                              Spill);
      
      void BindDrawBuffers(
              D3D11Buffer*                      pBufferForArgs,
              D3D11Buffer*                      pBufferForCount);
      
      void BindVertexBuffer(
              UINT                              Slot,
              D3D11Buffer*                      pBuffer,
              UINT                              Offset,
              UINT                              Stride);
      
      void BindIndexBuffer(
              D3D11Buffer*                      pBuffer,
              UINT                              Offset,
              DXGI_FORMAT                       Format);
      
      void BindXfbBuffer(
              UINT                              Slot,
              D3D11Buffer*                      pBuffer,
              UINT                              Offset);
      
      void BindConstantBuffer(
              UINT                              Slot,
        const D3D11ConstantBufferBinding*       pBufferBinding);
      
      void BindSampler(
              UINT                              Slot,
              D3D11SamplerState*                pSampler);
      
      void BindShaderResource(
              UINT                              Slot,
              D3D11ShaderResourceView*          pResource);
      
      void BindUnorderedAccessView(
              UINT                              UavSlot,
              D3D11UnorderedAccessView*         pUav,
              UINT                              CtrSlot,
              UINT                              Counter);
      
      void DiscardBuffer(
              D3D11Buffer*                      pBuffer);
      
      void DiscardTexture(
              D3D11CommonTexture*               pTexture);
      
      void SetDrawBuffers(
              ID3D11Buffer*                     pBufferForArgs,
              ID3D11Buffer*                     pBufferForCount);
      
      void SetConstantBuffers(
              DxbcProgramType                   ShaderStage,
              D3D11ConstantBufferBindings&      Bindings,
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers);
      
      void SetConstantBuffers1(
              DxbcProgramType                   ShaderStage,
              D3D11ConstantBufferBindings&      Bindings,
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer* const*              ppConstantBuffers,
        const UINT*                             pFirstConstant,
        const UINT*                             pNumConstants);
      
      void SetSamplers(
              DxbcProgramType                   ShaderStage,
              D3D11SamplerBindings&             Bindings,
              UINT                              StartSlot,
              UINT                              NumSamplers,
              ID3D11SamplerState* const*        ppSamplers);
      
      void SetShaderResources(
              DxbcProgramType                   ShaderStage,
              D3D11ShaderResourceBindings&      Bindings,
              UINT                              StartSlot,
              UINT                              NumResources,
              ID3D11ShaderResourceView* const*  ppResources);
      
      void SetUnorderedAccessViews(
              DxbcProgramType                   ShaderStage,
              D3D11UnorderedAccessBindings&     Bindings,
              UINT                              StartSlot,
              UINT                              NumUAVs,
              ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
        const UINT*                             pUAVInitialCounts);
      
      void SetRenderTargets(
              UINT                              NumViews,
              ID3D11RenderTargetView* const*    ppRenderTargetViews,
              ID3D11DepthStencilView*           pDepthStencilView);
      
      void GetConstantBuffers(
        const D3D11ConstantBufferBindings&      Bindings,
              UINT                              StartSlot,
              UINT                              NumBuffers,
              ID3D11Buffer**                    ppConstantBuffers, 
              UINT*                             pFirstConstant, 
              UINT*                             pNumConstants);
      
      void RestoreState();
      
      void RestoreConstantBuffers(
              DxbcProgramType                   Stage,
              D3D11ConstantBufferBindings&      Bindings);
      
      void RestoreSamplers(
              DxbcProgramType                   Stage,
              D3D11SamplerBindings&             Bindings);
      
      void RestoreShaderResources(
              DxbcProgramType                   Stage,
              D3D11ShaderResourceBindings&      Bindings);
      
      void RestoreUnorderedAccessViews(
              DxbcProgramType                   Stage,
              D3D11UnorderedAccessBindings&     Bindings);
      
      bool ValidateRenderTargets(
              UINT                              NumViews,
              ID3D11RenderTargetView* const*    ppRenderTargetViews,
              ID3D11DepthStencilView*           pDepthStencilView);
      
      DxvkDataSlice AllocUpdateBufferSlice(size_t Size);
      
      DxvkCsChunkRef AllocCsChunk();
      
      template<typename T>
      const D3D11CommonShader* GetCommonShader(T* pShader) const {
        return pShader != nullptr ? pShader->GetCommonShader() : nullptr;
      }
  
      D3D10DeviceLock LockContext() {
        return m_multithread.AcquireLock();
      }
  
      template<typename Cmd>
      void EmitCs(Cmd&& command) {
        m_cmdData = nullptr;
  
        if (!m_csChunk->push(command)) {
          EmitCsChunk(std::move(m_csChunk));
          
          m_csChunk = AllocCsChunk();
          m_csChunk->push(command);
        }
      }
  
      template<typename M, typename Cmd, typename... Args>
      M* EmitCsCmd(Cmd&& command, Args&&... args) {
        M* data = m_csChunk->pushCmd<M, Cmd, Args...>(
          command, std::forward<Args>(args)...);
  
        if (!data) {
          EmitCsChunk(std::move(m_csChunk));
          
          m_csChunk = AllocCsChunk();
          data = m_csChunk->pushCmd<M, Cmd, Args...>(
            command, std::forward<Args>(args)...);
        }
  
        m_cmdData = data;
        return data;
      }
      
      void FlushCsChunk() {
        if (m_csChunk->commandCount() != 0) {
          EmitCsChunk(std::move(m_csChunk));
          m_csChunk = AllocCsChunk();
          m_cmdData = nullptr;
        }
      }
      
      virtual void EmitCsChunk(DxvkCsChunkRef&& chunk) = 0;
      
    };
    
  }
  