Vulkan cleanup for Webgpu (#2127)

* Harmonize and simplify Vulkan SPIRV bindings mappings

* Handle Vulkan V-flip properly

* Update Embedded shaders
This commit is contained in:
Hugo Amnov
2020-05-03 22:54:30 +02:00
committed by GitHub
parent f9b1a9f5d4
commit b48b084d25
55 changed files with 4717 additions and 4812 deletions

View File

@@ -567,39 +567,6 @@ namespace bgfx { namespace spirv
};
BX_STATIC_ASSERT(bgfx::Attrib::Count == BX_COUNTOF(s_attribName) );
int32_t extractStageNumber(const std::string _strLine)
{
bx::StringView found = bx::findIdentifierMatch(_strLine.c_str(), "register");
const char* ptr = found.getPtr() + found.getLength();
const char* start = NULL;
const char* end = NULL;
while (*ptr != ')'
&& ptr < _strLine.c_str() + _strLine.size() )
{
if (*ptr >= '0' && *ptr <= '9')
{
if (start == NULL)
{
start = ptr;
}
end = ptr;
}
ptr++;
}
BX_CHECK(start != NULL && end != NULL, "cannot find register number");
bx::StringView numberString(start, end - start + 1);
int32_t regNumber = -1;
bx::fromString(&regNumber, numberString);
BX_CHECK(regNumber >= 0, "register number should be semi-positive integer");
return regNumber;
}
bgfx::Attrib::Enum toAttribEnum(const bx::StringView& _name)
{
for (uint8_t ii = 0; ii < Attrib::Count; ++ii)
@@ -641,7 +608,7 @@ namespace bgfx { namespace spirv
{
const Uniform& un = uniforms[ii];
if (un.type != UniformType::Sampler)
if ((un.type & ~BGFX_UNIFORM_MASK) > UniformType::End)
size = bx::max(size, (uint16_t)(un.regIndex + un.regCount*16));
uint8_t nameSize = (uint8_t)un.name.size();
@@ -763,11 +730,18 @@ namespace bgfx { namespace spirv
{
program->buildReflection();
std::map<std::string, uint32_t> stageMap;
if (_firstPass)
{
// first time through, we just find unused uniforms and get rid of them
std::string output;
struct Uniform
{
std::string name;
std::string decl;
};
std::vector<Uniform> uniforms;
bx::Error err;
LineReader reader(_code.c_str() );
while (err.isOk() )
@@ -778,16 +752,23 @@ namespace bgfx { namespace spirv
{
std::string strLine(str, len);
bool moved = false;
size_t index = strLine.find("uniform ");
if (index != std::string::npos)
{
bool found = false;
bool sampler = false;
std::string name = "";
// add to samplers
for (uint32_t ii = 0; ii < BX_COUNTOF(s_samplerTypes); ++ii)
{
if (!bx::findIdentifierMatch(strLine.c_str(), s_samplerTypes[ii]).isEmpty())
{
found = true;
sampler = true;
break;
}
}
@@ -804,6 +785,7 @@ namespace bgfx { namespace spirv
if (!bx::findIdentifierMatch(strLine.c_str(), program->getUniformName(ii)).isEmpty())
{
found = true;
name = program->getUniformName(ii);
break;
}
}
@@ -811,118 +793,43 @@ namespace bgfx { namespace spirv
if (!found)
{
strLine = strLine.replace(index, 7 /* uniform */, "static");
strLine.replace(index, 7 /* uniform */, "static");
}
else if (!sampler)
{
Uniform uniform;
uniform.name = name;
uniform.decl = strLine;
uniforms.push_back(uniform);
moved = true;
}
}
output += strLine;
if (!moved)
output += strLine;
}
}
std::string uniformBlock;
uniformBlock += "cbuffer UniformBlock\n";
uniformBlock += "{\n";
for (const Uniform& uniform : uniforms)
{
uniformBlock += uniform.decl.substr(7 /* uniform */);
}
uniformBlock += "};\n";
output = uniformBlock + output;
//std::cout << "[debug] uniforms: " << std::endl << uniformBlock << std::endl;
// recompile with the unused uniforms converted to statics
return compile(_options, _version, output.c_str(), _writer, false);
}
else
{
// second time, find sampler state and get its stage index
bx::Error err;
LineReader reader(_code.c_str());
while (err.isOk())
{
char str[4096];
int32_t len = bx::read(&reader, str, BX_COUNTOF(str), &err);
if (err.isOk())
{
std::string strLine(str, len);
size_t index = strLine.find("uniform ");
if (index != std::string::npos)
{
if (!bx::findIdentifierMatch(strLine.c_str(), "SamplerState").isEmpty() ||
!bx::findIdentifierMatch(strLine.c_str(), "SamplerComparisonState").isEmpty())
{
int32_t regNumber = extractStageNumber(strLine);
bx::StringView found = bx::findIdentifierMatch(strLine.c_str(), "SamplerState");
if (found.isEmpty() )
{
found = bx::findIdentifierMatch(
strLine.c_str()
, "SamplerComparisonState"
);
}
const char* ptr = found.getPtr() + found.getLength();
const char* start = NULL;
const char* end = NULL;
while (ptr < strLine.c_str() + strLine.size())
{
if (*ptr != ' ')
{
if (start == NULL)
{
start = ptr;
}
end = ptr;
}
else if (start != NULL)
{
break;
}
ptr++;
}
BX_CHECK(start != NULL && end != NULL, "sampler name cannot be found");
std::string samplerName(start, end - start + 1);
stageMap[samplerName] = regNumber;
}
}
else if (!bx::findIdentifierMatch(strLine.c_str(), "StructuredBuffer").isEmpty()
|| !bx::findIdentifierMatch(strLine.c_str(), "RWStructuredBuffer").isEmpty() )
{
int32_t regNumber = extractStageNumber(strLine);
const char* ptr = strLine.c_str();
const char* start = NULL;
const char* end = NULL;
while (ptr < strLine.c_str() + strLine.size())
{
if (*ptr == '>')
{
start = ptr + 1;
while (*start == ' ')
{
start++;
}
}
if (*ptr == ':')
{
end = ptr - 1;
while (*end == ' ')
{
end--;
}
}
if (start != NULL && end != NULL)
{
break;
}
ptr++;
}
BX_CHECK(start != NULL && end != NULL, "sampler name cannot be found");
std::string bufferName(start, end - start + 1);
stageMap[bufferName] = regNumber;
}
}
}
// second time, do nothing (todo remove)
}
UniformArray uniforms;
@@ -1034,29 +941,14 @@ namespace bgfx { namespace spirv
Uniform un;
un.name = uniform_name;
un.type = UniformType::Sampler;
un.type = UniformType::Enum(BGFX_UNIFORM_SAMPLERBIT | UniformType::Sampler);
uint32_t texture_binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding);
uint32_t sampler_binding_index = 0;
std::string sampler_name;
const uint32_t binding = refl.get_decoration(resource.id, spv::DecorationBinding);
for (auto& sampler_resource : resourcesrefl.separate_samplers)
{
sampler_name = refl.get_name(sampler_resource.id);
if (sampler_name.size() > 7
&& !bx::strFind(sampler_name.c_str(), uniform_name.c_str()).isEmpty()
&& (0 == bx::strCmp(sampler_name.c_str() + name.length() - 7, "Sampler") ||
0 == bx::strCmp(sampler_name.c_str() + name.length() - 7, "SamplerComparison")
) )
{
sampler_binding_index = refl.get_decoration(sampler_resource.id, spv::Decoration::DecorationBinding);
break;
}
}
uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding);
un.num = stageMap[sampler_name]; // want to write stage index
un.regIndex = texture_binding_index; // for sampled image binding index
un.regCount = sampler_binding_index; // for sampler binding index
un.regIndex = binding_index;
un.regCount = 0; // unused
uniforms.push_back(un);
}
@@ -1077,9 +969,8 @@ namespace bgfx { namespace spirv
Uniform un;
un.name = uniform_name;
un.type = UniformType::End;
un.num = stageMap[sampler_name]; // want to write stage index
un.regIndex = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; // for descriptor type
un.regCount = binding_index; // for image binding index
un.regIndex = binding_index;
un.regCount = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; // for descriptor type
uniforms.push_back(un);
}
@@ -1097,9 +988,8 @@ namespace bgfx { namespace spirv
uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding);
uniform.name = name;
uniform.type = UniformType::End;
uniform.num = stageMap[name];
uniform.regIndex = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
uniform.regCount = binding_index;
uniform.regIndex = binding_index;
uniform.regCount = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
break;
}
}