This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions

View File

@@ -0,0 +1,106 @@
//===== Copyright <20> 1996-2007, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
// This file defines a number of constants and structured which are used to build up a command
// buffer to pass to ShaderAPI for state setting and other operations. Since the prupose of these
// command buffers is to minimize and optimize calls into shaderapi, their structure is not
// abstract - they are built out by the calling process.
//
//===========================================================================//
#ifndef COMMANDBUFFER_H
#define COMMANDBUFFER_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Commands used by the per-pass command buffers
//-----------------------------------------------------------------------------
enum CommandBufferCommand_t
{
// flow control commands.
CBCMD_END = 0, // end of stream
CBCMD_JUMP, // int cmd, void *adr. jump to another
// stream. Can be used to implement
// non-sequentially allocated storage
CBCMD_JSR, // int cmd, void *adr. subroutine call to another stream.
// constant setting commands
CBCMD_SET_PIXEL_SHADER_FLOAT_CONST, // int cmd,int first_reg, int nregs, float values[nregs*4]
CBCMD_SET_VERTEX_SHADER_FLOAT_CONST, // int cmd,int first_reg, int nregs, float values[nregs*4]
CBCMD_SET_VERTEX_SHADER_FLOAT_CONST_REF, // int cmd,int first_reg, int nregs, &float values[nregs*4]
CBCMD_SETPIXELSHADERFOGPARAMS, // int cmd, int regdest
CBCMD_STORE_EYE_POS_IN_PSCONST, // int cmd, int regdest
CBCMD_SET_DEPTH_FEATHERING_CONST, // int cmd, int constant register, float blend scale
// texture binding
CBCMD_BIND_STANDARD_TEXTURE, // cmd, sampler, texture id
CBCMD_BIND_SHADERAPI_TEXTURE_HANDLE, // cmd, sampler, texture handle
// shaders
CBCMD_SET_PSHINDEX, // cmd, idx
CBCMD_SET_VSHINDEX, // cmd, idx
CBCMD_SET_VERTEX_SHADER_FLASHLIGHT_STATE, // cmd, int first_reg (for worldToTexture matrix)
CBCMD_SET_PIXEL_SHADER_FLASHLIGHT_STATE, // cmd, int color reg, int atten reg, int origin reg, sampler (for flashlight texture)
CBCMD_SET_PIXEL_SHADER_UBERLIGHT_STATE, // cmd
CBCMD_SET_VERTEX_SHADER_NEARZFARZ_STATE, // cmd
};
//-----------------------------------------------------------------------------
// Commands used by the per-instance command buffer
// NOTE: If you add commands, you probably want to change the size of
// CInstanceStorageBuffer and/or the choice of making it a fixed-size allocation
// see shaderlib/baseshader.*
//
// FIXME!! NOTE that this whole scheme here generates a dependency of the
// shaders on internal guts of shaderapidx8, since it's responsible for
// setting various pixel shader + vertex shader constants based on the
// commands below. We need to remove this dependency as it's way too restrictive
// and puts the smarts in the wrong place (see CBICMD_SETPIXELSHADERGLINTDAMPING
// as an example). Not going to solve this for l4d though, as I don't anticipate
// a large amount of new shader writing for that product.
//-----------------------------------------------------------------------------
enum CommandBufferInstanceCommand_t
{
CBICMD_END = 0, // end of stream
CBICMD_JUMP, // int cmd, void *adr. jump to another
// stream. Can be used to implement
// non-sequentially allocated storage
CBICMD_JSR, // int cmd, void *adr. subroutine call to another stream.
CBICMD_SETSKINNINGMATRICES, // int cmd
CBICMD_SETVERTEXSHADERLOCALLIGHTING, // int cmd
CBICMD_SETPIXELSHADERLOCALLIGHTING, // int cmd, int regdest
CBICMD_SETVERTEXSHADERAMBIENTLIGHTCUBE, // int cmd
CBICMD_SETPIXELSHADERAMBIENTLIGHTCUBE, // int cmd, int regdest
CBICMD_SETPIXELSHADERAMBIENTLIGHTCUBELUMINANCE, // int cmd, int regdest
CBICMD_SETPIXELSHADERGLINTDAMPING, // int cmd, int regdest
CBICMD_BIND_ENV_CUBEMAP_TEXTURE, // cmd, sampler
CBICMD_SETMODULATIONPIXELSHADERDYNAMICSTATE,
CBICMD_SETMODULATIONPIXELSHADERDYNAMICSTATE_LINEARCOLORSPACE_LINEARSCALE, // int cmd, int constant register, Vector color2
CBICMD_SETMODULATIONPIXELSHADERDYNAMICSTATE_LINEARCOLORSPACE, // int cmd, int constant register, Vector color2
CBICMD_SETMODULATIONPIXELSHADERDYNAMICSTATE_LINEARSCALE, // int cmd, int constant register, Vector color2, float scale
CBICMD_SETMODULATIONVERTEXSHADERDYNAMICSTATE, // int cmd, int constant register, Vector color2
CBICMD_SETMODULATIONPIXELSHADERDYNAMICSTATE_IDENTITY, // int cmd, int constant register
CBICMD_SETMODULATIONVERTEXSHADERDYNAMICSTATE_LINEARSCALE, // int cmd, int constant register, Vector color2, float scale
// This must be last
CBICMD_COUNT,
};
#endif // COMMANDBUFFER_H

View File

