shaderc_spirv now emitting sampler uniforms

ShaderC now emits sampler uniforms for Metal and Spirv.
This commit is contained in:
Nick Waanders 2019-03-12 15:23:10 -07:00
parent 96ad5c3f30
commit 88da162438
1 changed files with 61 additions and 21 deletions

View File

@ -16,6 +16,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
#include <SPIRV/GlslangToSpv.h>
#define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
#include <spirv_msl.hpp>
#include <spirv_reflect.hpp>
#include <spirv-tools/optimizer.hpp>
BX_PRAGMA_DIAGNOSTIC_POP()
@ -583,6 +584,39 @@ namespace bgfx { namespace spirv
return bgfx::Attrib::Count;
}
static uint16_t writeUniformArray(bx::WriterI* _writer, const UniformArray& uniforms, bool isFragmentShader)
{
uint16_t size = 0;
uint16_t count = static_cast<uint16_t>(uniforms.size());
bx::write(_writer, count);
uint32_t fragmentBit = isFragmentShader ? BGFX_UNIFORM_FRAGMENTBIT : 0;
for (uint16_t ii = 0; ii < count; ++ii)
{
const Uniform& un = uniforms[ii];
size += un.regCount*16;
uint8_t nameSize = (uint8_t)un.name.size();
bx::write(_writer, nameSize);
bx::write(_writer, un.name.c_str(), nameSize);
bx::write(_writer, uint8_t(un.type | fragmentBit));
bx::write(_writer, un.num);
bx::write(_writer, un.regIndex);
bx::write(_writer, un.regCount);
BX_TRACE("%s, %s, %d, %d, %d"
, un.name.c_str()
, getUniformTypeName(un.type)
, un.num
, un.regIndex
, un.regCount
);
}
return size;
}
static bool compile(const Options& _options, uint32_t _version, const std::string& _code, bx::WriterI* _writer, bool _firstPass)
{
BX_UNUSED(_version);
@ -674,8 +708,6 @@ namespace bgfx { namespace spirv
}
else
{
uint16_t size = 0;
program->buildReflection();
if (_firstPass)
@ -733,11 +765,11 @@ namespace bgfx { namespace spirv
return compile(_options, _version, output.c_str(), _writer, false);
}
UniformArray uniforms;
{
uint16_t count = (uint16_t)program->getNumLiveUniformVariables();
bx::write(_writer, count);
uint32_t fragmentBit = _options.shaderType == 'f' ? BGFX_UNIFORM_FRAGMENTBIT : 0;
for (uint16_t ii = 0; ii < count; ++ii)
{
Uniform un;
@ -769,23 +801,7 @@ namespace bgfx { namespace spirv
break;
}
size += un.regCount*16;
uint8_t nameSize = (uint8_t)un.name.size();
bx::write(_writer, nameSize);
bx::write(_writer, un.name.c_str(), nameSize);
bx::write(_writer, uint8_t(un.type | fragmentBit));
bx::write(_writer, un.num);
bx::write(_writer, un.regIndex);
bx::write(_writer, un.regCount);
BX_TRACE("%s, %s, %d, %d, %d"
, un.name.c_str()
, getUniformTypeName(un.type)
, un.num
, un.regIndex
, un.regCount
);
uniforms.push_back(un);
}
}
if (g_verbose)
@ -823,6 +839,30 @@ namespace bgfx { namespace spirv
bx::MemoryReader reader(spirv.data(), uint32_t(spirv.size()*4) );
disassemble(writer, &reader, &err);
spirv_cross::CompilerReflection refl(spirv);
spirv_cross::ShaderResources resourcesrefl = refl.get_shader_resources();
// Loop through the separate_images, and extract the uniform names:
for (auto &resource : resourcesrefl.separate_images)
{
std::string name = refl.get_name(resource.id);
if (name.size() > 7 && 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") )
{
auto uniform_name = name.substr(0, name.length() - 7);
Uniform un;
un.name = uniform_name;
un.type = UniformType::Sampler;
un.num = 0; // needed?
un.regIndex = 0; // needed?
un.regCount = 0; // needed?
uniforms.push_back(un);
}
}
uint16_t size = writeUniformArray( _writer, uniforms, _options.shaderType == 'f');
if (_version == BX_MAKEFOURCC('M', 'T', 'L', 0))
{
if (g_verbose)