csgo-2018-source/public/rendersystem/irendercontext.h
2021-07-24 21:11:47 -07:00

383 lines
13 KiB
C++

//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef IRENDERCONTEXT_H
#define IRENDERCONTEXT_H
#ifdef _WIN32
#pragma once
#endif
#include "rendersystem/irenderdevice.h"
#include "mathlib/vector4d.h"
#include "tier1/generichash.h"
#include "rendersystem/renderstate.h"
#include "mathlib/vmatrix.h"
#include "rendersystem/schema/renderable.g.h"
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
enum RenderBufferStride_t
{
RENDER_BUFFER_STRIDE_INVALID = -1,
};
//-----------------------------------------------------------------------------
// Index/vertex buffer lock info
//-----------------------------------------------------------------------------
struct LockDesc_t
{
void *m_pMemory;
};
//-----------------------------------------------------------------------------
// Viewport structure
//-----------------------------------------------------------------------------
#define RENDER_VIEWPORT_VERSION 1
struct RenderViewport_t
{
int m_nVersion;
int m_nTopLeftX;
int m_nTopLeftY;
int m_nWidth;
int m_nHeight;
float m_flMinZ;
float m_flMaxZ;
RenderViewport_t() : m_nVersion( RENDER_VIEWPORT_VERSION ) {}
void Init()
{
memset( this, 0, sizeof(RenderViewport_t) );
m_nVersion = RENDER_VIEWPORT_VERSION;
}
void Init( int x, int y, int nWidth, int nHeight, float flMinZ = 0.0f, float flMaxZ = 1.0f )
{
m_nVersion = RENDER_VIEWPORT_VERSION;
m_nTopLeftX = x; m_nTopLeftY = y; m_nWidth = nWidth; m_nHeight = nHeight;
m_flMinZ = flMinZ;
m_flMaxZ = flMaxZ;
}
};
// clear flags
enum RenderClearFlags_t
{
RENDER_CLEAR_FLAGS_CLEAR_DEPTH = 0x1,
RENDER_CLEAR_FLAGS_CLEAR_STENCIL = 0x2
};
enum StandardTextureID_t
{
STDTEXTURE_NORMAL_DEPTH_BUFFER = 0,
STDTEXTURE_LIGHTPASS_OUTPUT,
STDTEXTURE_NUMBER_OF_IDS
};
class CDisplayList // subclasses in devices
{
public:
CDisplayList *m_pNext;
};
//-----------------------------------------------------------------------------
// Data for the material system
//-----------------------------------------------------------------------------
#define RENDER_MATERIAL_NUM_WORLD_MATRICES 53
struct RenderMaterialData_t
{
int nMode;
float flTime;
float mWorldArray[ RENDER_MATERIAL_NUM_WORLD_MATRICES ][3][4];
VMatrix mView;
VMatrix mProjection;
VMatrix mVP;
VMatrix mWVP;
Vector vCameraPosition;
Vector vCameraForwardVec;
Vector vCameraUpVec;
float flNearPlane;
float flFarPlane;
float vViewportSize[2];
HRenderTexture customTextures[2];
void Init()
{
nMode = 0;
flTime = 0.0f;
float m4x3Identity[3][4] = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f };
for ( int i = 0; i < RENDER_MATERIAL_NUM_WORLD_MATRICES; i++ )
{
memcpy( mWorldArray[i], m4x3Identity, sizeof( m4x3Identity ) );
}
mView.Identity();
mProjection.Identity();
mVP.Identity();
mWVP.Identity();
vCameraPosition.Init( 0.0f, 0.0f, 0.0f );
vCameraForwardVec.Init( 0.0f, 0.0f, 0.0f );
vCameraUpVec.Init( 0.0f, 0.0f, 0.0f );
flNearPlane = 0.0f;
flFarPlane = 1.0f;
vViewportSize[0] = 0.0f;
vViewportSize[1] = 0.0f;
customTextures[0] = RENDER_TEXTURE_HANDLE_INVALID;
customTextures[1] = RENDER_TEXTURE_HANDLE_INVALID;
}
};
//-----------------------------------------------------------------------------
// Render context interface
//-----------------------------------------------------------------------------
abstract_class IRenderContext
{
// rendering functions. in flux
public:
virtual void SetSwapChain( SwapChainHandle_t hSwapChain ) = 0;
// Called when the context is handed to a thread.
virtual void AttachToCurrentThread() = 0;
virtual void Clear( const Vector4D &vecRGBAColor, int nFlags = 0 ) = 0; // any RENDER_CLEAR_FLAGS_CLEAR_xxx flags
virtual void SetViewports( int nCount, const RenderViewport_t* pViewports, bool setImmediately = false ) = 0;
virtual void GetViewport( RenderViewport_t *pViewport, int nViewport ) = 0;
// Restriction: This can only be called as the first call after a
// context is created, or the first call after a Submit.
virtual void BindRenderTargets( RenderTargetBinding_t hRenderTargetBinding ) = 0;
// set this to actually draw, and clear display list data
virtual void Submit( void ) =0;
// use this interface to finish a command list but not submit it until later. This call resets
// the rendercontext
virtual CDisplayList *DetachCommandList ( void ) =0;
// add items to the next submitted batches. Doing a submit resets this
virtual void DependsOn( CDependencyDescriptor *pDesc ) = 0;
virtual void Satisfies( CDependencyDescriptor *pDesc ) = 0;
// Creates/destroys vertex + index buffers
// For CreateDynamicIndexBuffer, nMaxInstanceCount == 0 means we don't expect
// the buffer to be used w/ instanced rendering.
// mNaxInstanceCount == INT_MAX means we have no idea how many instances will be rendered
virtual HRenderBuffer CreateDynamicVertexBuffer( const BufferDesc_t& desc ) = 0;
virtual void DestroyDynamicVertexBuffer( HRenderBuffer hVertexBuffer ) = 0;
virtual HRenderBuffer CreateDynamicIndexBuffer( const BufferDesc_t& desc, int nMaxInstanceCount = 0 ) = 0;
virtual void DestroyDynamicIndexBuffer( HRenderBuffer hIndexBuffer ) = 0;
// Use this to read or write buffers, whether lock is for read or write
// depends on the type of buffer (dynamic, staging, semistatic, etc)
virtual bool LockIndexBuffer( HRenderBuffer hIndexBuffer, int nMaxSizeInBytes, LockDesc_t *pDesc ) = 0;
virtual void UnlockIndexBuffer( HRenderBuffer hIndexBuffer, int nWrittenSizeInBytes, LockDesc_t *pDesc ) = 0;
virtual bool LockVertexBuffer( HRenderBuffer hVertexBuffer, int nMaxSizeInBytes, LockDesc_t *pDesc ) = 0;
virtual void UnlockVertexBuffer( HRenderBuffer hVertexBuffer, int nWrittenSizeInBytes, LockDesc_t *pDesc ) = 0;
// Binds an vertex/index buffer
virtual bool BindIndexBuffer( HRenderBuffer hIndexBuffer, int nOffset ) = 0;
virtual bool BindVertexBuffer( int nSlot, HRenderBuffer hVertexBuffer, int nOffset, int nStride = RENDER_BUFFER_STRIDE_INVALID ) = 0;
// Binds a vertex shader
virtual void BindVertexShader( RenderShaderHandle_t hVertexShader, RenderInputLayout_t hInputLayout ) = 0;
// Binds all other shader types
virtual void BindShader( RenderShaderType_t nType, RenderShaderHandle_t hShader ) = 0;
// textures
virtual void BindTexture( int nSamplerIndex, HRenderTexture hTexture, RenderShaderType_t nTargetPipelineStage = RENDER_PIXEL_SHADER ) = 0;
virtual void SetSamplerStatePS( int nSamplerIndex, RsFilter_t eFilterMode, RsTextureAddressMode_t eUWrapMode = RS_TEXTURE_ADDRESS_WRAP,
RsTextureAddressMode_t eVWrapMode = RS_TEXTURE_ADDRESS_WRAP, RsTextureAddressMode_t eWWrapMode = RS_TEXTURE_ADDRESS_WRAP,
RsComparison_t eTextureComparisonMode = RS_CMP_LESS ) = 0;
virtual void SetSamplerStateVS( int nSamplerIndex, RsFilter_t eFilterMode, RsTextureAddressMode_t eUWrapMode = RS_TEXTURE_ADDRESS_WRAP,
RsTextureAddressMode_t eVWrapMode = RS_TEXTURE_ADDRESS_WRAP, RsTextureAddressMode_t eWWrapMode = RS_TEXTURE_ADDRESS_WRAP,
RsComparison_t eTextureComparisonMode = RS_CMP_LESS ) = 0;
virtual void SetSamplerState( int32 nSamplerIndex, const CSamplerStateDesc *pSamplerDesc, RenderShaderType_t nTargetPipelineStage = RENDER_PIXEL_SHADER ) = 0;
// download data into a texture. It is acceptable to pass NULL for pData, in which case a d3d
// texture will be allocated and set up, but with unset bits (this is useful for getting a
// render target into memory for instance).
// NOTE: This doesn't work on file-backed textures
virtual void SetTextureData( HRenderTexture hTexture, const TextureDesc_t *pDataDesc, const void *pData, int nDataSize, bool bIsPreTiled, int nSpecificMipLevelToSet = -1, Rect_t const *pSubRectToUpdate = NULL ) = 0;
// Draws stuff!
// If nMaxVertexCount == 0, then calculate max vertex count from the size of the vertex buffer
virtual void Draw( RenderPrimitiveType_t type, int nFirstVertex, int nVertexCount ) = 0;
virtual void DrawInstanced( RenderPrimitiveType_t type, int nFirstVertex, int nVertexCountPerInstance, int nInstanceCount ) = 0;
virtual void DrawIndexed( RenderPrimitiveType_t type, int nFirstIndex, int nIndexCount, int nMaxVertexCount = 0 ) = 0;
virtual void DrawIndexedInstanced( RenderPrimitiveType_t type, int nFirstIndex, int nIndexCountPerInstance, int nInstanceCount, int nMaxVertexCount = 0 ) = 0;
// misc state setting
virtual void SetCullMode( RenderCullMode_t eCullMode ) = 0;
virtual void SetBlendMode( RenderBlendMode_t eBlendMode, float const *pBlendFactor = NULL ) = 0;
virtual void SetZBufferMode( RenderZBufferMode_t eZBufferMode ) = 0;
virtual RsRasterizerStateHandle_t FindOrCreateRasterizerState( const RsRasterizerStateDesc_t *pRsDesc ) = 0;
virtual void SetRasterizerState( RsRasterizerStateHandle_t rasterizerState ) = 0;
virtual RsDepthStencilStateHandle_t FindOrCreateDepthStencilState( const RsDepthStencilStateDesc_t *pRsDesc ) = 0;
virtual void SetDepthStencilState( RsDepthStencilStateHandle_t rasterizerState, uint32 nStencilRef = 0 ) = 0;
virtual RsBlendStateHandle_t FindOrCreateBlendState( const RsBlendStateDesc_t *pBlendDesc ) = 0;
virtual void SetBlendState( RsBlendStateHandle_t blendState, float const *pBlendFactor = NULL, uint32 nSampleMask = 0xFFFFFFFF ) = 0;
// set the data in a constant buffer
virtual void SetConstantBufferData( ConstantBufferHandle_t hConstantBuffer, void const *pData, int nDataSize ) = 0;
// bind constant buffers
virtual void BindConstantBuffer( RenderShaderType_t nType, ConstantBufferHandle_t hConstantBuffer, int nSlot, int nRegisterBaseForDx9 ) = 0;
// get access to per-frame pooled constant buffers.
virtual ConstantBufferHandle_t GetDynamicConstantBuffer( int nSize, void const *pData = NULL ) =0;
// Get the input layout associated with this renderbuffer. Returns RENDER_INPUT_LAYOUT_INVALID if none is associated.
virtual RenderInputLayout_t GetInputLayoutForVertexBuffer( HRenderBuffer hBuffer, InputLayoutVariation_t nVariation = INPUT_LAYOUT_VARIATION_DEFAULT ) = 0;
// Blocks the thread until the render thread completely empties
virtual void Flush() = 0;
// Forces a device lost
virtual void ForceDeviceLost() = 0;
// Returns the device associated w/ the context
virtual IRenderDevice *GetDevice() = 0;
// PIX events for debugging/perf analysis
virtual void BeginPixEvent( color32 c, const char *pEventName ) = 0;
virtual void EndPixEvent( ) = 0;
virtual void PixSetMarker( color32 c, const char *pEventName ) = 0;
// "standard" texture support.
virtual void BindStandardTexture( int nSamplerIndex, StandardTextureID_t nTextureID, RenderShaderType_t nTargetPipelineStage = RENDER_PIXEL_SHADER ) = 0;
virtual void SetStandardTexture( StandardTextureID_t nTextureID, HRenderTexture hTexture ) =0;
virtual HRenderTexture GetStandardTexture( StandardTextureID_t nTextureID ) =0;
// Material system data
virtual RenderMaterialData_t &GetMaterialData() = 0;
protected:
// Don't allow delete calls on an IRenderContext
virtual ~IRenderContext() {}
};
//-----------------------------------------------------------------------------
// simple helper class with all inlines
//-----------------------------------------------------------------------------
class CRenderContextPtr
{
public:
CRenderContextPtr( IRenderDevice *pDevice, RenderTargetBinding_t hRenderTargetBinding = RENDER_TARGET_BINDING_INVALID );
~CRenderContextPtr( void );
IRenderContext *operator->( void ) const;
operator IRenderContext*() const;
void Release( );
protected:
IRenderContext *m_pContext;
IRenderDevice *m_pDevice;
};
FORCEINLINE CRenderContextPtr::CRenderContextPtr( IRenderDevice *pDevice, RenderTargetBinding_t hRenderTargetBinding )
{
m_pDevice = pDevice;
m_pContext = pDevice->GetRenderContext( );
m_pContext->BindRenderTargets( hRenderTargetBinding );
}
FORCEINLINE CRenderContextPtr::~CRenderContextPtr( void )
{
Release();
}
FORCEINLINE void CRenderContextPtr::Release( )
{
if ( m_pContext )
{
m_pContext->Submit( );
m_pDevice->ReleaseRenderContext( m_pContext );
m_pContext = NULL;
m_pDevice = NULL;
}
}
// delegate to context via -> override
FORCEINLINE IRenderContext *CRenderContextPtr::operator->( void ) const
{
return m_pContext;
}
// Cast operator (to pass to other methods)
FORCEINLINE CRenderContextPtr::operator IRenderContext*() const
{
return m_pContext;
}
//-----------------------------------------------------------------------------
// Pix measurement helper class
//-----------------------------------------------------------------------------
class CRenderPixEvent
{
public:
CRenderPixEvent( IRenderContext *pRenderContext, color32 c, const char *pName )
{
m_pContext = pRenderContext;
m_pContext->BeginPixEvent( c, pName );
}
~CRenderPixEvent()
{
Release();
}
void Release()
{
if ( m_pContext )
{
m_pContext->EndPixEvent();
m_pContext = NULL;
}
}
private:
IRenderContext *m_pContext;
};
#endif // IRENDERCONTEXT_H