@@ -0,0 +1,541 @@
//==== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======//
//
// Purpose:
//
//===========================================================================//
#ifndef INDEXDATA_H
#define INDEXDATA_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#include "rendersystem/irendercontext.h"
//-----------------------------------------------------------------------------
//
// Helper class used to define index buffers
//
//-----------------------------------------------------------------------------
template < class T > class CIndexData
{
public:
CIndexData( IRenderContext* pRenderContext, HRenderBuffer hIndexBuffer );
CIndexData( IRenderContext* pRenderContext, RenderBufferType_t nType, int nIndexCount, const char *pDebugName, const char *pBudgetGroup );
// This constructor is meant to be used with instance rendering.
// Passing in either 0 or INT_MAX here means the client code
// doesn't know how many instances will be rendered.
CIndexData( IRenderContext* pRenderContext, RenderBufferType_t nType, int nIndexCount, int nMaxInstanceCount, const char *pDebugName, const char *pBudgetGroup );
~CIndexData();
// Begins, ends modification of the index buffer (returns true if the lock succeeded)
// A lock may not succeed if there isn't enough room
// Passing in 0 locks the entire buffer
bool Lock( int nMaxIndexCount = 0 );
void Unlock();
// returns the number of indices
int IndexCount() const;
// returns the total # of indices in the entire buffer
int GetBufferIndexCount() const;
// Used to define the indices (only used if you aren't using primitives)
void Index( T nIndex );
// NOTE: This version is the one you really want to achieve write-combining;
// Write combining only works if you write in 4 bytes chunks.
void Index2( T nIndex1, T nIndex2 );
/*
void FastTriangle( T nStartVert );
void FastQuad( T nStartVert );
void FastPolygon( T nStartVert, int nEdgeCount );
void FastPolygonList( T nStartVert, int *pVertexCount, int polygonCount );
void FastIndexList( const T *pIndexList, T nStartVert, int indexCount );
*/
// Call this to detach ownership of the vertex buffer. Caller is responsible
// for deleting it now
HRenderBuffer TakeOwnership();
protected:
enum
{
BUFFER_OFFSET_UNINITIALIZED = 0xFFFFFFFF
};
void Init( IRenderContext* pRenderContext, RenderBufferType_t nType, int nIndexCount, int nMaxInstanceCount, const char *pDebugName, const char *pBudgetGroup );
void Release();
// Pointer to the memory we're writing
T* m_pMemory;
// The current index
int m_nIndexCount;
// Amount to increase the index count each time (0 if there was a lock failure)
int m_nIndexIncrement;
// The mesh we're modifying
IRenderContext* m_pRenderContext;
HRenderBuffer m_hIndexBuffer;
// Max number of indices
int m_nMaxIndexCount;
int m_nBufferIndexCount : 31;
int m_bShouldDeallocate : 1;
};
//-----------------------------------------------------------------------------
//
// Inline methods related to CIndexData
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
template< class T >
inline CIndexData<T>::CIndexData( IRenderContext* pRenderContext, HRenderBuffer hIndexBuffer )
{
m_pRenderContext = pRenderContext;
m_hIndexBuffer = hIndexBuffer;
m_bShouldDeallocate = false;
BufferDesc_t desc;
pRenderContext->GetDevice()->GetIndexBufferDesc( hIndexBuffer, &desc );
m_nBufferIndexCount = desc.m_nElementCount;
#ifdef _DEBUG
m_nIndexCount = 0;
m_nMaxIndexCount = 0;
m_pMemory = NULL;
m_nIndexIncrement = 0;
#endif
}
template< class T >
inline CIndexData<T>::CIndexData( IRenderContext* pRenderContext, RenderBufferType_t nType, int nIndexCount, const char *pDebugName, const char *pBudgetGroup )
{
Init( pRenderContext, nType, nIndexCount, 0, pDebugName, pBudgetGroup );
}
template< class T >
inline CIndexData<T>::CIndexData( IRenderContext* pRenderContext, RenderBufferType_t nType, int nIndexCount, int nMaxInstanceCount, const char *pDebugName, const char *pBudgetGroup )
{
if ( nMaxInstanceCount == 0 )
{
nMaxInstanceCount = INT_MAX;
}
Init( pRenderContext, nType, nIndexCount, nMaxInstanceCount, pDebugName, pBudgetGroup );
}
template< class T >
inline void CIndexData<T>::Init( IRenderContext* pRenderContext, RenderBufferType_t nType,
int nIndexCount, int nMaxInstanceCount, const char *pDebugName, const char *pBudgetGroup )
{
m_pRenderContext = pRenderContext;
BufferDesc_t indexDesc;
indexDesc.m_nElementSizeInBytes = sizeof(T);
indexDesc.m_nElementCount = nIndexCount;
indexDesc.m_pDebugName = pDebugName;
indexDesc.m_pBudgetGroupName = pBudgetGroup;
m_hIndexBuffer = pRenderContext->GetDevice()->CreateIndexBuffer( nType, indexDesc, nMaxInstanceCount );
m_nBufferIndexCount = nIndexCount;
m_bShouldDeallocate = true;
ResourceAddRef( m_hIndexBuffer );
#ifdef _DEBUG
m_nIndexCount = 0;
m_nMaxIndexCount = 0;
m_pMemory = NULL;
m_nIndexIncrement = 0;
#endif
}
template< class T >
inline CIndexData<T>::~CIndexData()
{
// If this assertion fails, you forgot to unlock
Assert( !m_pMemory );
Release();
}
//-----------------------------------------------------------------------------
// Release
//-----------------------------------------------------------------------------
template< class T >
void CIndexData<T>::Release()
{
if ( m_bShouldDeallocate && ( m_hIndexBuffer != RENDER_BUFFER_HANDLE_INVALID ) )
{
ResourceRelease( m_hIndexBuffer );
m_pRenderContext->GetDevice()->DestroyIndexBuffer( m_hIndexBuffer );
m_hIndexBuffer = RENDER_BUFFER_HANDLE_INVALID;
m_bShouldDeallocate = false;
}
}
//-----------------------------------------------------------------------------
// Call this to take ownership of the vertex buffer
//-----------------------------------------------------------------------------
template< class T >
inline HRenderBuffer CIndexData<T>::TakeOwnership()
{
if ( m_bShouldDeallocate )
{
ResourceRelease( m_hIndexBuffer );
}
m_bShouldDeallocate = false;
return m_hIndexBuffer;
}
//-----------------------------------------------------------------------------
// Returns the buffer vertex count
//-----------------------------------------------------------------------------
template< class T >
inline int CIndexData<T>::GetBufferIndexCount() const
{
return m_nBufferIndexCount;
}
//-----------------------------------------------------------------------------
// Begins, ends modification of the index buffer
//-----------------------------------------------------------------------------
template< class T >
inline bool CIndexData<T>::Lock( int nMaxIndexCount )
{
if ( nMaxIndexCount == 0 )
{
nMaxIndexCount = m_nBufferIndexCount;
}
// Lock the index buffer
LockDesc_t desc;
bool bOk = m_pRenderContext->LockIndexBuffer( m_hIndexBuffer, nMaxIndexCount * sizeof(T), &desc );
m_nIndexIncrement = bOk ? 1 : 0;
m_nMaxIndexCount = nMaxIndexCount * m_nIndexIncrement;
m_nIndexCount = 0;
m_pMemory = (T*)desc.m_pMemory;
return bOk;
}
template< class T >
inline void CIndexData<T>::Unlock()
{
LockDesc_t desc;
desc.m_pMemory = m_pMemory;
m_pRenderContext->UnlockIndexBuffer( m_hIndexBuffer, m_nIndexCount * sizeof(T), &desc );
#ifdef _DEBUG
m_nIndexCount = 0;
m_nMaxIndexCount = 0;
m_pMemory = 0;
m_nIndexIncrement = 0;
#endif
}
/*
//-----------------------------------------------------------------------------
// Binds this index buffer
//-----------------------------------------------------------------------------
inline void CIndexData<T>::Bind( IMatRenderContext *pContext )
{
pContext->BindIndexBuffer( m_pIndexBuffer, 0 );
}
*/
//-----------------------------------------------------------------------------
// returns the number of indices
//-----------------------------------------------------------------------------
template< class T >
inline int CIndexData<T>::IndexCount() const
{
return m_nIndexCount;
}
//-----------------------------------------------------------------------------
// Used to write data into the index buffer
//-----------------------------------------------------------------------------
template< class T >
inline void CIndexData<T>::Index( T nIndex )
{
// FIXME: Should we prevent use of this with T = uint16? (write-combining)
Assert( m_pMemory );
Assert( ( m_nIndexIncrement == 0 ) || ( m_nIndexCount < m_nMaxIndexCount ) );
m_pMemory[m_nIndexCount] = nIndex;
m_nIndexCount += m_nIndexIncrement;
}
//-----------------------------------------------------------------------------
// NOTE: This version is the one you really want to achieve write-combining;
// Write combining only works if you write in 4 bytes chunks.
//-----------------------------------------------------------------------------
template< >
inline void CIndexData<uint16>::Index2( uint16 nIndex1, uint16 nIndex2 )
{
Assert( m_pMemory );
Assert( ( m_nIndexIncrement == 0 ) || ( m_nIndexCount < m_nMaxIndexCount - 1 ) );
#ifndef _X360
uint32 nIndices = ( (uint32)nIndex1 ) | ( ( (uint32)nIndex2 ) << 16 );
#else
uint32 nIndices = ( (uint32)nIndex2 ) | ( ( (uint32)nIndex1 ) << 16 );
#endif
*(uint32*)( &m_pMemory[m_nIndexCount] ) = nIndices;
m_nIndexCount += m_nIndexIncrement + m_nIndexIncrement;
}
template< >
inline void CIndexData<uint32>::Index2( uint32 nIndex1, uint32 nIndex2 )
{
Assert( m_pMemory );
Assert( ( m_nIndexIncrement == 0 ) || ( m_nIndexCount < m_nMaxIndexCount - 1 ) );
m_pMemory[m_nIndexCount] = nIndex1;
m_pMemory[m_nIndexCount+1] = nIndex2;
m_nIndexCount += m_nIndexIncrement + m_nIndexIncrement;
}
template< class T >
inline void CIndexData<T>::Index2( T nIndex1, T nIndex2 )
{
COMPILE_TIME_ASSERT( 0 );
}
#if 0
template< class T >
inline void CIndexData<T>::FastTriangle( int startVert )
{
startVert += m_nIndexOffset;
m_pIndices[m_nCurrentIndex+0] = startVert;
m_pIndices[m_nCurrentIndex+1] = startVert + 1;
m_pIndices[m_nCurrentIndex+2] = startVert + 2;
AdvanceIndices(3);
}
template< class T >
inline void CIndexData<T>::FastQuad( int startVert )
{
startVert += m_nIndexOffset;
m_pIndices[m_nCurrentIndex+0] = startVert;
m_pIndices[m_nCurrentIndex+1] = startVert + 1;
m_pIndices[m_nCurrentIndex+2] = startVert + 2;
m_pIndices[m_nCurrentIndex+3] = startVert;
m_pIndices[m_nCurrentIndex+4] = startVert + 2;
m_pIndices[m_nCurrentIndex+5] = startVert + 3;
AdvanceIndices(6);
}
template< class T >
inline void CIndexData<T>::FastPolygon( int startVert, int triangleCount )
{
unsigned short *pIndex = &m_pIndices[m_nCurrentIndex];
startVert += m_nIndexOffset;
if ( !IsX360() )
{
// NOTE: IndexSize is 1 or 0 (0 for alt-tab)
// This prevents us from writing into bogus memory
Assert( m_nIndexSize == 0 || m_nIndexSize == 1 );
triangleCount *= m_nIndexSize;
}
for ( int v = 0; v < triangleCount; ++v )
{
*pIndex++ = startVert;
*pIndex++ = startVert + v + 1;
*pIndex++ = startVert + v + 2;
}
AdvanceIndices(triangleCount*3);
}
template< class T >
inline void CIndexData<T>::FastPolygonList( int startVert, int *pVertexCount, int polygonCount )
{
unsigned short *pIndex = &m_pIndices[m_nCurrentIndex];
startVert += m_nIndexOffset;
int indexOut = 0;
if ( !IsX360() )
{
// NOTE: IndexSize is 1 or 0 (0 for alt-tab)
// This prevents us from writing into bogus memory
Assert( m_nIndexSize == 0 || m_nIndexSize == 1 );
polygonCount *= m_nIndexSize;
}
for ( int i = 0; i < polygonCount; i++ )
{
int vertexCount = pVertexCount[i];
int triangleCount = vertexCount-2;
for ( int v = 0; v < triangleCount; ++v )
{
*pIndex++ = startVert;
*pIndex++ = startVert + v + 1;
*pIndex++ = startVert + v + 2;
}
startVert += vertexCount;
indexOut += triangleCount * 3;
}
AdvanceIndices(indexOut);
}
template< class T >
inline void CIndexData<T>::FastIndexList( const unsigned short *pIndexList, int startVert, int indexCount )
{
unsigned short *pIndexOut = &m_pIndices[m_nCurrentIndex];
startVert += m_nIndexOffset;
if ( !IsX360() )
{
// NOTE: IndexSize is 1 or 0 (0 for alt-tab)
// This prevents us from writing into bogus memory
Assert( m_nIndexSize == 0 || m_nIndexSize == 1 );
indexCount *= m_nIndexSize;
}
for ( int i = 0; i < indexCount; ++i )
{
pIndexOut[i] = startVert + pIndexList[i];
}
AdvanceIndices(indexCount);
}
#endif
//-----------------------------------------------------------------------------
// Dynamic index field creation
// NOTE: Draw call must occur prior to destruction of this class!
//-----------------------------------------------------------------------------
template< class T > class CDynamicIndexData : public CIndexData< T >
{
typedef CIndexData< T > BaseClass;
public:
CDynamicIndexData( IRenderContext* pRenderContext, int nIndexCount, const char *pDebugName, const char *pBudgetGroup );
// This constructor is meant to be used with instance rendering.
// Passing in either 0 or INT_MAX here means the client code
// doesn't know how many instances will be rendered.
CDynamicIndexData( IRenderContext* pRenderContext, int nIndexCount, int nMaxInstanceCount, const char *pDebugName, const char *pBudgetGroup );
~CDynamicIndexData();
void Release();
// Begins, ends modification of the vertex buffer (returns true if the lock succeeded)
// A lock may not succeed if there isn't enough room
bool Lock( );
// Binds the vb to a particular slot using a particular offset
void Bind( int nOffset );
private:
void Init( IRenderContext* pRenderContext, int nIndexCount, int nMaxInstanceCount, const char *pDebugName, const char *pBudgetGroup );
};
//-----------------------------------------------------------------------------
//
// Inline methods related to CDynamicIndexData
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
template< class T >
inline CDynamicIndexData<T>::CDynamicIndexData( IRenderContext* pRenderContext,
int nIndexCount, const char *pDebugName, const char *pBudgetGroup ) :
BaseClass( pRenderContext, RENDER_BUFFER_HANDLE_INVALID )
{
Init( pRenderContext, nIndexCount, 0, pDebugName, pBudgetGroup );
}
template< class T >
inline CDynamicIndexData<T>::CDynamicIndexData( IRenderContext* pRenderContext,
int nIndexCount, int nMaxInstanceCount, const char *pDebugName, const char *pBudgetGroup ) :
BaseClass( pRenderContext, RENDER_BUFFER_HANDLE_INVALID )
{
if ( nMaxInstanceCount == 0 )
{
nMaxInstanceCount = INT_MAX;
}
Init( pRenderContext, nIndexCount, nMaxInstanceCount, pDebugName, pBudgetGroup );
}
template< class T >
inline void CDynamicIndexData<T>::Init( IRenderContext* pRenderContext,
int nIndexCount, int nMaxInstanceCount, const char *pDebugName, const char *pBudgetGroup )
{
BufferDesc_t indexDesc;
indexDesc.m_nElementSizeInBytes = sizeof(T);
indexDesc.m_nElementCount = nIndexCount;
indexDesc.m_pDebugName = pDebugName;
indexDesc.m_pBudgetGroupName = pBudgetGroup;
this->m_hIndexBuffer = pRenderContext->CreateDynamicIndexBuffer( indexDesc, nMaxInstanceCount );
this->m_nBufferIndexCount = nIndexCount;
ResourceAddRef( m_hIndexBuffer );
}
template< class T >
inline CDynamicIndexData<T>::~CDynamicIndexData()
{
Release();
}
//-----------------------------------------------------------------------------
// Release
//-----------------------------------------------------------------------------
template< class T >
void CDynamicIndexData<T>::Release()
{
if ( this->m_hIndexBuffer != RENDER_BUFFER_HANDLE_INVALID )
{
this->m_pRenderContext->DestroyDynamicIndexBuffer( this->m_hIndexBuffer );
ResourceRelease( m_hIndexBuffer );
this->m_hIndexBuffer = RENDER_BUFFER_HANDLE_INVALID;
}
}
//-----------------------------------------------------------------------------
// Begins, ends modification of the buffer
//-----------------------------------------------------------------------------
template< class T >
inline bool CDynamicIndexData<T>::Lock( )
{
Assert( this->m_hIndexBuffer != RENDER_BUFFER_HANDLE_INVALID );
return BaseClass::Lock( );
}
//-----------------------------------------------------------------------------
// Binds the ib to a particular stream using a particular offset
//-----------------------------------------------------------------------------
template< class T >
inline void CDynamicIndexData<T>::Bind( int nOffset )
{
this->m_pRenderContext->BindIndexBuffer( this->m_hIndexBuffer, nOffset );
}
#endif // INDEXDATA_H

View File

@@ -0,0 +1,382 @@
//===== Copyright <20> 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

View File

