|
|
//===== 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
|