Merge pull request #1760 from marauder2k9-torque/ShaderGen-produce-shaderdata

Shader Gen to produce ShaderData
This commit is contained in:
Brian Roberts 2026-06-07 18:23:21 -05:00 committed by GitHub
commit bac9ed99b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 477 additions and 128 deletions

View file

@ -681,6 +681,24 @@ bool GFXD3D11Shader::_init()
return true;
}
static String buildMacroHash(const D3D_SHADER_MACRO* defines)
{
String combined;
if (!defines)
return "";
for (const D3D_SHADER_MACRO* m = defines; m->Name != nullptr; ++m)
{
combined += m->Name;
combined += "=";
combined += m->Definition ? m->Definition : "";
combined += ";";
}
return Torque::getStringHash64(combined);
}
bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
GFXShaderStage shaderStage,
const D3D_SHADER_MACRO *defines)
@ -706,8 +724,40 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
Con::printf( "Compiling Shader: '%s'", filePath.getFullPath().c_str() );
#endif
String macroHash = buildMacroHash(defines);
Torque::Path cachePath = filePath;
cachePath.setExtension("tso");
cachePath.setFileName(cachePath.getFileName() + "_" + macroHash);
if (Torque::FS::IsFile(cachePath))
{
Torque::FS::FileNodeRef rawFile = Torque::FS::GetFileNode(filePath);
Torque::FS::FileNodeRef cachedFile = Torque::FS::GetFileNode(cachePath);
if (rawFile != NULL && cachedFile != NULL)
{
if (cachedFile->getModifiedTime() >= rawFile->getModifiedTime())
{
FileStream fs;
if (fs.open(cachePath, Torque::FS::File::Read))
{
U32 size = fs.getStreamSize();
D3DCreateBlob(size, &code);
fs.read(size, code->GetBufferPointer());
res = 1;
}
}
}
}
bool loadedFromCache = (code != NULL);
// Is it an HLSL shader?
if(filePath.getExtension().equal("hlsl", String::NoCase))
if(filePath.getExtension().equal("hlsl", String::NoCase) && !loadedFromCache)
{
// Set this so that the D3DInclude::Open will have this
// information for relative paths.
@ -788,6 +838,20 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
AssertISV(SUCCEEDED(res), "Unable to compile shader!");
// succeeded write out a cache
if (!loadedFromCache)
{
if (SUCCEEDED(res) && code)
{
// Save cache
FileStream out(FileStream::AsyncMode::Background);
if (out.open(cachePath, Torque::FS::File::Write))
{
out.write(code->GetBufferSize(), code->GetBufferPointer());
}
}
}
if(code != NULL)
{
switch (shaderStage)

View file

@ -542,6 +542,77 @@ bool GFXGLShader::_init()
macros.last().name = "TORQUE_VERTEX_SHADER";
macros.last().value = "";
Torque::Path cachePath = mVertexFile;
cachePath.setExtension("tso");
String macroHash;
GFXShaderMacro::stringize(macros, &macroHash);
macroHash = Torque::getStringHash64(macroHash);
String fileName = cachePath.getFileName();
if (!mVertexFile.isEmpty())
fileName += "_" + mVertexFile.getFileName();
if (!mPixelFile.isEmpty())
fileName += "_" + mPixelFile.getFileName();
if (!mGeometryFile.isEmpty())
fileName += "_" + mGeometryFile.getFileName();
fileName += "_" + macroHash;
cachePath.setFileName(fileName);
if (Torque::FS::IsFile(cachePath))
{
Torque::FS::FileNodeRef rawFile = Torque::FS::GetFileNode(mVertexFile);
Torque::FS::FileNodeRef cachedFile = Torque::FS::GetFileNode(cachePath);
if (rawFile != NULL && cachedFile != NULL)
{
if (cachedFile->getModifiedTime() >= rawFile->getModifiedTime())
{
FileStream fs;
if (fs.open(cachePath, Torque::FS::File::Read))
{
U32 size;
FrameAllocatorMarker bin;
GLenum gl_format;
fs.read(&gl_format);
fs.read(&size);
char* bin_data = (char*)bin.alloc(size);
fs.read(size, bin_data);
glProgramBinary(
mProgram,
gl_format,
bin_data,
size);
GLint linked;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
if (linked == GL_TRUE)
{
initConstantDescs();
initHandles();
// Notify Buffers we might have changed in size.
// If this was our first init then we won't have any activeBuffers
// to worry about unnecessarily calling.
Vector<GFXShaderConstBuffer*>::iterator biter = mActiveBuffers.begin();
for (; biter != mActiveBuffers.end(); biter++)
((GFXGLShaderConstBuffer*)(*biter))->onShaderReload(this);
return true;
}
}
}
}
}
// Default to true so we're "successful" if a vertex/pixel shader wasn't specified.
bool compiledVertexShader = true;
bool compiledPixelShader = true;
@ -659,6 +730,27 @@ bool GFXGLShader::_init()
if (linkStatus == GL_FALSE)
return false;
GLint binaryLength;
glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
if (binaryLength)
{
FrameAllocatorMarker bin;
char* bin_data = (char*)bin.alloc(binaryLength);
GLenum binaryFormat;
GLint length;
glGetProgramBinary(mProgram, binaryLength, &length, &binaryFormat, bin_data);
AssertWarn(length == binaryLength, "GFXGLShader: Binary length does not match");
FileStream out(FileStream::AsyncMode::Background);
if (out.open(cachePath, Torque::FS::File::Write))
{
out.write(binaryFormat);
out.write(length);
out.write(length, bin_data);
}
}
initConstantDescs();
initHandles();