@@ -0,0 +1,546 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef IRENDERDEVICE_H
#define IRENDERDEVICE_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/interface.h"
#include "appframework/iappsystem.h"
#include "bitmap/imageformat.h"
#include "tier1/utlbuffer.h"
#include "mathlib/vector4d.h"
#include "bitmap/colorformat.h"
#include "rendersystem/renderstate.h"
#include "resourcesystem/stronghandle.h"
#include "rendersystem/schema/texture.g.h"
#include "rendersystem/schema/renderbuffer.g.h"
#include "rendersystem/schema/renderable.g.h"
#include "tier0/platwindow.h"
//-----------------------------------------------------------------------------
// forward declarations
//-----------------------------------------------------------------------------
class KeyValues;
struct RenderInputLayoutField_t;
class IRenderContext;
struct Rect_t;
//-----------------------------------------------------------------------------
// turn this on to get logging
//----------------------------------------------------------------------------
//#define LOG_COMMAND_BUFFER_EXECUTE
//-----------------------------------------------------------------------------
// Adapter info
//-----------------------------------------------------------------------------
enum
{
RENDER_ADAPTER_NAME_LENGTH = 512
};
struct RenderAdapterInfo_t
{
char m_pDriverName[RENDER_ADAPTER_NAME_LENGTH];
unsigned int m_VendorID;
unsigned int m_DeviceID;
unsigned int m_SubSysID;
unsigned int m_Revision;
int m_nDXSupportLevel; // This is the *preferred* dx support level
int m_nMinDXSupportLevel;
int m_nMaxDXSupportLevel;
unsigned int m_nDriverVersionHigh;
unsigned int m_nDriverVersionLow;
};
//-----------------------------------------------------------------------------
// Flags to be used with the CreateDevice call
//-----------------------------------------------------------------------------
enum RenderCreateDeviceFlags_t
{
RENDER_CREATE_DEVICE_RESIZE_WINDOWS = 0x1,
};
//-----------------------------------------------------------------------------
// Describes how to set the mode
//-----------------------------------------------------------------------------
#define RENDER_DISPLAY_MODE_VERSION 1
struct RenderDisplayMode_t
{
RenderDisplayMode_t() { memset( this, 0, sizeof(RenderDisplayMode_t) ); m_nVersion = RENDER_DISPLAY_MODE_VERSION; }
int m_nVersion;
int m_nWidth; // 0 when running windowed means use desktop resolution
int m_nHeight;
ImageFormat m_Format; // use ImageFormats (ignored for windowed mode)
int m_nRefreshRateNumerator; // Refresh rate. Use 0 in numerator + denominator for a default setting.
int m_nRefreshRateDenominator; // Refresh rate = numerator / denominator.
};
//-----------------------------------------------------------------------------
// Describes how to set the device
//-----------------------------------------------------------------------------
#define RENDER_DEVICE_INFO_VERSION 1
struct RenderDeviceInfo_t
{
RenderDeviceInfo_t() { memset( this, 0, sizeof(RenderDeviceInfo_t) ); m_nVersion = RENDER_DEVICE_INFO_VERSION; m_DisplayMode.m_nVersion = RENDER_DISPLAY_MODE_VERSION; }
int m_nVersion;
RenderDisplayMode_t m_DisplayMode;
int m_nBackBufferCount; // valid values are 1 or 2 [2 results in triple buffering]
RenderMultisampleType_t m_nMultisampleType;
bool m_bFullscreen : 1;
bool m_bUseStencil : 1;
bool m_bWaitForVSync : 1; // Would we not present until vsync?
bool m_bScaleToOutputResolution : 1;// 360 ONLY: sets up hardware scaling
bool m_bProgressive : 1; // 360 ONLY: interlaced or progressive
bool m_bUsingMultipleWindows : 1; // Forces D3DPresent to use _COPY instead
};
//-----------------------------------------------------------------------------
// Vertex field description
//-----------------------------------------------------------------------------
enum
{
RENDER_INPUT_LAYOUT_FIELD_SEMANTIC_NAME_SIZE = 32,
};
struct RenderInputLayoutField_t
{
char m_pSemanticName[RENDER_INPUT_LAYOUT_FIELD_SEMANTIC_NAME_SIZE];
int m_nSemanticIndex;
ColorFormat_t m_Format;
int m_nOffset;
int m_nSlot;
RenderSlotType_t m_nSlotType;
int m_nInstanceStepRate;
};
#define DEFINE_PER_VERTEX_FIELD( _slot, _name, _index, _vertexformat, _field ) \
{ _name, _index, ComputeColorFormat( &(((_vertexformat*)0)->_field) ), offsetof( _vertexformat, _field ), _slot, RENDER_SLOT_PER_VERTEX, 0 },
#define DEFINE_PER_INSTANCE_FIELD( _slot, _stepRate, _name, _index, _vertexformat, _field ) \
{ _name, _index, ComputeColorFormat( &(((_vertexformat*)0)->_field) ), offsetof( _vertexformat, _field ), _slot, RENDER_SLOT_PER_INSTANCE, _stepRate },
//-----------------------------------------------------------------------------
// When we switch render target bindings, should we keep the contents?
//-----------------------------------------------------------------------------
enum RenderTargetBindingFlags_t
{
DISCARD_CONTENTS = 0x00,
PRESERVE_COLOR0 = 0x01, // corresponds to Render Target 0
PRESERVE_COLOR1 = 0x02, // corresponds to Render Target 1
PRESERVE_COLOR2 = 0x04,
PRESERVE_COLOR3 = 0x08,
PRESERVE_DEPTHSTENCIL = 0x10,
PRESERVE_CONTENTS = PRESERVE_COLOR0 | PRESERVE_COLOR1 | PRESERVE_COLOR2 | PRESERVE_COLOR3 | PRESERVE_DEPTHSTENCIL,
TILE_VERTICALLY = 0x20, // by default, we tile horizontally (splits are vertical)
};
//-----------------------------------------------------------------------------
// Variations on input layouts
// These are used to support various types of instancing
//-----------------------------------------------------------------------------
enum InputLayoutVariation_t
{
INPUT_LAYOUT_VARIATION_DEFAULT = 0x00,
INPUT_LAYOUT_VARIATION_STREAM1_MAT3X4,
INPUT_LAYOUT_VARIATION_STREAM1_MAT4X4,
INPUT_LAYOUT_VARIATION_MAX
};
//-----------------------------------------------------------------------------
// Handle to a vertex format
//-----------------------------------------------------------------------------
DECLARE_HANDLE_32BIT( RenderInputLayout_t );
#define RENDER_INPUT_LAYOUT_INVALID ( RenderInputLayout_t::MakeHandle( (uint32)~0 ) )
//-----------------------------------------------------------------------------
// Standard texture handles
//-----------------------------------------------------------------------------
#define RENDER_TEXTURE_DEFAULT_RENDER_TARGET ( (HRenderTexture)-1 )
//-----------------------------------------------------------------------------
// Handle to a render resource
//-----------------------------------------------------------------------------
DECLARE_POINTER_HANDLE( RenderResourceHandle_t );
#define RENDER_RESOURCE_HANDLE_INVALID ( (RenderResourceHandle_t)0 )
//-----------------------------------------------------------------------------
// Handle to a class that describes which render targets are in use
//-----------------------------------------------------------------------------
DECLARE_DERIVED_POINTER_HANDLE( RenderTargetBinding_t, RenderResourceHandle_t );
#define RENDER_TARGET_BINDING_INVALID ( (RenderTargetBinding_t)0 )
#define RENDER_TARGET_BINDING_BACK_BUFFER ( (RenderTargetBinding_t)-1 )
//-----------------------------------------------------------------------------
// Handle to a vertex, pixel, geometry, etc. shader
//-----------------------------------------------------------------------------
DECLARE_DERIVED_POINTER_HANDLE( RenderShaderHandle_t, RenderResourceHandle_t );
#define RENDER_SHADER_HANDLE_INVALID ( (RenderShaderHandle_t)0 )
enum RenderShaderType_t
{
RENDER_SHADER_TYPE_INVALID = -1,
RENDER_PIXEL_SHADER = 0,
RENDER_VERTEX_SHADER,
RENDER_GEOMETRY_SHADER,
RENDER_SHADER_TYPE_COUNT,
};
//-----------------------------------------------------------------------------
// Handle to a vertex buffer/indexbuffer
//-----------------------------------------------------------------------------
DECLARE_DERIVED_POINTER_HANDLE( VertexBufferHandle_t, RenderResourceHandle_t );
DECLARE_DERIVED_POINTER_HANDLE( IndexBufferHandle_t, RenderResourceHandle_t );
#define VERTEX_BUFFER_HANDLE_INVALID ( (VertexBufferHandle_t)0 )
#define INDEX_BUFFER_HANDLE_INVALID ( (IndexBufferHandle_t)0 )
//-----------------------------------------------------------------------------
// constant buffers
//-----------------------------------------------------------------------------
DECLARE_DERIVED_POINTER_HANDLE( ConstantBufferHandle_t, RenderResourceHandle_t );
#define CONSTANT_BUFFER_HANDLE_INVALID ( ( ConstantBufferHandle_t ) 0 )
//-----------------------------------------------------------------------------
// A shader buffer returns a block of memory which must be released when done with it
//-----------------------------------------------------------------------------
abstract_class IRenderShaderBuffer
{
public:
virtual size_t GetSize() const = 0;
virtual const void* GetBits() const = 0;
virtual void Release() = 0;
};
//-----------------------------------------------------------------------------
// Swap chain handle
//-----------------------------------------------------------------------------
DECLARE_POINTER_HANDLE( SwapChainHandle_t );
#define SWAP_CHAIN_HANDLE_INVALID ( (SwapChainHandle_t)0 )
//-----------------------------------------------------------------------------
// Mode change callback
//-----------------------------------------------------------------------------
typedef void (*RenderModeChangeCallbackFunc_t)( void );
//-----------------------------------------------------------------------------
// This is a little wacky. It's super convenient for app systems to be
// able to use the render device in their Init() blocks. This is tricky
// however because we don't have a great way of getting data to the
// devicemgr so it knows how to create the device. Specifically, we need to
// tell it which adapter to use, whether we're going to have resizing windows,
// and what window we're going to have 3D on (this is a dx9 restriction).
// So, we need to be able to run application code right after renderdevice init
// but before any other inits. The other alternative is for the application
// to send information to the render device mgr post connect but pre init.
// The first option is better because it lets the application do arbitrary
// stuff after it can query information about adapters, etc.
//-----------------------------------------------------------------------------
abstract_class IRenderDeviceSetup
{
public:
// This will be called by the render device mgr after it initializes itself
virtual bool CreateRenderDevice() = 0;
};
//-----------------------------------------------------------------------------
// Methods related to discovering and selecting devices
//-----------------------------------------------------------------------------
abstract_class IRenderDeviceMgr : public IAppSystem
{
public:
// Gets the number of adapters...
virtual int GetAdapterCount() const = 0;
// Returns info about each adapter
virtual void GetAdapterInfo( int nAdapter, RenderAdapterInfo_t& info ) const = 0;
// Gets recommended congifuration for a particular adapter at a particular dx level
virtual bool GetRecommendedConfigurationInfo( int nAdapter, int nDXLevel, KeyValues *pConfiguration ) = 0;
// Returns the number of modes
virtual int GetModeCount( int nAdapter ) const = 0;
// Returns mode information..
virtual void GetModeInfo( RenderDisplayMode_t* pInfo, int nAdapter, int nMode ) const = 0;
// Returns the current mode info for the requested adapter
virtual void GetCurrentModeInfo( RenderDisplayMode_t* pInfo, int nAdapter ) const = 0;
// Use the returned factory to get at an IRenderDevice and an IHardwareConfig
// and any other interfaces we decide to create.
// A returned factory of NULL indicates the device was not created properly.
virtual CreateInterfaceFn CreateDevice( int nAdapter, int nFlags, int nDXLevel = 0 ) = 0;
// Installs a callback to get called
virtual void AddModeChangeCallback( RenderModeChangeCallbackFunc_t func ) = 0;
virtual void RemoveModeChangeCallback( RenderModeChangeCallbackFunc_t func ) = 0;
virtual bool GetRecommendedVideoConfig( int nAdapter, KeyValues *pConfiguration ) = 0;
// Destroys the device
virtual void DestroyDevice() = 0;
// Method to allow callbacks to set up the device during init
// See big comment above IRenderDeviceSetup for why this is necessary
virtual void InstallRenderDeviceSetup( IRenderDeviceSetup *pSetup ) = 0;
};
//-----------------------------------------------------------------------------
// Data for vertex/index buffer creation
//-----------------------------------------------------------------------------
struct BufferDesc_t
{
int m_nElementCount; // Number of vertices/indices
int m_nElementSizeInBytes; // Size of a single vertex/index
const char * m_pDebugName; // Used to debug buffers
const char * m_pBudgetGroupName;
};
//-----------------------------------------------------------------------------
// Base class for abstract dependency class obtained and managed by the render device. These MUST
// be gotten from the device in order to be used in submits. Application code only needs to treat
// these as pointers/handles
//-----------------------------------------------------------------------------
class CDependencyDescriptor;
enum RenderSystemAssetFileLoadMode_t // controls behavior when rendersystem assets are created from files
{
LOADMODE_IMMEDIATE, // asset is created and loaded from disk immediately
LOADMODE_ASYNCHRONOUS, // asset will start loading asynchronously
LOADMODE_STREAMED, // asset will be asynchronously loaded when referenced.
};
//-----------------------------------------------------------------------------
// Methods related to control of the device
//-----------------------------------------------------------------------------
abstract_class IRenderDevice
{
public:
// Creates a 'swap chain' which represents a back buffer and a window.
// When present happens, you must pass it a swap chain handle.
virtual SwapChainHandle_t CreateSwapChain( PlatWindow_t hWnd, const RenderDeviceInfo_t &mode ) = 0;
virtual void DestroySwapChain( SwapChainHandle_t hSwapChain ) = 0;
virtual void UpdateSwapChain( SwapChainHandle_t hSwapChain, const RenderDeviceInfo_t &mode ) = 0;
virtual const RenderDeviceInfo_t &GetSwapChainInfo( SwapChainHandle_t hSwapChain ) const = 0;
// Returns the window associated with a swap chain
virtual PlatWindow_t GetSwapChainWindow( SwapChainHandle_t hSwapChain ) const = 0;
// Releases/reloads resources when other apps want some memory
virtual void ReleaseResources() = 0;
virtual void ReacquireResources() = 0;
// returns the backbuffer format and dimensions
virtual ImageFormat GetBackBufferFormat( SwapChainHandle_t hSwapChain ) const = 0;
virtual void GetBackBufferDimensions( SwapChainHandle_t hSwapChain, int *pWidth, int *pHeight ) const = 0;
// Returns the current adapter in use
virtual int GetCurrentAdapter() const = 0;
// Are we using graphics?
virtual bool IsUsingGraphics() const = 0;
// Use this to spew information about the 3D layer
virtual void SpewDriverInfo() const = 0;
// What's the bit depth of the stencil buffer?
virtual int StencilBufferBits() const = 0;
// Are we using a mode that uses MSAA
virtual bool IsAAEnabled() const = 0;
// Which version string should we use when compiling shaders
virtual const char *GetShaderVersionString( RenderShaderType_t nType ) const = 0;
// Does a page flip
virtual void Present( ) = 0;
// Gamma ramp control
virtual void SetHardwareGammaRamp( float fGamma, float fGammaTVRangeMin, float fGammaTVRangeMax, float fGammaTVExponent, bool bTVEnabled ) = 0;
// Shader compilation
virtual IRenderShaderBuffer* CompileShader( const char *pProgram, size_t nBufLen, const char *pShaderVersion ) = 0;
// Shader creation, destruction
virtual RenderShaderHandle_t CreateShader( RenderShaderType_t nType, IRenderShaderBuffer* pShaderBuffer ) = 0;
virtual void DestroyShader( RenderShaderType_t nType, RenderShaderHandle_t hShader ) = 0;
// Defines input layouts
virtual RenderInputLayout_t CreateInputLayout( const char *pLayoutName, int nFieldCount, const RenderInputLayoutField_t *pFieldDescs ) = 0;
virtual void DestroyInputLayout( RenderInputLayout_t hInputLayout ) = 0;
// Defines render target bind objects
// NOTE: Use RENDER_TARGET_BINDING_BACK_BUFFER for the back buffer
// Also note: If you need to re-use a buffer and render into it a second time,
// create a new render target binding to the same buffer. That will help sorting
virtual RenderTargetBinding_t CreateRenderTargetBinding( int nFlags, int nRenderTargetCount, const HRenderTexture *pRenderTargets, HRenderTexture hDepthStencilTexture ) = 0;
RenderTargetBinding_t CreateRenderTargetBinding( int nFlags, HRenderTexture hRenderTarget, HRenderTexture hDepthStencilTexture );
virtual void DestroyRenderTargetBinding( RenderTargetBinding_t hBinding ) = 0;
// Utility methods to make shader creation simpler
// NOTE: For the utlbuffer version, use a binary buffer for a compiled shader
// and a text buffer for a source-code (.fxc) shader
RenderShaderHandle_t CreateShader( RenderShaderType_t nType, const char *pProgram, size_t nBufLen, const char *pShaderVersion );
RenderShaderHandle_t CreateShader( RenderShaderType_t nType, CUtlBuffer &buf, const char *pShaderVersion = NULL );
RenderShaderHandle_t CreateShader( RenderShaderType_t nType, const void *pCompiledProgram, size_t nBufLen );
// Creates render state objects
virtual RsRasterizerStateHandle_t FindOrCreateRasterizerState( const RsRasterizerStateDesc_t *pRsDesc ) = 0;
virtual RsDepthStencilStateHandle_t FindOrCreateDepthStencilState( const RsDepthStencilStateDesc_t *pDsDesc ) = 0;
virtual RsBlendStateHandle_t FindOrCreateBlendState( const RsBlendStateDesc_t *pBlendDesc ) = 0;
// Creates/destroys vertex + index buffers
// For CreateIndexBuffer, 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 CreateRenderBuffer( const char *pGroupName, const char *pResourceName, const RenderBufferDesc_t *pDescriptor, size_t nDataSize ) = 0;
virtual void DestroyRenderBuffer( HRenderBuffer hBuffer ) = 0;
virtual HRenderBuffer CreateVertexBuffer( RenderBufferType_t nType, const BufferDesc_t& desc ) = 0;
virtual void DestroyVertexBuffer( HRenderBuffer hVertexBuffer ) = 0;
virtual HRenderBuffer CreateIndexBuffer( RenderBufferType_t nType, const BufferDesc_t& desc, int nMaxInstanceCount = 0 ) = 0;
virtual void DestroyIndexBuffer( HRenderBuffer hIndexBuffer ) = 0;
// Query buffer info
virtual void GetVertexBufferDesc( HRenderBuffer hVertexBuffer, BufferDesc_t *pDesc ) = 0;
virtual void GetIndexBufferDesc( HRenderBuffer hIndexBuffer, BufferDesc_t *pDesc ) = 0;
// textures
virtual HRenderTexture FindOrCreateTexture( const char *pGroupName, const char *pResourceName, const TextureHeader_t *pDescriptor ) = 0;
// manage file-backed textures.
virtual HRenderTexture FindOrCreateFileTexture( const char *pFileName, RenderSystemAssetFileLoadMode_t nLoadMode = LOADMODE_ASYNCHRONOUS ) = 0;
virtual HRenderTexture FindFileTexture( ResourceId_t nId, RenderSystemAssetFileLoadMode_t nLoadMode = LOADMODE_ASYNCHRONOUS ) = 0;
// Allows use of render contexts
virtual void EnableRenderContexts( bool bEnable ) = 0;
// render contexts
virtual IRenderContext *GetRenderContext( ) = 0;
virtual void ReleaseRenderContext( IRenderContext *pContext ) = 0;
// submitting pre-built display lists
virtual void SubmitDisplayList( class CDisplayList *pCommandList ) =0;
// there is no release. These are automatically released when satisfied, and as far as the client is concerned, they are all gone after Present().
virtual CDependencyDescriptor *GetDependencyDescriptor( int nNumBatchesWhichWillBeSubmitted = 1, char const *pDebugString = NULL ) =0;
// create/destroy constant buffers
virtual ConstantBufferHandle_t CreateConstantBuffer( size_t nNumBytes ) { return NULL; };
virtual void DestroyConstantBuffer( ConstantBufferHandle_t hConstantBuffer ) {};
// Forces a device lost
virtual void ForceDeviceLost() = 0;
// Reads the contents of a texture
virtual void ReadTexturePixels( HRenderTexture hTexture, Rect_t *pSrcRect, Rect_t *pDstRect, void *pData, ImageFormat dstFormat, int nDstStride ) = 0;
};
//-----------------------------------------------------------------------------
// Helper wrapper for IRenderShaderBuffer for reading precompiled shader files
// NOTE: This is meant to be instanced on the stack; so don't call Release!
//-----------------------------------------------------------------------------
class CUtlRenderShaderBuffer : public IRenderShaderBuffer
{
public:
CUtlRenderShaderBuffer( CUtlBuffer &buf ) : m_pBuf( &buf ) {}
virtual size_t GetSize() const
{
return m_pBuf->TellMaxPut();
}
virtual const void* GetBits() const
{
return m_pBuf->Base();
}
virtual void Release()
{
Assert( 0 );
}
private:
CUtlBuffer *m_pBuf;
};
//-----------------------------------------------------------------------------
// Inline methods of IRenderDevice
//-----------------------------------------------------------------------------
inline RenderTargetBinding_t IRenderDevice::CreateRenderTargetBinding( int nFlags, HRenderTexture hRenderTarget, HRenderTexture hDepthStencilTexture )
{
return CreateRenderTargetBinding( nFlags, 1, &hRenderTarget, hDepthStencilTexture );
}
inline RenderShaderHandle_t IRenderDevice::CreateShader( RenderShaderType_t nType, const char *pProgram, size_t nBufLen, const char *pShaderVersion )
{
RenderShaderHandle_t hShader = RENDER_SHADER_HANDLE_INVALID;
IRenderShaderBuffer* pShaderBuffer = CompileShader( pProgram, nBufLen, pShaderVersion );
if ( pShaderBuffer )
{
hShader = CreateShader( nType, pShaderBuffer );
pShaderBuffer->Release();
}
return hShader;
}
inline RenderShaderHandle_t IRenderDevice::CreateShader( RenderShaderType_t nType, CUtlBuffer &buf, const char *pShaderVersion )
{
// NOTE: Text buffers are assumed to have source-code shader files
// Binary buffers are assumed to have compiled shader files
if ( buf.IsText() )
{
Assert( pShaderVersion );
return CreateShader( nType, (const char *)buf.Base(), buf.TellMaxPut(), pShaderVersion );
}
CUtlRenderShaderBuffer shaderBuffer( buf );
return CreateShader( nType, &shaderBuffer );
}
inline RenderShaderHandle_t IRenderDevice::CreateShader( RenderShaderType_t nType, const void *pCompiledProgram, size_t nBufLen )
{
Assert( nBufLen == ( int )nBufLen ); // make sure we're not trimming 4Gb+ sizes
CUtlBuffer tmpBuf( pCompiledProgram, ( int )nBufLen, CUtlBuffer::READ_ONLY );
return CreateShader( nType, tmpBuf, NULL );
}
#endif // IRENDERDEVICE_H

