This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

349 lines
12 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
// Utility class for building command buffers into memory
//===========================================================================//
#ifndef COMMANDBUILDER_H
#define COMMANDBUILDER_H
#ifndef COMMANDBUFFER_H
#include "shaderapi/commandbuffer.h"
#endif
#include "BaseVSShader.h"
#include "shaderapi/ishaderapi.h"
#ifdef _WIN32
#pragma once
#endif
extern ConVar my_mat_fullbright;
template <int N>
class CFixedCommandStorageBuffer {
public:
uint8 m_Data[N];
uint8 *m_pDataOut;
#ifdef DBGFLAG_ASSERT
size_t m_nNumBytesRemaining;
#endif
FORCEINLINE CFixedCommandStorageBuffer(void) {
m_pDataOut = m_Data;
#ifdef DBGFLAG_ASSERT
m_nNumBytesRemaining = N;
#endif
}
FORCEINLINE void EnsureCapacity(size_t sz) {
Assert(m_nNumBytesRemaining >= sz);
}
template <class T>
FORCEINLINE void Put(T const &nValue) {
EnsureCapacity(sizeof(T));
*(reinterpret_cast<T *>(m_pDataOut)) = nValue;
m_pDataOut += sizeof(nValue);
#ifdef DBGFLAG_ASSERT
m_nNumBytesRemaining -= sizeof(nValue);
#endif
}
FORCEINLINE void PutInt(int nValue) { Put(nValue); }
FORCEINLINE void PutFloat(float nValue) { Put(nValue); }
FORCEINLINE void PutPtr(void *pPtr) { Put(pPtr); }
FORCEINLINE void PutMemory(const void *pMemory, size_t nBytes) {
EnsureCapacity(nBytes);
memcpy(m_pDataOut, pMemory, nBytes);
m_pDataOut += nBytes;
}
FORCEINLINE uint8 *Base(void) { return m_Data; }
FORCEINLINE void Reset(void) {
m_pDataOut = m_Data;
#ifdef DBGFLAG_ASSERT
m_nNumBytesRemaining = N;
#endif
}
FORCEINLINE size_t Size(void) const { return m_pDataOut - m_Data; }
};
template <class S>
class CCommandBufferBuilder {
public:
S m_Storage;
FORCEINLINE void End(void) { m_Storage.PutInt(CBCMD_END); }
FORCEINLINE IMaterialVar *Param(int nVar) const {
return CBaseShader::s_ppParams[nVar];
}
FORCEINLINE void SetPixelShaderConstants(int nFirstConstant,
int nConstants) {
m_Storage.PutInt(CBCMD_SET_PIXEL_SHADER_FLOAT_CONST);
m_Storage.PutInt(nFirstConstant);
m_Storage.PutInt(nConstants);
}
FORCEINLINE void OutputConstantData(float const *pSrcData) {
m_Storage.PutFloat(pSrcData[0]);
m_Storage.PutFloat(pSrcData[1]);
m_Storage.PutFloat(pSrcData[2]);
m_Storage.PutFloat(pSrcData[3]);
}
FORCEINLINE void OutputConstantData4(float flVal0, float flVal1,
float flVal2, float flVal3) {
m_Storage.PutFloat(flVal0);
m_Storage.PutFloat(flVal1);
m_Storage.PutFloat(flVal2);
m_Storage.PutFloat(flVal3);
}
FORCEINLINE void SetPixelShaderConstant(int nFirstConstant,
float const *pSrcData,
int nNumConstantsToSet) {
SetPixelShaderConstants(nFirstConstant, nNumConstantsToSet);
m_Storage.PutMemory(pSrcData, 4 * sizeof(float) * nNumConstantsToSet);
}
FORCEINLINE void SetPixelShaderConstant(int nFirstConstant, int nVar) {
SetPixelShaderConstant(nFirstConstant, Param(nVar)->GetVecValue());
}
void SetPixelShaderConstantGammaToLinear(int pixelReg, int constantVar) {
float val[4];
Param(constantVar)->GetVecValue(val, 3);
val[0] = val[0] > 1.0f ? val[0] : GammaToLinear(val[0]);
val[1] = val[1] > 1.0f ? val[1] : GammaToLinear(val[1]);
val[2] = val[2] > 1.0f ? val[2] : GammaToLinear(val[2]);
val[3] = 1.0;
SetPixelShaderConstant(pixelReg, val);
}
FORCEINLINE void SetPixelShaderConstant(int nFirstConstant,
float const *pSrcData) {
SetPixelShaderConstants(nFirstConstant, 1);
OutputConstantData(pSrcData);
}
FORCEINLINE void SetPixelShaderConstant4(int nFirstConstant, float flVal0,
float flVal1, float flVal2,
float flVal3) {
SetPixelShaderConstants(nFirstConstant, 1);
OutputConstantData4(flVal0, flVal1, flVal2, flVal3);
}
FORCEINLINE void SetPixelShaderConstant_W(int pixelReg, int constantVar,
float fWValue) {
if (constantVar != -1) {
float val[3];
Param(constantVar)->GetVecValue(val, 3);
SetPixelShaderConstant4(pixelReg, val[0], val[1], val[2], fWValue);
}
}
FORCEINLINE void SetVertexShaderConstant(int nFirstConstant,
float const *pSrcData) {
m_Storage.PutInt(CBCMD_SET_VERTEX_SHADER_FLOAT_CONST);
m_Storage.PutInt(nFirstConstant);
m_Storage.PutInt(1);
OutputConstantData(pSrcData);
}
FORCEINLINE void SetVertexShaderConstant(int nFirstConstant,
float const *pSrcData,
int nConsts) {
m_Storage.PutInt(CBCMD_SET_VERTEX_SHADER_FLOAT_CONST);
m_Storage.PutInt(nFirstConstant);
m_Storage.PutInt(nConsts);
m_Storage.PutMemory(pSrcData, 4 * nConsts * sizeof(float));
}
FORCEINLINE void SetVertexShaderConstant4(int nFirstConstant, float flVal0,
float flVal1, float flVal2,
float flVal3) {
m_Storage.PutInt(CBCMD_SET_VERTEX_SHADER_FLOAT_CONST);
m_Storage.PutInt(nFirstConstant);
m_Storage.PutInt(1);
m_Storage.PutFloat(flVal0);
m_Storage.PutFloat(flVal1);
m_Storage.PutFloat(flVal2);
m_Storage.PutFloat(flVal3);
}
void SetVertexShaderTextureTransform(int vertexReg, int transformVar) {
Vector4D transformation[2];
IMaterialVar *pTransformationVar = Param(transformVar);
if (pTransformationVar &&
(pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) {
const VMatrix &mat = pTransformationVar->GetMatrixValue();
transformation[0].Init(mat[0][0], mat[0][1], mat[0][2], mat[0][3]);
transformation[1].Init(mat[1][0], mat[1][1], mat[1][2], mat[1][3]);
} else {
transformation[0].Init(1.0f, 0.0f, 0.0f, 0.0f);
transformation[1].Init(0.0f, 1.0f, 0.0f, 0.0f);
}
SetVertexShaderConstant(vertexReg, transformation[0].Base(), 2);
}
void SetVertexShaderTextureScaledTransform(int vertexReg, int transformVar,
int scaleVar) {
Vector4D transformation[2];
IMaterialVar *pTransformationVar = Param(transformVar);
if (pTransformationVar &&
(pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) {
const VMatrix &mat = pTransformationVar->GetMatrixValue();
transformation[0].Init(mat[0][0], mat[0][1], mat[0][2], mat[0][3]);
transformation[1].Init(mat[1][0], mat[1][1], mat[1][2], mat[1][3]);
} else {
transformation[0].Init(1.0f, 0.0f, 0.0f, 0.0f);
transformation[1].Init(0.0f, 1.0f, 0.0f, 0.0f);
}
Vector2D scale(1, 1);
IMaterialVar *pScaleVar = Param(scaleVar);
if (pScaleVar) {
if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
pScaleVar->GetVecValue(scale.Base(), 2);
else if (pScaleVar->IsDefined())
scale[0] = scale[1] = pScaleVar->GetFloatValue();
}
// Apply the scaling
transformation[0][0] *= scale[0];
transformation[0][1] *= scale[1];
transformation[1][0] *= scale[0];
transformation[1][1] *= scale[1];
transformation[0][3] *= scale[0];
transformation[1][3] *= scale[1];
SetVertexShaderConstant(vertexReg, transformation[0].Base(), 2);
}
FORCEINLINE void SetEnvMapTintPixelShaderDynamicState(int pixelReg,
int tintVar) {
if (g_pConfig->bShowSpecular && my_mat_fullbright.GetInt() != 2) {
SetPixelShaderConstant(pixelReg, Param(tintVar)->GetVecValue());
} else {
SetPixelShaderConstant4(pixelReg, 0.0, 0.0, 0.0, 0.0);
}
}
FORCEINLINE void SetEnvMapTintPixelShaderDynamicStateGammaToLinear(
int pixelReg, int tintVar, float flAlphaValue = 1.0) {
if ((tintVar != -1) && g_pConfig->bShowSpecular &&
my_mat_fullbright.GetInt() != 2) {
float color[4];
color[3] = flAlphaValue;
Param(tintVar)->GetLinearVecValue(color, 3);
SetPixelShaderConstant(pixelReg, color);
} else {
SetPixelShaderConstant4(pixelReg, 0.0, 0.0, 0.0, flAlphaValue);
}
}
FORCEINLINE void StoreEyePosInPixelShaderConstant(int nConst) {
m_Storage.PutInt(CBCMD_STORE_EYE_POS_IN_PSCONST);
m_Storage.PutInt(nConst);
}
FORCEINLINE void CommitPixelShaderLighting(int nConst) {
m_Storage.PutInt(CBCMD_COMMITPIXELSHADERLIGHTING);
m_Storage.PutInt(nConst);
}
FORCEINLINE void SetPixelShaderStateAmbientLightCube(int nConst) {
m_Storage.PutInt(CBCMD_SETPIXELSHADERSTATEAMBIENTLIGHTCUBE);
m_Storage.PutInt(nConst);
}
FORCEINLINE void SetAmbientCubeDynamicStateVertexShader(void) {
m_Storage.PutInt(CBCMD_SETAMBIENTCUBEDYNAMICSTATEVERTEXSHADER);
}
FORCEINLINE void SetPixelShaderFogParams(int nReg) {
m_Storage.PutInt(CBCMD_SETPIXELSHADERFOGPARAMS);
m_Storage.PutInt(nReg);
}
FORCEINLINE void BindStandardTexture(Sampler_t nSampler,
StandardTextureId_t nTextureId) {
m_Storage.PutInt(CBCMD_BIND_STANDARD_TEXTURE);
m_Storage.PutInt(nSampler);
m_Storage.PutInt(nTextureId);
}
FORCEINLINE void BindTexture(Sampler_t nSampler,
ShaderAPITextureHandle_t hTexture) {
Assert(hTexture != INVALID_SHADERAPI_TEXTURE_HANDLE);
if (hTexture != INVALID_SHADERAPI_TEXTURE_HANDLE) {
m_Storage.PutInt(CBCMD_BIND_SHADERAPI_TEXTURE_HANDLE);
m_Storage.PutInt(nSampler);
m_Storage.PutInt(hTexture);
}
}
FORCEINLINE void BindTexture(CBaseVSShader *pShader, Sampler_t nSampler,
int nTextureVar, int nFrameVar) {
ShaderAPITextureHandle_t hTexture =
pShader->GetShaderAPITextureBindHandle(nTextureVar, nFrameVar);
BindTexture(nSampler, hTexture);
}
FORCEINLINE void BindMultiTexture(CBaseVSShader *pShader,
Sampler_t nSampler1, Sampler_t nSampler2,
int nTextureVar, int nFrameVar) {
ShaderAPITextureHandle_t hTexture =
pShader->GetShaderAPITextureBindHandle(nTextureVar, nFrameVar, 0);
BindTexture(nSampler1, hTexture);
hTexture =
pShader->GetShaderAPITextureBindHandle(nTextureVar, nFrameVar, 1);
BindTexture(nSampler2, hTexture);
}
FORCEINLINE void SetPixelShaderIndex(int nIndex) {
m_Storage.PutInt(CBCMD_SET_PSHINDEX);
m_Storage.PutInt(nIndex);
}
FORCEINLINE void SetVertexShaderIndex(int nIndex) {
m_Storage.PutInt(CBCMD_SET_VSHINDEX);
m_Storage.PutInt(nIndex);
}
FORCEINLINE void SetDepthFeatheringPixelShaderConstant(
int iConstant, float fDepthBlendScale) {
m_Storage.PutInt(CBCMD_SET_DEPTH_FEATHERING_CONST);
m_Storage.PutInt(iConstant);
m_Storage.PutFloat(fDepthBlendScale);
}
FORCEINLINE void Goto(uint8 *pCmdBuf) {
m_Storage.PutInt(CBCMD_JUMP);
m_Storage.PutPtr(pCmdBuf);
}
FORCEINLINE void Call(uint8 *pCmdBuf) {
m_Storage.PutInt(CBCMD_JSR);
m_Storage.PutPtr(pCmdBuf);
}
FORCEINLINE void Reset(void) { m_Storage.Reset(); }
FORCEINLINE size_t Size(void) const { return m_Storage.Size(); }
FORCEINLINE uint8 *Base(void) { return m_Storage.Base(); }
};
#endif // commandbuilder_h