|
|
@@ -30,6 +30,7 @@ ShaderProgramResource2::ShaderProgramResource2(ResourceManager* manager)
|
|
|
ShaderProgramResource2::~ShaderProgramResource2()
|
|
|
{
|
|
|
m_mutators.destroy(getAllocator());
|
|
|
+ m_consts.destroy(getAllocator());
|
|
|
}
|
|
|
|
|
|
Error ShaderProgramResource2::load(const ResourceFilename& filename, Bool async)
|
|
|
@@ -55,187 +56,88 @@ Error ShaderProgramResource2::load(const ResourceFilename& filename, Bool async)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Create the inputs
|
|
|
+ // Create the constants
|
|
|
+ for(const ShaderProgramBinaryConstant& c : binary.m_constants)
|
|
|
{
|
|
|
- U32 descriptorSet = MAX_U32;
|
|
|
- U32 maxDescriptorSet = 0;
|
|
|
- for(const ShaderProgramBinaryBlock& block : binary.m_uniformBlocks)
|
|
|
+ U32 componentIdx;
|
|
|
+ U32 componentCount;
|
|
|
+ CString name;
|
|
|
+ ANKI_CHECK(parseConst(c.m_name.getBegin(), componentIdx, componentCount, name));
|
|
|
+
|
|
|
+ // Do the mapping
|
|
|
+ ConstMapping mapping;
|
|
|
+ mapping.m_component = componentIdx;
|
|
|
+ if(componentIdx > 0)
|
|
|
{
|
|
|
- maxDescriptorSet = max(maxDescriptorSet, block.m_set);
|
|
|
-
|
|
|
- if(block.m_name.getBegin() != CString("b_ankiMaterial"))
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- m_materialUboIdx = U8(&block - &binary.m_uniformBlocks[0]);
|
|
|
- descriptorSet = block.m_set;
|
|
|
-
|
|
|
- for(const ShaderProgramBinaryVariable& var : block.m_variables)
|
|
|
- {
|
|
|
- Bool instanced;
|
|
|
- U32 idx;
|
|
|
- CString name;
|
|
|
- ANKI_CHECK(parseVariable(var.m_name.getBegin(), instanced, idx, name));
|
|
|
-
|
|
|
- if(idx > 0)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- ShaderProgramResourceInputVariable2& in = *m_inputVars.emplaceBack(getAllocator());
|
|
|
- in.m_name.create(getAllocator(), name);
|
|
|
- in.m_index = m_inputVars.getSize() - 1;
|
|
|
- in.m_constant = false;
|
|
|
- in.m_dataType = var.m_type;
|
|
|
- in.m_instanced = instanced;
|
|
|
- }
|
|
|
+ const ShaderProgramResourceConstant2* other = tryFindConstant(name);
|
|
|
+ ANKI_ASSERT(other);
|
|
|
+ mapping.m_constsIdx = U32(other - m_consts.getBegin());
|
|
|
}
|
|
|
-
|
|
|
- // Continue with the opaque if it's a material shader program
|
|
|
- if(descriptorSet != MAX_U32)
|
|
|
+ else
|
|
|
{
|
|
|
- for(const ShaderProgramBinaryOpaque& o : binary.m_opaques)
|
|
|
- {
|
|
|
- maxDescriptorSet = max(maxDescriptorSet, o.m_set);
|
|
|
-
|
|
|
- if(o.m_set != descriptorSet)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- ShaderProgramResourceInputVariable2& in = *m_inputVars.emplaceBack(getAllocator());
|
|
|
- in.m_name.create(getAllocator(), o.m_name.getBegin());
|
|
|
- in.m_index = m_inputVars.getSize() - 1;
|
|
|
- in.m_constant = false;
|
|
|
- in.m_dataType = o.m_type;
|
|
|
- in.m_instanced = false;
|
|
|
- }
|
|
|
+ mapping.m_constsIdx = m_consts.getSize();
|
|
|
}
|
|
|
|
|
|
- if(descriptorSet != MAX_U32 && descriptorSet != maxDescriptorSet)
|
|
|
+ m_constBinaryMapping.emplaceBack(getAllocator(), mapping);
|
|
|
+
|
|
|
+ // Skip if const is there
|
|
|
+ if(componentIdx > 0)
|
|
|
{
|
|
|
- ANKI_RESOURCE_LOGE("All bindings of a material shader should be in the highest descriptor set");
|
|
|
- return Error::USER_DATA;
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
- m_descriptorSet = U8(descriptorSet);
|
|
|
+ // Create new one
|
|
|
+ ShaderProgramResourceConstant2& in = *m_consts.emplaceBack(getAllocator());
|
|
|
+ in.m_name.create(getAllocator(), name);
|
|
|
+ in.m_index = m_consts.getSize() - 1;
|
|
|
|
|
|
- for(const ShaderProgramBinaryConstant& c : binary.m_constants)
|
|
|
+ if(componentCount == 1)
|
|
|
{
|
|
|
- U32 componentIdx;
|
|
|
- U32 componentCount;
|
|
|
- CString name;
|
|
|
- ANKI_CHECK(parseConst(c.m_name.getBegin(), componentIdx, componentCount, name));
|
|
|
-
|
|
|
- if(componentIdx > 0)
|
|
|
+ in.m_dataType = c.m_type;
|
|
|
+ }
|
|
|
+ else if(componentCount == 2)
|
|
|
+ {
|
|
|
+ if(c.m_type == ShaderVariableDataType::INT)
|
|
|
{
|
|
|
- continue;
|
|
|
+ in.m_dataType = ShaderVariableDataType::IVEC2;
|
|
|
}
|
|
|
-
|
|
|
- ShaderProgramResourceInputVariable2& in = *m_inputVars.emplaceBack(getAllocator());
|
|
|
- in.m_name.create(getAllocator(), name);
|
|
|
- in.m_index = m_inputVars.getSize() - 1;
|
|
|
- in.m_constant = true;
|
|
|
-
|
|
|
- if(componentCount == 1)
|
|
|
+ else
|
|
|
{
|
|
|
- in.m_dataType = c.m_type;
|
|
|
+ ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
|
|
|
+ in.m_dataType = ShaderVariableDataType::VEC2;
|
|
|
}
|
|
|
- else if(componentCount == 2)
|
|
|
+ }
|
|
|
+ else if(componentCount == 3)
|
|
|
+ {
|
|
|
+ if(c.m_type == ShaderVariableDataType::INT)
|
|
|
{
|
|
|
- if(c.m_type == ShaderVariableDataType::INT)
|
|
|
- {
|
|
|
- in.m_dataType = ShaderVariableDataType::IVEC2;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
|
|
|
- in.m_dataType = ShaderVariableDataType::VEC2;
|
|
|
- }
|
|
|
+ in.m_dataType = ShaderVariableDataType::IVEC3;
|
|
|
}
|
|
|
- else if(componentCount == 3)
|
|
|
+ else
|
|
|
{
|
|
|
- if(c.m_type == ShaderVariableDataType::INT)
|
|
|
- {
|
|
|
- in.m_dataType = ShaderVariableDataType::IVEC3;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
|
|
|
- in.m_dataType = ShaderVariableDataType::VEC3;
|
|
|
- }
|
|
|
+ ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
|
|
|
+ in.m_dataType = ShaderVariableDataType::VEC3;
|
|
|
}
|
|
|
- else if(componentCount == 4)
|
|
|
+ }
|
|
|
+ else if(componentCount == 4)
|
|
|
+ {
|
|
|
+ if(c.m_type == ShaderVariableDataType::INT)
|
|
|
{
|
|
|
- if(c.m_type == ShaderVariableDataType::INT)
|
|
|
- {
|
|
|
- in.m_dataType = ShaderVariableDataType::IVEC4;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
|
|
|
- in.m_dataType = ShaderVariableDataType::VEC4;
|
|
|
- }
|
|
|
+ in.m_dataType = ShaderVariableDataType::IVEC4;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- ANKI_ASSERT(0);
|
|
|
+ ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
|
|
|
+ in.m_dataType = ShaderVariableDataType::VEC4;
|
|
|
}
|
|
|
}
|
|
|
- } // End creating the inputs
|
|
|
-
|
|
|
- m_shaderStages = binary.m_presentShaderTypes;
|
|
|
-
|
|
|
- return Error::NONE;
|
|
|
-}
|
|
|
-
|
|
|
-Error ShaderProgramResource2::parseVariable(CString fullVarName, Bool& instanced, U32& idx, CString& name)
|
|
|
-{
|
|
|
- if(fullVarName.find("u_ankiPerDraw") == CString::NPOS)
|
|
|
- {
|
|
|
- instanced = false;
|
|
|
- }
|
|
|
- else if(fullVarName.find("u_ankiPerInstance") == CString::NPOS)
|
|
|
- {
|
|
|
- instanced = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ANKI_RESOURCE_LOGE("Wrong variable name: %s", fullVarName.cstr());
|
|
|
- return Error::USER_DATA;
|
|
|
- }
|
|
|
-
|
|
|
- if(instanced)
|
|
|
- {
|
|
|
- const PtrSize leftBracket = fullVarName.find("[");
|
|
|
- const PtrSize rightBracket = fullVarName.find("]");
|
|
|
-
|
|
|
- if(leftBracket == CString::NPOS || rightBracket == CString::NPOS || rightBracket <= leftBracket)
|
|
|
- {
|
|
|
- ANKI_RESOURCE_LOGE("Wrong variable name: %s", fullVarName.cstr());
|
|
|
- return Error::USER_DATA;
|
|
|
- }
|
|
|
-
|
|
|
- Array<char, 8> idxStr;
|
|
|
- ANKI_ASSERT(rightBracket - leftBracket < idxStr.getSize() - 1);
|
|
|
- for(PtrSize i = leftBracket; i <= rightBracket; ++i)
|
|
|
+ else
|
|
|
{
|
|
|
- idxStr[i - leftBracket] = fullVarName[i];
|
|
|
+ ANKI_ASSERT(0);
|
|
|
}
|
|
|
- idxStr[rightBracket - leftBracket + 1] = '\0';
|
|
|
-
|
|
|
- ANKI_CHECK(CString(idxStr.getBegin()).toNumber(idx));
|
|
|
}
|
|
|
|
|
|
- const PtrSize dot = fullVarName.find(".");
|
|
|
- if(dot == CString::NPOS)
|
|
|
- {
|
|
|
- ANKI_RESOURCE_LOGE("Wrong variable name: %s", fullVarName.cstr());
|
|
|
- return Error::USER_DATA;
|
|
|
- }
|
|
|
-
|
|
|
- name = fullVarName.getBegin() + dot;
|
|
|
+ m_shaderStages = binary.m_presentShaderTypes;
|
|
|
|
|
|
return Error::NONE;
|
|
|
}
|
|
|
@@ -338,59 +240,6 @@ void ShaderProgramResource2::initVariant(
|
|
|
}
|
|
|
ANKI_ASSERT(binaryVariant);
|
|
|
|
|
|
- // Init the uniform vars
|
|
|
- if(m_materialUboIdx != MAX_U8)
|
|
|
- {
|
|
|
- variant.m_blockInfos.create(getAllocator(), m_inputVars.getSize());
|
|
|
-
|
|
|
- for(const ShaderProgramBinaryVariableInstance& instance :
|
|
|
- binaryVariant->m_uniformBlocks[m_materialUboIdx].m_variables)
|
|
|
- {
|
|
|
- ANKI_ASSERT(instance.m_index == m_materialUboIdx);
|
|
|
- const U32 inputIdx = m_binaryMapping.m_uniformVars[instance.m_index].m_inputVarIdx;
|
|
|
- const U32 arrayIdx = m_binaryMapping.m_uniformVars[instance.m_index].m_arrayIdx;
|
|
|
- ShaderVariableBlockInfo& blockInfo = variant.m_blockInfos[inputIdx];
|
|
|
-
|
|
|
- if(arrayIdx == 0)
|
|
|
- {
|
|
|
- blockInfo = instance.m_blockInfo;
|
|
|
- }
|
|
|
- else if(arrayIdx == 1)
|
|
|
- {
|
|
|
- ANKI_ASSERT(blockInfo.m_offset >= 0);
|
|
|
- blockInfo.m_arraySize = max(blockInfo.m_arraySize, I16(arrayIdx + 1));
|
|
|
- ANKI_ASSERT(instance.m_blockInfo.m_offset > blockInfo.m_offset);
|
|
|
- blockInfo.m_arrayStride = instance.m_blockInfo.m_offset - blockInfo.m_offset;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- ANKI_ASSERT(blockInfo.m_offset >= 0);
|
|
|
- blockInfo.m_arraySize = max(blockInfo.m_arraySize, I16(arrayIdx + 1));
|
|
|
- }
|
|
|
-
|
|
|
- variant.m_activeInputVars.set(inputIdx);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Init the opaques
|
|
|
- variant.m_opaqueBindings.create(getAllocator(), m_inputVars.getSize(), -1);
|
|
|
- for(const ShaderProgramBinaryOpaqueInstance& instance : binaryVariant->m_opaques)
|
|
|
- {
|
|
|
- const U32 opaqueIdx = instance.m_index;
|
|
|
- const ShaderProgramBinaryOpaque& opaque = binary.m_opaques[opaqueIdx];
|
|
|
- if(opaque.m_set != m_descriptorSet)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- const U32 inputIdx = m_binaryMapping.m_opaques[opaqueIdx];
|
|
|
- const Input& in = m_inputVars[inputIdx];
|
|
|
- ANKI_ASSERT(in.isSampler() || in.isTexture());
|
|
|
-
|
|
|
- variant.m_opaqueBindings[inputIdx] = I16(opaque.m_binding);
|
|
|
- variant.m_activeInputVars.set(inputIdx);
|
|
|
- }
|
|
|
-
|
|
|
// Set the constannt values
|
|
|
Array2d<ShaderSpecializationConstValue, U(ShaderType::COUNT), 64> constValues;
|
|
|
Array<U32, U(ShaderType::COUNT)> constValueCounts;
|
|
|
@@ -409,14 +258,14 @@ void ShaderProgramResource2::initVariant(
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- const U32 inputIdx = m_binaryMapping.m_constants[instance.m_index].m_inputVarIdx;
|
|
|
- const U32 component = m_binaryMapping.m_constants[instance.m_index].m_component;
|
|
|
+ const U32 inputIdx = m_constBinaryMapping[instance.m_index].m_constsIdx;
|
|
|
+ const U32 component = m_constBinaryMapping[instance.m_index].m_component;
|
|
|
|
|
|
// Get value
|
|
|
const ShaderProgramResourceConstantValue2* value = nullptr;
|
|
|
for(U32 i = 0; i < info.m_constantValueCount; ++i)
|
|
|
{
|
|
|
- if(info.m_constantValues[i].m_inputVariableIndex == inputIdx)
|
|
|
+ if(info.m_constantValues[i].m_constantIndex == inputIdx)
|
|
|
{
|
|
|
value = &info.m_constantValues[i];
|
|
|
break;
|