View File

@@ -0,0 +1,132 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//===========================================================================//
#ifndef IRENDERHARDWARECONFIG_H
#define IRENDERHARDWARECONFIG_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/interface.h"
#include "bitmap/imageformat.h"
// use DEFCONFIGMETHOD to define time-critical methods that we want to make just return constants
// on the 360, so that the checks will happen at compile time. Not all methods are defined this way
// - just the ones that I perceive as being called often in the frame interval.
#ifdef _X360
#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) \
FORCEINLINE ret_type method const \
{ \
return xbox_return_value; \
}
#else
#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) \
virtual ret_type method const = 0;
#endif
//-----------------------------------------------------------------------------
// Render system configuration
//-----------------------------------------------------------------------------
class IRenderHardwareConfig
{
public:
virtual int GetFrameBufferColorDepth() const = 0;
virtual int GetSamplerCount() const = 0;
virtual bool HasSetDeviceGammaRamp() const = 0;
DEFCONFIGMETHOD( bool, SupportsNormalMapCompression(), true );
virtual int MaximumAnisotropicLevel() const = 0; // 0 means no anisotropic filtering
virtual int MaxTextureWidth() const = 0;
virtual int MaxTextureHeight() const = 0;
virtual int TextureMemorySize() const = 0;
virtual bool SupportsMipmappedCubemaps() const = 0;
virtual int NumVertexShaderConstants() const = 0;
virtual int NumPixelShaderConstants() const = 0;
virtual int MaxNumLights() const = 0;
virtual int MaxTextureAspectRatio() const = 0;
virtual int MaxVertexShaderBlendMatrices() const = 0;
virtual int MaxUserClipPlanes() const = 0;
virtual bool UseFastClipping() const = 0;
// This here should be the major item looked at when checking for compat
// from anywhere other than the material system shaders
DEFCONFIGMETHOD( int, GetDXSupportLevel(), 98 );
virtual const char *GetShaderDLLName() const = 0;
virtual bool ReadPixelsFromFrontBuffer() const = 0;
// Are dx dynamic textures preferred?
virtual bool PreferDynamicTextures() const = 0;
virtual bool NeedsAAClamp() const = 0;
virtual bool NeedsATICentroidHack() const = 0;
// This is the max dx support level supported by the card
virtual int GetMaxDXSupportLevel() const = 0;
// Does the card specify fog color in linear space when sRGBWrites are enabled?
virtual bool SpecifiesFogColorInLinearSpace() const = 0;
// Does the card support sRGB reads/writes?
DEFCONFIGMETHOD( bool, SupportsSRGB(), true );
virtual bool IsAAEnabled() const = 0; // Is antialiasing being used?
// NOTE: Anything after this was added after shipping HL2.
virtual int GetVertexTextureCount() const = 0;
virtual int GetMaxVertexTextureDimension() const = 0;
virtual int MaxTextureDepth() const = 0;
virtual bool SupportsStreamOffset() const = 0;
virtual int StencilBufferBits() const = 0;
virtual int MaxViewports() const = 0;
virtual void OverrideStreamOffsetSupport( bool bOverrideEnabled, bool bEnableSupport ) = 0;
virtual ShadowFilterMode_t GetShadowFilterMode( bool bForceLowQualityShadows, bool bPS30 ) const = 0;
virtual int NeedsShaderSRGBConversion() const = 0;
DEFCONFIGMETHOD( bool, UsesSRGBCorrectBlending(), true );
virtual bool HasFastVertexTextures() const = 0;
virtual int MaxHWMorphBatchCount() const = 0;
virtual bool SupportsBorderColor( void ) const = 0;
virtual bool SupportsFetch4( void ) const = 0;
virtual float GetShadowDepthBias() const = 0;
virtual float GetShadowSlopeScaleDepthBias() const = 0;
virtual bool PreferZPrepass() const = 0;
virtual bool SuppressPixelShaderCentroidHackFixup() const = 0;
virtual bool PreferTexturesInHWMemory() const = 0;
virtual bool PreferHardwareSync() const = 0;
virtual bool ActualHasFastVertexTextures() const = 0;
virtual bool SupportsShadowDepthTextures( void ) const = 0;
virtual ImageFormat GetShadowDepthTextureFormat( void ) const = 0;
virtual ImageFormat GetNullTextureFormat( void ) const = 0;
virtual int GetMinDXSupportLevel() const = 0;
virtual bool IsUnsupported() const = 0;
// Necessary on the 360 to improve performance of hierarchical Z
virtual bool ReverseDepth() const = 0;
};
#endif // IRENDERHARDWARECONFIG_H

