mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-28 18:45:54 -05:00
Merge pull request #336 from MikePopoloski/master
Change shaderc to remove unused uniforms from DX11 shaders
This commit is contained in:
commit
eb9ec057f7
3 changed files with 86 additions and 43 deletions
|
@ -313,45 +313,6 @@ void strreplace(char* _str, const char* _find, const char* _replace)
|
|||
}
|
||||
}
|
||||
|
||||
class LineReader
|
||||
{
|
||||
public:
|
||||
LineReader(const char* _str)
|
||||
: m_str(_str)
|
||||
, m_pos(0)
|
||||
, m_size( (uint32_t)strlen(_str) )
|
||||
{
|
||||
}
|
||||
|
||||
std::string getLine()
|
||||
{
|
||||
const char* str = &m_str[m_pos];
|
||||
skipLine();
|
||||
|
||||
const char* eol = &m_str[m_pos];
|
||||
|
||||
std::string tmp;
|
||||
tmp.assign(str, eol-str);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool isEof() const
|
||||
{
|
||||
return m_str[m_pos] == '\0';
|
||||
}
|
||||
|
||||
void skipLine()
|
||||
{
|
||||
const char* str = &m_str[m_pos];
|
||||
const char* nl = bx::strnl(str);
|
||||
m_pos += (uint32_t)(nl - str);
|
||||
}
|
||||
|
||||
const char* m_str;
|
||||
uint32_t m_pos;
|
||||
uint32_t m_size;
|
||||
};
|
||||
|
||||
void printCode(const char* _code, int32_t _line, int32_t _start, int32_t _end)
|
||||
{
|
||||
fprintf(stderr, "Code:\n---\n");
|
||||
|
|
|
@ -61,6 +61,45 @@ extern bool g_verbose;
|
|||
#include <bx/hash.h>
|
||||
#include "../../src/vertexdecl.h"
|
||||
|
||||
class LineReader
|
||||
{
|
||||
public:
|
||||
LineReader(const char* _str)
|
||||
: m_str(_str)
|
||||
, m_pos(0)
|
||||
, m_size((uint32_t)strlen(_str))
|
||||
{
|
||||
}
|
||||
|
||||
std::string getLine()
|
||||
{
|
||||
const char* str = &m_str[m_pos];
|
||||
skipLine();
|
||||
|
||||
const char* eol = &m_str[m_pos];
|
||||
|
||||
std::string tmp;
|
||||
tmp.assign(str, eol - str);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool isEof() const
|
||||
{
|
||||
return m_str[m_pos] == '\0';
|
||||
}
|
||||
|
||||
void skipLine()
|
||||
{
|
||||
const char* str = &m_str[m_pos];
|
||||
const char* nl = bx::strnl(str);
|
||||
m_pos += (uint32_t)(nl - str);
|
||||
}
|
||||
|
||||
const char* m_str;
|
||||
uint32_t m_pos;
|
||||
uint32_t m_size;
|
||||
};
|
||||
|
||||
struct UniformType
|
||||
{
|
||||
enum Enum
|
||||
|
@ -102,7 +141,7 @@ void strreplace(char* _str, const char* _find, const char* _replace);
|
|||
int32_t writef(bx::WriterI* _writer, const char* _format, ...);
|
||||
void writeFile(const char* _filePath, const void* _data, int32_t _size);
|
||||
|
||||
bool compileHLSLShader(bx::CommandLine& _cmdLine, uint32_t _d3d, const std::string& _code, bx::WriterI* _writer);
|
||||
bool compileHLSLShader(bx::CommandLine& _cmdLine, uint32_t _d3d, const std::string& _code, bx::WriterI* _writer, bool firstPass = true);
|
||||
bool compileGLSLShader(bx::CommandLine& _cmdLine, uint32_t _gles, const std::string& _code, bx::WriterI* _writer);
|
||||
|
||||
#endif // SHADERC_H_HEADER_GUARD
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#if SHADERC_CONFIG_HLSL
|
||||
|
||||
#include <sstream>
|
||||
#include <d3dcompiler.h>
|
||||
#include <d3d11shader.h>
|
||||
|
||||
|
@ -143,6 +144,8 @@ static uint32_t s_optimizationLevelDx11[4] =
|
|||
D3DCOMPILE_OPTIMIZATION_LEVEL3,
|
||||
};
|
||||
|
||||
typedef std::vector<std::string> UniformNameList;
|
||||
|
||||
bool getReflectionDataDx9(ID3DBlob* _code, UniformArray& _uniforms)
|
||||
{
|
||||
// see reference for magic values: https://msdn.microsoft.com/en-us/library/ff552891(VS.85).aspx
|
||||
|
@ -243,7 +246,7 @@ bool getReflectionDataDx9(ID3DBlob* _code, UniformArray& _uniforms)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool getReflectionDataDx11(ID3DBlob* _code, bool _vshader, UniformArray& _uniforms, uint8_t& _numAttrs, uint16_t* _attrs, uint16_t& _size)
|
||||
bool getReflectionDataDx11(ID3DBlob* _code, bool _vshader, UniformArray& _uniforms, uint8_t& _numAttrs, uint16_t* _attrs, uint16_t& _size, UniformNameList& unusedUniforms)
|
||||
{
|
||||
ID3D11ShaderReflection* reflect = NULL;
|
||||
HRESULT hr = D3DReflect(_code->GetBufferPointer()
|
||||
|
@ -355,6 +358,9 @@ bool getReflectionDataDx11(ID3DBlob* _code, bool _vshader, UniformArray& _unifor
|
|||
}
|
||||
else
|
||||
{
|
||||
if (0 == (varDesc.uFlags & D3D_SVF_USED))
|
||||
unusedUniforms.push_back(varDesc.Name);
|
||||
|
||||
BX_TRACE("\t%s, unknown type", varDesc.Name);
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +397,7 @@ bool getReflectionDataDx11(ID3DBlob* _code, bool _vshader, UniformArray& _unifor
|
|||
return true;
|
||||
}
|
||||
|
||||
bool compileHLSLShader(bx::CommandLine& _cmdLine, uint32_t _d3d, const std::string& _code, bx::WriterI* _writer)
|
||||
bool compileHLSLShader(bx::CommandLine& _cmdLine, uint32_t _d3d, const std::string& _code, bx::WriterI* _writer, bool firstPass)
|
||||
{
|
||||
BX_TRACE("DX11");
|
||||
|
||||
|
@ -495,8 +501,45 @@ bool compileHLSLShader(bx::CommandLine& _cmdLine, uint32_t _d3d, const std::stri
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!getReflectionDataDx11(code, profile[0] == 'v', uniforms, numAttrs, attrs, size) )
|
||||
UniformNameList unusedUniforms;
|
||||
if (!getReflectionDataDx11(code, profile[0] == 'v', uniforms, numAttrs, attrs, size, unusedUniforms) )
|
||||
return false;
|
||||
|
||||
if (firstPass && unusedUniforms.size() > 0)
|
||||
{
|
||||
const size_t strLength = strlen("uniform");
|
||||
|
||||
// first time through, we just find unused uniforms and get rid of them
|
||||
std::stringstream output;
|
||||
LineReader reader(_code.c_str());
|
||||
while (!reader.isEof() )
|
||||
{
|
||||
std::string line = reader.getLine();
|
||||
for (UniformNameList::const_iterator it = unusedUniforms.begin(); it != unusedUniforms.end(); ++it)
|
||||
{
|
||||
size_t index = line.find("uniform ");
|
||||
if (index == std::string::npos)
|
||||
continue;
|
||||
|
||||
// matching lines like: uniform u_name;
|
||||
// we want to replace "uniform" with "static" so that it's no longer
|
||||
// included in the uniform blob that the application must upload
|
||||
// we can't just remove them, because unused functions might still reference
|
||||
// them and cause a compile error when they're gone
|
||||
if (line.find(*it) != std::string::npos)
|
||||
{
|
||||
line = line.replace(index, strLength, "static");
|
||||
unusedUniforms.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
output << line;
|
||||
}
|
||||
|
||||
// recompile with the unused uniforms converted to statics
|
||||
return compileHLSLShader(_cmdLine, _d3d, output.str(), _writer, false);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t count = (uint16_t)uniforms.size();
|
||||
|
|
Loading…
Reference in a new issue