View File

@@ -0,0 +1,35 @@
//===== Copyright <20> 1996-2007, Valve Corporation, All rights reserved. ======//
//
// Purpose: tracks VB allocations (and compressed/uncompressed vertex memory usage)
//
//===========================================================================//
#ifndef IVBALLOCTRACKER_H
#define IVBALLOCTRACKER_H
//#include "materialsystem/imaterialsystem.h"
// By default, only enable this alloc tracking for a debug shaderapidx*.dll
// (it uses about 0.25MB to track ~7000 allocations)
#if defined(_DEBUG)
#define ENABLE_VB_ALLOC_TRACKER 1
#else
#define ENABLE_VB_ALLOC_TRACKER 0
#endif
// This interface is actually exported by the shader API DLL.
#define VB_ALLOC_TRACKER_INTERFACE_VERSION "VBAllocTracker001"
// Interface to the VB mem alloc tracker
abstract_class IVBAllocTracker
{
public:
// This should be called wherever VertexBuffers are allocated
virtual void CountVB( void * buffer, bool isDynamic, int bufferSize, int vertexSize, VertexFormat_t fmt ) = 0;
// This should be called wherever VertexBuffers are freed
virtual void UnCountVB( void * buffer ) = 0;
// Track mesh allocations (set this before an allocation, clear it after)
virtual void TrackMeshAllocations( const char * allocatorName ) = 0;
};
#endif // IVBALLOCTRACKER_H

View File

@@ -0,0 +1,533 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: API-independent render state declarations
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef RENDERSTATE_H
#define RENDERSTATE_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/interface.h"
#include "tier1/generichash.h"
#include "basetypes.h"
#include "mathlib/mathlib.h"
//-----------------------------------------------------------------------------
// Handle to render state objects
//-----------------------------------------------------------------------------
DECLARE_POINTER_HANDLE( RsRasterizerStateHandle_t );
#define RENDER_RASTERIZER_STATE_HANDLE_INVALID ( (RsRasterizerStateHandle_t)0 )
DECLARE_POINTER_HANDLE( RsDepthStencilStateHandle_t );
#define RENDER_DEPTH_STENCIL_STATE_HANDLE_INVALID ( (RsDepthStencilStateHandle_t)0 )
DECLARE_POINTER_HANDLE( RsBlendStateHandle_t );
#define RENDER_BLEND_STATE_HANDLE_INVALID ( (RsBlendStateHandle_t)0 )
//-----------------------------------------------------------------------------
// Packs a float4 color to ARGB 8-bit int color compatible with D3D9
//-----------------------------------------------------------------------------
FORCEINLINE uint32 PackFloat4ColorToUInt32( float flR, float flG, float flB, float flA )
{
uint32 nR, nG, nB, nA;
nR = uint32( flR * 255.0f );
nG = uint32( flG * 255.0f );
nB = uint32( flB * 255.0f );
nA = uint32( flA * 255.0f );
return ( ( nA & 0xFF ) << 24 ) | ( ( nR & 0xFF ) << 16 ) | ( ( nG & 0xFF ) << 8 ) | ( ( nB & 0xFF ) );
}
//-----------------------------------------------------------------------------
// Packs a float4 color to ARGB 8-bit int color compatible with D3D9, clamping the floats to [0, 1]
//-----------------------------------------------------------------------------
FORCEINLINE uint32 ClampAndPackFloat4ColorToUInt32( float flR, float flG, float flB, float flA )
{
uint32 nR, nG, nB, nA;
nR = uint32( clamp( flR, 0.0f, 1.0f ) * 255.0f );
nG = uint32( clamp( flG, 0.0f, 1.0f ) * 255.0f );
nB = uint32( clamp( flB, 0.0f, 1.0f ) * 255.0f );
nA = uint32( clamp( flA, 0.0f, 1.0f ) * 255.0f );
return ( ( nA & 0xFF ) << 24 ) | ( ( nR & 0xFF ) << 16 ) | ( ( nG & 0xFF ) << 8 ) | ( ( nB & 0xFF ) );
}
//-----------------------------------------------------------------------------
// Unpacks an ARGB 8-bit int color to 4 floats
//-----------------------------------------------------------------------------
FORCEINLINE void UnpackUint32ColorToFloat4( uint32 nPackedColor, float* pflR, float* pflG, float* pflB, float* pflA )
{
uint32 nR, nG, nB, nA;
nR = ( nPackedColor >> 16 ) & 0xFF;
nG = ( nPackedColor >> 8 ) & 0xFF;
nB = ( nPackedColor ) & 0xFF;
nA = ( nPackedColor >> 24 ) & 0xFF;
*pflR = nR * 255.0f;
*pflG = nG * 255.0f;
*pflB = nB * 255.0f;
*pflA = nA * 255.0f;
}
enum RsCullMode_t
{
RS_CULL_NONE = 0,
RS_CULL_BACK = 1,
RS_CULL_FRONT = 2
};
enum RsFillMode_t
{
RS_FILL_SOLID = 0,
RS_FILL_WIREFRAME = 1
};
enum RsComparison_t
{
RS_CMP_NEVER = 0,
RS_CMP_LESS = 1,
RS_CMP_EQUAL = 2,
RS_CMP_LESS_EQUAL = 3,
RS_CMP_GREATER = 4,
RS_CMP_NOT_EQUAL = 5,
RS_CMP_GREATER_EQUAL = 6,
RS_CMP_ALWAYS = 7
};
enum RsStencilOp_t
{
RS_STENCIL_OP_KEEP = 0,
RS_STENCIL_OP_ZERO = 1,
RS_STENCIL_OP_REPLACE = 2,
RS_STENCIL_OP_INCR_SAT = 3,
RS_STENCIL_OP_DECR_SAT = 4,
RS_STENCIL_OP_INVERT = 5,
RS_STENCIL_OP_INCR = 6,
RS_STENCIL_OP_DECR = 7
};
enum RsHiStencilComparison360_t
{
RS_HI_STENCIL_CMP_EQUAL = 0,
RS_HI_STENCIL_CMP_NOT_EQUAL = 1
};
enum RsHiZMode360_t
{
RS_HI_Z_AUTOMATIC = 0,
RS_HI_Z_DISABLE = 1,
RS_HI_Z_ENABLE = 2
};
enum RsBlendOp_t
{
RS_BLEND_OP_ADD = 0,
RS_BLEND_OP_SUBTRACT = 1,
RS_BLEND_OP_REV_SUBTRACT = 2,
RS_BLEND_OP_MIN = 3,
RS_BLEND_OP_MAX = 4
};
enum RsBlendMode_t
{
RS_BLEND_MODE_ZERO = 0,
RS_BLEND_MODE_ONE = 1,
RS_BLEND_MODE_SRC_COLOR = 2,
RS_BLEND_MODE_INV_SRC_COLOR = 3,
RS_BLEND_MODE_SRC_ALPHA = 4,
RS_BLEND_MODE_INV_SRC_ALPHA = 5,
RS_BLEND_MODE_DEST_ALPHA = 6,
RS_BLEND_MODE_INV_DEST_ALPHA = 7,
RS_BLEND_MODE_DEST_COLOR = 8,
RS_BLEND_MODE_INV_DEST_COLOR = 9,
RS_BLEND_MODE_SRC_ALPHA_SAT = 10,
RS_BLEND_MODE_BLEND_FACTOR = 11,
RS_BLEND_MODE_INV_BLEND_FACTOR = 12
};
enum RsColorWriteEnableBits_t
{
RS_COLOR_WRITE_ENABLE_R = 0x1,
RS_COLOR_WRITE_ENABLE_G = 0x2,
RS_COLOR_WRITE_ENABLE_B = 0x4,
RS_COLOR_WRITE_ENABLE_A = 0x8,
RS_COLOR_WRITE_ENABLE_ALL = RS_COLOR_WRITE_ENABLE_R | RS_COLOR_WRITE_ENABLE_G | RS_COLOR_WRITE_ENABLE_B | RS_COLOR_WRITE_ENABLE_A
};
enum
{
RS_MAX_RENDER_TARGETS = 8
};
//-----------------------------------------------------------------------------
struct RsRasterizerStateDesc_t
{
RsFillMode_t m_nFillMode;
RsCullMode_t m_nCullMode;
bool m_bDepthClipEnable;
bool m_bMultisampleEnable;
int32 m_nDepthBias; // TODO: make this a float?
float32 m_flDepthBiasClamp;
float32 m_flSlopeScaledDepthBias;
/* Not exposing these DX11 states
BOOL FrontCounterClockwise;
BOOL ScissorEnable;
BOOL AntialiasedLineEnable;
This needs to be passed in explicitly when setting the blend state op:
uint32 multisamplemask;
*/
FORCEINLINE uint32 HashValue() const
{
// TODO: Optimize this
return HashItem( *this );
}
FORCEINLINE bool operator==( RsRasterizerStateDesc_t const &state ) const
{
return memcmp( this, &state, sizeof( RsRasterizerStateDesc_t ) ) == 0;
}
};
//-----------------------------------------------------------------------------
struct RsDepthStencilStateDesc_t
{
bool m_bDepthTestEnable;
bool m_bDepthWriteEnable;
RsComparison_t m_depthFunc;
RsHiZMode360_t m_hiZEnable360;
RsHiZMode360_t m_hiZWriteEnable360;
bool m_bStencilEnable;
uint8 m_nStencilReadMask;
uint8 m_nStencilWriteMask;
RsStencilOp_t m_frontStencilFailOp;
RsStencilOp_t m_frontStencilDepthFailOp;
RsStencilOp_t m_frontStencilPassOp;
RsComparison_t m_frontStencilFunc;
RsStencilOp_t m_backStencilFailOp;
RsStencilOp_t m_backStencilDepthFailOp;
RsStencilOp_t m_backStencilPassOp;
RsComparison_t m_backStencilFunc;
bool m_bHiStencilEnable360;
bool m_bHiStencilWriteEnable360;
RsHiStencilComparison360_t m_hiStencilFunc360;
uint8 m_nHiStencilRef360;
// Stencil ref not part of this, it's set explicitly when binding DS state block
// TODO: Figure out if I should pull the 360 HiStencil ref out too.
FORCEINLINE uint32 HashValue() const
{
// TODO: Optimize this
return HashItem( *this );
}
FORCEINLINE bool operator==( RsDepthStencilStateDesc_t const &state ) const
{
return memcmp( this, &state, sizeof( RsDepthStencilStateDesc_t ) ) == 0;
}
};
//-----------------------------------------------------------------------------
struct RsBlendStateDesc_t
{
bool m_bAlphaToCoverageEnable;
bool m_bIndependentBlendEnable;
bool m_bHighPrecisionBlendEnable360;
bool m_bBlendEnable[RS_MAX_RENDER_TARGETS];
RsBlendMode_t m_srcBlend[RS_MAX_RENDER_TARGETS];
RsBlendMode_t m_destBlend[RS_MAX_RENDER_TARGETS];
RsBlendOp_t m_blendOp[RS_MAX_RENDER_TARGETS];
RsBlendMode_t m_srcBlendAlpha[RS_MAX_RENDER_TARGETS];
RsBlendMode_t m_destBlendAlpha[RS_MAX_RENDER_TARGETS];
RsBlendOp_t m_blendOpAlpha[RS_MAX_RENDER_TARGETS];
uint8 m_nRenderTargetWriteMask[RS_MAX_RENDER_TARGETS];
FORCEINLINE uint32 HashValue() const
{
// TODO: Optimize this
return HashItem( *this );
}
FORCEINLINE bool operator==( RsBlendStateDesc_t const &state ) const
{
return memcmp( this, &state, sizeof( RsBlendStateDesc_t ) ) == 0;
}
};
enum RsFilter_t
{
RS_FILTER_MIN_MAG_MIP_POINT = 0,
RS_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x1,
RS_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x4,
RS_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x5,
RS_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10,
RS_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11,
RS_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14,
RS_FILTER_MIN_MAG_MIP_LINEAR = 0x15,
RS_FILTER_ANISOTROPIC = 0x55,
RS_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x80,
RS_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x81,
RS_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x84,
RS_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x85,
RS_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x90,
RS_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x91,
RS_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x94,
RS_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x95,
RS_FILTER_COMPARISON_ANISOTROPIC = 0xd5
};
enum RsFilterType_t
{
RS_FILTER_TYPE_POINT = 0,
RS_FILTER_TYPE_LINEAR = 1
};
FORCEINLINE RsFilter_t RsEncodeBasicTextureFilter( RsFilterType_t minFilter, RsFilterType_t magFilter, RsFilterType_t mipFilter, bool bComparison )
{
return static_cast< RsFilter_t >( ( bComparison ? 0x80 : 0 ) | ( ( minFilter & 0x3 ) << 4 ) | ( ( magFilter & 0x3 ) << 2 ) | ( mipFilter & 0x3 ) );
}
FORCEINLINE RsFilter_t RsEncodeAnisoTextureFilter( bool bComparison )
{
return RsEncodeBasicTextureFilter( RS_FILTER_TYPE_LINEAR, RS_FILTER_TYPE_LINEAR, RS_FILTER_TYPE_LINEAR, bComparison );
}
FORCEINLINE RsFilterType_t RsGetTextureMinFilterType( RsFilter_t filter )
{
return static_cast< RsFilterType_t >( 0x3 & ( filter >> 4 ) );
}
FORCEINLINE RsFilterType_t RsGetTextureMagFilterType( RsFilter_t filter )
{
return static_cast< RsFilterType_t >( 0x3 & ( filter >> 2 ) );
}
FORCEINLINE RsFilterType_t RsGetTextureMipFilterType( RsFilter_t filter )
{
return static_cast< RsFilterType_t >( 0x3 & filter );
}
FORCEINLINE bool RsIsComparisonTextureFilter( RsFilter_t filter )
{
return ( filter & 0x80 ) != 0;
}
FORCEINLINE bool RsIsAnisoTextureFilter( RsFilter_t filter )
{
return static_cast< RsFilter_t >( filter & ~0x80 ) == RS_FILTER_ANISOTROPIC;
}
enum RsTextureAddressMode_t
{
RS_TEXTURE_ADDRESS_WRAP = 0,
RS_TEXTURE_ADDRESS_MIRROR = 1,
RS_TEXTURE_ADDRESS_CLAMP = 2,
RS_TEXTURE_ADDRESS_BORDER = 3,
RS_TEXTURE_ADDRESS_MIRROR_ONCE = 4
};
//-----------------------------------------------------------------------------
class CSamplerStateDesc
{
public:
explicit CSamplerStateDesc( RsFilter_t filter = RS_FILTER_MIN_MAG_MIP_LINEAR,
RsTextureAddressMode_t addressU = RS_TEXTURE_ADDRESS_WRAP,
RsTextureAddressMode_t addressV = RS_TEXTURE_ADDRESS_WRAP,
RsTextureAddressMode_t addressW = RS_TEXTURE_ADDRESS_WRAP,
float32 flMipLodBias = 0.0f,
uint32 nMaxAniso = 16,
RsComparison_t comparisonFunc = RS_CMP_LESS,
uint32 nMinLod = 0,
uint32 nMaxLod = 16,
bool bSrgbFetch = false,
bool bFetch4 = false )
{
SetFilterMode( filter );
SetTextureAddressModeU( addressU );
SetTextureAddressModeV( addressU );
SetTextureAddressModeW( addressU );
SetMipLodBias( flMipLodBias );
SetMaxAnisotropy( nMaxAniso );
SetComparisonFunc( comparisonFunc );
SetMinMaxLod( nMinLod, nMaxLod );
SetSrgbFetchEnabled( bSrgbFetch );
SetFetch4Enabled( bFetch4 );
float32 flZeros[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
SetBorderColor( flZeros );
m_nPad = 0;
}
FORCEINLINE RsFilter_t GetFilterMode() const { return static_cast< RsFilter_t >( m_nFilterMode ); }
FORCEINLINE void SetFilterMode( RsFilter_t filter ) { m_nFilterMode = filter; }
FORCEINLINE RsTextureAddressMode_t GetTextureAddressModeU() const { return static_cast< RsTextureAddressMode_t >( m_nAddressU ); }
FORCEINLINE RsTextureAddressMode_t GetTextureAddressModeV() const { return static_cast< RsTextureAddressMode_t >( m_nAddressV ); }
FORCEINLINE RsTextureAddressMode_t GetTextureAddressModeW() const { return static_cast< RsTextureAddressMode_t >( m_nAddressW ); }
FORCEINLINE void SetTextureAddressModeU( RsTextureAddressMode_t addressMode ) { m_nAddressU = addressMode; }
FORCEINLINE void SetTextureAddressModeV( RsTextureAddressMode_t addressMode ) { m_nAddressV = addressMode; }
FORCEINLINE void SetTextureAddressModeW( RsTextureAddressMode_t addressMode ) { m_nAddressW = addressMode; }
FORCEINLINE float32 GetMipLodBias() const
{
return float32( m_nMipLodBias ) / 16.0f * ( m_nMipLodBiasSign ? -1.0f : 1.0f );
}
FORCEINLINE void SetMipLodBias( float32 flBias )
{
m_nMipLodBias = int( fabsf( flBias ) * 16.0f );
m_nMipLodBiasSign = ( flBias >= 0.0f ) ? 0 : 1;
}
FORCEINLINE uint32 GetMaxAnisotropy() const { return 1 << m_nAnisoExp; }
FORCEINLINE void SetMaxAnisotropy( uint32 nMaxAniso )
{
uint32 nAnisoExp = uint32( FastLog2( MAX( nMaxAniso, 1 ) ) );
m_nAnisoExp = MIN( nAnisoExp, 7 );
}
FORCEINLINE RsComparison_t GetComparisonFunc() const { return static_cast< RsComparison_t >( m_nComparisonFunc ); }
FORCEINLINE void SetComparisonFunc( RsComparison_t compFunc ) { m_nComparisonFunc = compFunc; }
FORCEINLINE void SetBorderColor( const float32 *pBorderColor )
{
m_nBorderColor8Bit = ClampAndPackFloat4ColorToUInt32( pBorderColor[0], pBorderColor[1], pBorderColor[2], pBorderColor[3] );
}
FORCEINLINE void GetBorderColor( float32 *pBorderColorOut ) const
{
UnpackUint32ColorToFloat4( m_nBorderColor8Bit, pBorderColorOut, pBorderColorOut + 1, pBorderColorOut + 2, pBorderColorOut + 3 );
}
FORCEINLINE uint32 GetBorderColor32Bit() const
{
return m_nBorderColor8Bit;
}
FORCEINLINE void GetMinMaxLod( uint32 *pMinLodOut, uint32 *pMaxLodOut ) const
{
*pMinLodOut = m_nMinLod;
*pMaxLodOut = m_nMaxLod;
}
FORCEINLINE uint32 GetMinLod() const
{
return m_nMinLod;
}
FORCEINLINE uint32 GetMaxLod() const
{
return m_nMaxLod;
}
FORCEINLINE void SetMinMaxLod( uint32 nMinLod, uint32 nMaxLod )
{
m_nMinLod = MIN( 15, nMinLod );
m_nMaxLod = MIN( 15, nMaxLod );
}
FORCEINLINE void SetMinLod( uint32 nMinLod )
{
m_nMinLod = MIN( 15, nMinLod );
}
FORCEINLINE void SetMaxLod( uint32 nMaxLod )
{
m_nMaxLod = MIN( 15, nMaxLod );
}
bool GetFetch4Enabled() const { return m_nFetch4Enable ? true : false; }
void SetFetch4Enabled( bool bEnable ) { m_nFetch4Enable = bEnable; }
bool GetSrgbFetchEnabled() const { return m_nSrgbFetchEnable ? true : false; }
void SetSrgbFetchEnabled( bool bEnable ) { m_nSrgbFetchEnable = bEnable; }
FORCEINLINE uint32 HashValue( void ) const
{
COMPILE_TIME_ASSERT( sizeof( CSamplerStateDesc ) == 12 );
return Hash12( this );
}
FORCEINLINE bool operator==( CSamplerStateDesc const &state ) const
{
return memcmp( this, &state, sizeof( CSamplerStateDesc ) ) == 0;
}
private:
// 32 bits
uint32 m_nFilterMode : 8;
uint32 m_nMipLodBias : 8; // 4.4 fixed point
uint32 m_nMipLodBiasSign : 1;
uint32 m_nAddressU : 3;
uint32 m_nAddressV : 3;
uint32 m_nAddressW : 3;
uint32 m_nAnisoExp : 3;
uint32 m_nComparisonFunc : 3;
// 32 bits
uint32 m_nBorderColor8Bit;
// 32 bits (18 bits available for extension
uint32 m_nMinLod : 6; // TODO: Either make them fixed-point, or kick them out of the state block alltogether
uint32 m_nMaxLod : 6;
uint32 m_nFetch4Enable : 1;
uint32 m_nSrgbFetchEnable : 1;
uint32 m_nPad : 18;
};
//-----------------------------------------------------------------------------
// Enums for builtin state objects
//-----------------------------------------------------------------------------
enum RenderCullMode_t
{
RENDER_CULLMODE_CULL_BACKFACING = 0, // this culls polygons with clockwise winding
RENDER_CULLMODE_CULL_FRONTFACING = 1, // this culls polygons with counterclockwise winding
RENDER_CULLMODE_CULL_NONE = 2, // no culling
};
enum RenderZBufferMode_t
{
RENDER_ZBUFFER_NONE = 0,
RENDER_ZBUFFER_ZTEST_AND_WRITE,
RENDER_ZBUFFER_ZTEST_NO_WRITE,
RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE,
RENDER_ZBUFFER_ZTEST_EQUAL_NO_WRITE,
// Stencil modes
RENDER_ZBUFFER_NONE_STENCIL_TEST_NOTEQUAL,
RENDER_ZBUFFER_ZTEST_AND_WRITE_STENCIL_SET1,
RENDER_ZBUFFER_ZTEST_NO_WRITE_STENCIL_TEST_NOTEQUAL_SET0,
RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE_STENCIL_TEST_NOTEQUAL_SET0,
RENDER_ZBUFFER_NUM_BUILTIN_MODES
};
enum RenderBlendMode_t
{
RENDER_BLEND_NONE = 0,
RENDER_BLEND_NOPIXELWRITE = 1,
RENDER_BLEND_RGBAPIXELWRITE,
RENDER_BLEND_ALPHABLENDING,
RENDER_BLEND_ADDITIVE_ON_ALPHA,
RENDER_NUM_BUILTIN_BLENDSTATES
};
#endif // RENDERSTATE_H

View File

@@ -0,0 +1,81 @@
#ifndef RENDERABLE_G_H
#define RENDERABLE_G_H
#ifdef COMPILER_MSVC
#pragma once
#endif
#include "resourcefile/resourcefile.h"
#include "resourcefile/resourcetype.h"
#include "renderbuffer.g.h"
//-----------------------------------------------------------------------------
// Enum definitions
//-----------------------------------------------------------------------------
enum RenderPrimitiveType_t
{
RENDER_PRIM_POINTS = 0,
RENDER_PRIM_LINES,
RENDER_PRIM_LINES_WITH_ADJACENCY,
RENDER_PRIM_LINE_STRIP,
RENDER_PRIM_LINE_STRIP_WITH_ADJACENCY,
RENDER_PRIM_TRIANGLES,
RENDER_PRIM_TRIANGLES_WITH_ADJACENCY,
RENDER_PRIM_TRIANGLE_STRIP,
RENDER_PRIM_TRIANGLE_STRIP_WITH_ADJACENCY,
RENDER_PRIM_INSTANCED_QUADS,
RENDER_PRIM_HETEROGENOUS,
RENDER_PRIM_TYPE_COUNT,
};
//-----------------------------------------------------------------------------
// Structure definitions
//-----------------------------------------------------------------------------
schema struct RenderBufferBinding_t
{
CResourceReference< RenderBufferBits_t > m_pRenderBuffer;
uint32 m_nBindOffsetBytes;
uint8 m_padding[4];
};
schema struct MaterialDrawDescriptor_t
{
int32 m_nBaseVertex;
int32 m_nVertexCount;
int32 m_nStartIndex;
int32 m_nIndexCount;
int32 m_nStartInstance;
int32 m_nInstanceCount;
uint8 m_nPrimitiveType; // See RenderPrimitiveType_t
uint8 m_padding[3];
CResourceArray< RenderBufferBinding_t > m_Buffers;
CResourceString m_pMaterialName;
//! opaquePointer
void *m_pMaterial;
};
schema struct PermRenderableBounds_t
{
Vector m_MinBounds;
Vector m_MaxBounds;
};
//! uncacheableStruct = PermRenderableBounds_t
schema struct Renderable_t
{
CResourceArray< MaterialDrawDescriptor_t > m_DrawCalls;
};
class CRenderable; // Forward declaration of associated runtime class
DEFINE_RESOURCE_CLASS_TYPE( Renderable_t, CRenderable, RESOURCE_TYPE_RENDERABLE );
typedef const ResourceBinding_t< CRenderable > *HRenderable;
typedef CStrongHandle< CRenderable > HRenderableStrong;
#define RENDERABLE_HANDLE_INVALID ( (HRenderable)0 )
#endif // RENDERABLE_G_H

View File

@@ -0,0 +1,91 @@
#ifndef RENDERBUFFER_G_H
#define RENDERBUFFER_G_H
#ifdef COMPILER_MSVC
#pragma once
#endif
#include "resourcefile/resourcefile.h"
#include "resourcefile/resourcetype.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct RenderInputLayoutField2_t;
struct RenderBufferDesc_t;
struct RenderBufferBits_t;
//-----------------------------------------------------------------------------
// Enum definitions
//-----------------------------------------------------------------------------
schema enum RenderBufferType_t
{
RENDER_BUFFER_TYPE_STATIC = 0, // GPU can read from it only, CPU can only write once
RENDER_BUFFER_TYPE_SEMISTATIC , // GPU can read, writes are infrequent from CPU
RENDER_BUFFER_TYPE_STAGING, // GPU can write, CPU can read
RENDER_BUFFER_TYPE_GPU_ONLY, // GPU can read/write, CPU cannot read/write (used for GPU-generated data)
RENDER_BUFFER_TYPE_COUNT,
RENDER_BUFFER_TYPE_COUNT_PLUS_1, // Ignore the man behind the curtain (used to silence a warning in rendersystem)
};
schema enum RenderBufferClass_t
{
RENDER_BUFFER_CLASS_VERTEX_BUFFER = 0,// (explicit)
RENDER_BUFFER_CLASS_INDEX_BUFFER,
RENDER_BUFFER_CLASS_RESERVED_VALUE_1, // These are for internal use only
RENDER_BUFFER_CLASS_RESERVED_VALUE_2,
};
schema enum RenderSlotType_t
{
RENDER_SLOT_INVALID = -1,
RENDER_SLOT_PER_VERTEX = 0,
RENDER_SLOT_PER_INSTANCE = 1,
};
schema enum MaxInputLayoutSemanticNameSize_t
{
RENDER_INPUT_LAYOUT_FIELD_SEMANTIC_NAME_SIZE2 = 32,
};
//-----------------------------------------------------------------------------
// Structure definitions
//-----------------------------------------------------------------------------
schema struct RenderInputLayoutField2_t
{
uint8 m_SemanticName[32];
int32 m_nSemanticIndex; // TODO: Change to ColorFormat_t and make bitmap/colorformat.h depend on ColorFormat.sch
int32 m_nFormat;
int32 m_nOffset;
int32 m_nSlot;
uint8 m_nSlotType; // See RenderSlotType_t
uint8 m_Padding[3];
int32 m_nInstanceStepRate;
};
schema struct RenderBufferDesc_t
{
int32 m_nElementCount;
uint16 m_nElementSizeInBytes; // Assume no single element is over 65k in size
uint8 m_nBufferType; // See RenderBufferType_t
uint8 m_nBufferClass; // See RenderBufferClass_t
CResourceArray< RenderInputLayoutField2_t > m_InputLayoutFields; // Unused for index buffers
};
//! uncacheableStruct = RenderBufferDesc_t
schema struct RenderBufferBits_t
{
// Empty like texture bits... Just a bag of bits with no reflection data...
};
class CRenderBufferBits; // Forward declaration of associated runtime class
DEFINE_RESOURCE_CLASS_TYPE( RenderBufferBits_t, CRenderBufferBits, RESOURCE_TYPE_RENDER_BUFFER );
typedef const ResourceBinding_t< CRenderBufferBits > *HRenderBuffer;
typedef CStrongHandle< CRenderBufferBits > HRenderBufferStrong;
#define RENDER_BUFFER_HANDLE_INVALID ( (HRenderBuffer)0 )
#endif // RENDERBUFFER_G_H

View File

@@ -0,0 +1,79 @@
#ifndef TEXTURE_G_H
#define TEXTURE_G_H
#ifdef COMPILER_MSVC
#pragma once
#endif
#include "resourcefile/resourcefile.h"
#include "resourcefile/resourcetype.h"
#include "mathlib/vector4d.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct TextureDesc_t;
struct TextureHeader_t;
struct TextureBits_t;
//-----------------------------------------------------------------------------
// Enum definitions
//-----------------------------------------------------------------------------
schema enum TextureSpecificationFlags_t
{
TSPEC_FLAGS = 0x0000,// (explicit)
TSPEC_RENDER_TARGET = 0x0001,// (explicit)
TSPEC_VERTEX_TEXTURE = 0x0002,// (explicit)
TSPEC_UNFILTERABLE_OK = 0x0004,// (explicit)
TSPEC_RENDER_TARGET_SAMPLEABLE = 0x0008,// (explicit)
TSPEC_SUGGEST_CLAMPS = 0x0010,
TSPEC_SUGGEST_CLAMPT = 0x0020,
TSPEC_SUGGEST_CLAMPU = 0x0040,
TSPEC_NO_LOD = 0x0080, // Don't downsample on lower-level cards
};
schema enum RenderMultisampleType_t
{
RENDER_MULTISAMPLE_INVALID = -1,// (explicit)
RENDER_MULTISAMPLE_NONE = 0,// (explicit)
RENDER_MULTISAMPLE_2X = 1,
RENDER_MULTISAMPLE_4X = 2,
RENDER_MULTISAMPLE_6X = 3,
RENDER_MULTISAMPLE_8X = 4,
RENDER_MULTISAMPLE_16X = 5,
};
//-----------------------------------------------------------------------------
// Structure definitions
//-----------------------------------------------------------------------------
schema struct TextureDesc_t
{
uint16 m_nWidth;
uint16 m_nHeight;
uint16 m_nDepth;
int8 m_nImageFormat;
uint8 m_nNumMipLevels;
};
schema struct TextureHeader_t : public TextureDesc_t
{
uint16 m_nMultisampleType; // See RenderMultisampleType_t
uint16 m_nFlags; // See TextureSpecificationFlags_t
Vector4D m_Reflectivity;
};
//! uncacheableStruct = TextureHeader_t
schema struct TextureBits_t
{
};
class CTextureBits; // Forward declaration of associated runtime class
DEFINE_RESOURCE_CLASS_TYPE( TextureBits_t, CTextureBits, RESOURCE_TYPE_TEXTURE );
typedef const ResourceBinding_t< CTextureBits > *HRenderTexture;
typedef CStrongHandle< CTextureBits > HRenderTextureStrong;
#define RENDER_TEXTURE_HANDLE_INVALID ( (HRenderTexture)0 )
#endif // TEXTURE_G_H

View File

@@ -0,0 +1,23 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef SHADERCONSTANTS_H
#define SHADERCONSTANTS_H
#ifdef COMPILER_MSVC
#pragma once
#endif
#include "tier0/platform.h"
enum RenderVertexShaderConstants_t
{
VSREG_INSTANCE_INDEX_COUNT = 255, // 360 only
};
#endif // SHADERCONSTANTS_H

View File

@@ -0,0 +1,444 @@
//==== Copyright <20> 1996-2008, Valve Corporation, All rights reserved. =======//
//
// Purpose:
//
//===========================================================================//
#ifndef VERTEXDATA_H
#define VERTEXDATA_H
#ifdef COMPILER_MSVC
#pragma once
#endif
#include "tier0/platform.h"
#include "rendersystem/irenderdevice.h"
//-----------------------------------------------------------------------------
// Vertex field creation
//-----------------------------------------------------------------------------
template< class T > class ALIGN16 CVertexData
{
public:
CVertexData( IRenderContext* pRenderContext, HRenderBuffer hVertexBuffer );
CVertexData( IRenderContext* pRenderContext, RenderBufferType_t nType, int nVertexCount, const char *pDebugName, const char *pBudgetGroup );
~CVertexData();
// Begins, ends modification of the vertex buffer (returns true if the lock succeeded)
// A lock may not succeed if there isn't enough room
bool Lock( int nMaxSizeInBytes = 0 );
void Unlock();
// returns the number of vertices
int VertexCount() const;
// returns the total # of vertices in the entire buffer
int GetBufferVertexCount() const;
// Call this to move forward a vertex
void AdvanceVertex();
IRenderContext *GetRenderContext() { return m_pRenderContext; }
// Call this to detach ownership of the vertex buffer. Caller is responsible
// for deleting it now
HRenderBuffer TakeOwnership();
// Allows us to iterate on this algorithm at a later date
FORCEINLINE T* operator->() { return &m_Scratch; }
FORCEINLINE const T* operator->() const { return &m_Scratch; }
protected:
enum
{
BUFFER_OFFSET_UNINITIALIZED = 0xFFFFFFFF
};
void Release();
// The temporary memory we're writing into
T m_Scratch;
// The mesh we're modifying
T* m_pMemory;
// The current vertex
int m_nVertexCount;
// Amount to increase the vertex count each time (0 if there was a lock failure)
int m_nVertexIncrement;
IRenderContext* m_pRenderContext;
HRenderBuffer m_hVertexBuffer;
int m_nMaxVertexCount;
int m_nBufferVertexCount : 31;
int m_bShouldDeallocate : 1;
};
//-----------------------------------------------------------------------------
//
// Inline methods related to CVertexData
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
template< class T >
inline CVertexData<T>::CVertexData( IRenderContext* pRenderContext, HRenderBuffer hVertexBuffer )
{
m_pRenderContext = pRenderContext;
m_hVertexBuffer = hVertexBuffer;
m_bShouldDeallocate = false;
BufferDesc_t desc;
pRenderContext->GetDevice()->GetVertexBufferDesc( hVertexBuffer, &desc );
m_nBufferVertexCount = desc.m_nElementCount;
#ifdef _DEBUG
// Initialize the vertex fields to NAN
memset( &m_Scratch, 0xFF, sizeof(m_Scratch) );
m_nVertexCount = 0;
m_nMaxVertexCount = 0;
m_pMemory = NULL;
m_nVertexIncrement = 0;
#endif
}
template< class T >
inline CVertexData<T>::CVertexData( IRenderContext* pRenderContext, RenderBufferType_t nType, int nVertexCount, const char *pDebugName, const char *pBudgetGroup )
{
m_pRenderContext = pRenderContext;
BufferDesc_t vertexDesc;
vertexDesc.m_nElementSizeInBytes = sizeof(T);
vertexDesc.m_nElementCount = nVertexCount;
vertexDesc.m_pDebugName = pDebugName;
vertexDesc.m_pBudgetGroupName = pBudgetGroup;
m_hVertexBuffer = pRenderContext->GetDevice()->CreateVertexBuffer( nType, vertexDesc );
m_nBufferVertexCount = nVertexCount;
m_bShouldDeallocate = true;
ResourceAddRef( m_hVertexBuffer );
#ifdef _DEBUG
// Initialize the vertex fields to NAN
memset( &m_Scratch, 0xFF, sizeof(m_Scratch) );
m_nVertexCount = 0;
m_nMaxVertexCount = 0;
m_pMemory = NULL;
m_nVertexIncrement = 0;
#endif
}
template< class T >
inline CVertexData<T>::~CVertexData()
{
// If this assertion fails, you forgot to unlock
Assert( !m_pMemory );
Release();
}
//-----------------------------------------------------------------------------
// Release
//-----------------------------------------------------------------------------
template< class T >
void CVertexData<T>::Release()
{
if ( m_bShouldDeallocate && ( m_hVertexBuffer != RENDER_BUFFER_HANDLE_INVALID ) )
{
ResourceRelease( m_hVertexBuffer );
m_pRenderContext->GetDevice()->DestroyVertexBuffer( m_hVertexBuffer );
m_hVertexBuffer = RENDER_BUFFER_HANDLE_INVALID;
m_bShouldDeallocate = false;
}
}
//-----------------------------------------------------------------------------
// Call this to take ownership of the vertex buffer
//-----------------------------------------------------------------------------
template< class T >
inline HRenderBuffer CVertexData<T>::TakeOwnership()
{
if ( m_bShouldDeallocate )
{
ResourceRelease( m_hVertexBuffer );
}
m_bShouldDeallocate = false;
return m_hVertexBuffer;
}
//-----------------------------------------------------------------------------
// Returns the buffer vertex count
//-----------------------------------------------------------------------------
template< class T >
inline int CVertexData<T>::GetBufferVertexCount() const
{
return m_nBufferVertexCount;
}
//-----------------------------------------------------------------------------
// Begins, ends modification of the vertex buffer
//-----------------------------------------------------------------------------
template< class T >
inline bool CVertexData<T>::Lock( int nMaxVertexCount )
{
if ( nMaxVertexCount == 0 )
{
nMaxVertexCount = m_nBufferVertexCount;
}
// Lock the vertex buffer
LockDesc_t desc;
bool bOk = m_pRenderContext->LockVertexBuffer( m_hVertexBuffer, nMaxVertexCount * sizeof(T), &desc );
m_nVertexIncrement = bOk ? 1 : 0;
m_nMaxVertexCount = nMaxVertexCount * m_nVertexIncrement;
m_nVertexCount = 0;
m_pMemory = (T*)desc.m_pMemory;
return bOk;
}
template< class T >
inline void CVertexData<T>::Unlock()
{
LockDesc_t desc;
desc.m_pMemory = m_pMemory;
m_pRenderContext->UnlockVertexBuffer( m_hVertexBuffer, m_nVertexCount * sizeof(T), &desc );
#ifdef _DEBUG
m_nVertexCount = 0;
m_nMaxVertexCount = 0;
m_pMemory = 0;
m_nVertexIncrement = 0;
#endif
}
//-----------------------------------------------------------------------------
// returns the number of vertices
//-----------------------------------------------------------------------------
template< class T >
inline int CVertexData<T>::VertexCount() const
{
return m_nVertexCount;
}
//-----------------------------------------------------------------------------
// NOTE: This version is the one you really want to achieve write-combining;
// Write combining only works if you write in 4 bytes chunks.
//-----------------------------------------------------------------------------
template< class T >
inline void CVertexData<T>::AdvanceVertex()
{
Assert( ( m_nVertexIncrement == 0 ) || ( m_nVertexCount < m_nMaxVertexCount ) );
T *pDest = &m_pMemory[ m_nVertexCount ];
T *pSrc = &m_Scratch;
#if defined( COMPILER_MSVC32 )
if ( sizeof(T) == 16 )
{
__asm
{
mov esi, pSrc
mov edi, pDest
movaps xmm0, [esi + 0]
movntps [edi + 0], xmm0
}
}
else if ( sizeof(T) == 32 )
{
__asm
{
mov esi, pSrc
mov edi, pDest
movaps xmm0, [esi + 0]
movaps xmm1, [esi + 16]
movntps [edi + 0], xmm0
movntps [edi + 16], xmm1
}
}
else if ( sizeof(T) == 48 )
{
__asm
{
mov esi, pSrc
mov edi, pDest
movaps xmm0, [esi + 0]
movaps xmm1, [esi + 16]
movaps xmm2, [esi + 32]
movntps [edi + 0], xmm0
movntps [edi + 16], xmm1
movntps [edi + 32], xmm2
}
}
else if ( sizeof(T) == 64 )
{
__asm
{
mov esi, pSrc
mov edi, pDest
movaps xmm0, [esi + 0]
movaps xmm1, [esi + 16]
movaps xmm2, [esi + 32]
movaps xmm3, [esi + 48]
movntps [edi + 0], xmm0
movntps [edi + 16], xmm1
movntps [edi + 32], xmm2
movntps [edi + 48], xmm3
}
}
else
#elif defined ( PLATFORM_X360 )
if ( sizeof(T) == 16 )
{
__vector4 v4Read = __lvx( pSrc, 0 );
__stvx( v4Read, pDest, 0 );
}
else if ( sizeof(T) == 32 )
{
__vector4 v4Read0 = __lvx( pSrc, 0 );
__vector4 v4Read1 = __lvx( pSrc, 16 );
__stvx( v4Read0, pDest, 0 );
__stvx( v4Read1, pDest, 16 );
}
else if ( sizeof(T) == 48 )
{
__vector4 v4Read0 = __lvx( pSrc, 0 );
__vector4 v4Read1 = __lvx( pSrc, 16 );
__vector4 v4Read2 = __lvx( pSrc, 32 );
__stvx( v4Read0, pDest, 0 );
__stvx( v4Read1, pDest, 16 );
__stvx( v4Read2, pDest, 32 );
}
else if ( sizeof(T) == 64 )
{
__vector4 v4Read0 = __lvx( pSrc, 0 );
__vector4 v4Read1 = __lvx( pSrc, 16 );
__vector4 v4Read2 = __lvx( pSrc, 32 );
__vector4 v4Read3 = __lvx( pSrc, 48 );
__stvx( v4Read0, pDest, 0 );
__stvx( v4Read1, pDest, 16 );
__stvx( v4Read2, pDest, 32 );
__stvx( v4Read3, pDest, 48 );
}
else
#endif
*pDest = *pSrc;
m_nVertexCount += m_nVertexIncrement;
}
//-----------------------------------------------------------------------------
// Dynamic vertex field creation
// NOTE: Draw call must occur prior to destruction of this class!
//-----------------------------------------------------------------------------
enum VertexDataStrideType_t
{
VD_STRIDE_ZERO = 0,
VD_STRIDE_DEFAULT,
};
template< class T > class ALIGN16 CDynamicVertexData : public CVertexData< T >
{
typedef CVertexData< T > BaseClass;
public:
CDynamicVertexData( IRenderContext* pRenderContext, int nVertexCount, const char *pDebugName, const char *pBudgetGroup );
~CDynamicVertexData();
void Release();
// Begins, ends modification of the vertex buffer (returns true if the lock succeeded)
// A lock may not succeed if there isn't enough room
bool Lock( );
// Binds the vb to a particular slot using a particular offset
void Bind( int nSlot, int nOffset, VertexDataStrideType_t nStride = VD_STRIDE_DEFAULT );
};
//-----------------------------------------------------------------------------
//
// Inline methods related to CDynamicVertexData
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
template< class T >
inline CDynamicVertexData<T>::CDynamicVertexData( IRenderContext* pRenderContext, int nVertexCount, const char *pDebugName, const char *pBudgetGroup ) :
BaseClass( pRenderContext, RENDER_BUFFER_HANDLE_INVALID )
{
BufferDesc_t vertexDesc;
vertexDesc.m_nElementSizeInBytes = sizeof(T);
vertexDesc.m_nElementCount = nVertexCount;
vertexDesc.m_pDebugName = pDebugName;
vertexDesc.m_pBudgetGroupName = pBudgetGroup;
this->m_hVertexBuffer = pRenderContext->CreateDynamicVertexBuffer( vertexDesc );
this->m_nBufferVertexCount = nVertexCount;
ResourceAddRef( this->m_hVertexBuffer );
}
template< class T >
inline CDynamicVertexData<T>::~CDynamicVertexData()
{
Release();
}
//-----------------------------------------------------------------------------
// Release
//-----------------------------------------------------------------------------
template< class T >
void CDynamicVertexData<T>::Release()
{
if ( this->m_hVertexBuffer != RENDER_BUFFER_HANDLE_INVALID )
{
this->m_pRenderContext->DestroyDynamicVertexBuffer( this->m_hVertexBuffer );
ResourceRelease( this->m_hVertexBuffer );
this->m_hVertexBuffer = RENDER_BUFFER_HANDLE_INVALID;
}
}
//-----------------------------------------------------------------------------
// Begins, ends modification of the buffer
//-----------------------------------------------------------------------------
template< class T >
inline bool CDynamicVertexData<T>::Lock( )
{
Assert( this->m_hVertexBuffer != RENDER_BUFFER_HANDLE_INVALID );
return BaseClass::Lock( );
}
//-----------------------------------------------------------------------------
// Binds the vb to a particular stream using a particular offset
//-----------------------------------------------------------------------------
template< class T >
inline void CDynamicVertexData<T>::Bind( int nSlot, int nOffset, VertexDataStrideType_t nStrideType )
{
int nStride = ( nStrideType == VD_STRIDE_DEFAULT ) ? sizeof( T ) : 0;
this->m_pRenderContext->BindVertexBuffer( nSlot, this->m_hVertexBuffer, nOffset, nStride );
}
#endif // VERTEXDATA_H