Compare commits
3 Commits
pf/testing
...
pf/test-of
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3fc8e3796 | ||
|
|
5e7106b521 | ||
|
|
30387af61c |
@@ -1308,7 +1308,12 @@ Description
|
||||
declare a variable called `eyeDirection` you can access it in the fragment shader using
|
||||
`variable_eyeDirection`. In the vertex shader, the interpolant name is simply a member of
|
||||
the `MaterialVertexInputs` structure (`material.eyeDirection` in your example). Each
|
||||
interpolant is of type `float4` (`vec4`) in the shaders.
|
||||
interpolant is of type `float4` (`vec4`) in the shaders. By default the precision of the
|
||||
interpolant is `highp` in *both* the vertex and fragment shaders.
|
||||
An alternate syntax can be used to specify both the name and precision of the interpolant.
|
||||
In this case the specified precision is used as-is in both fragment and vertex stages, in
|
||||
particular if `default` is specified the default precision is used is the fragment shader
|
||||
(`mediump`) and in the vertex shader (`highp`).
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
@@ -1320,7 +1325,11 @@ material {
|
||||
}
|
||||
],
|
||||
variables : [
|
||||
eyeDirection
|
||||
eyeDirection,
|
||||
{
|
||||
name : eyeColor,
|
||||
precision : medium
|
||||
}
|
||||
],
|
||||
vertexDomain : device,
|
||||
depthWrite : false,
|
||||
|
||||
@@ -323,6 +323,9 @@ public:
|
||||
//! Custom variables (all float4).
|
||||
MaterialBuilder& variable(Variable v, const char* name) noexcept;
|
||||
|
||||
MaterialBuilder& variable(Variable v, const char* name,
|
||||
ParameterPrecision precision) noexcept;
|
||||
|
||||
/**
|
||||
* Require a specified attribute.
|
||||
*
|
||||
@@ -708,11 +711,17 @@ public:
|
||||
ShaderStage stage;
|
||||
};
|
||||
|
||||
struct CustomVariable {
|
||||
utils::CString name;
|
||||
Precision precision = Precision::DEFAULT;
|
||||
bool hasPrecision = false;
|
||||
};
|
||||
|
||||
static constexpr size_t MATERIAL_PROPERTIES_COUNT = filament::MATERIAL_PROPERTIES_COUNT;
|
||||
using Property = filament::Property;
|
||||
|
||||
using PropertyList = bool[MATERIAL_PROPERTIES_COUNT];
|
||||
using VariableList = utils::CString[MATERIAL_VARIABLES_COUNT];
|
||||
using VariableList = CustomVariable[MATERIAL_VARIABLES_COUNT];
|
||||
using OutputList = std::vector<Output>;
|
||||
|
||||
static constexpr size_t MAX_COLOR_OUTPUT = filament::backend::MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
|
||||
|
||||
@@ -671,13 +671,15 @@ void GLSLPostProcessor::fixupClipDistance(
|
||||
// - triggers a crash on some Adreno drivers (b/291140208, b/289401984, b/289393290)
|
||||
// However Metal requires this pass in order to correctly generate half-precision MSL
|
||||
//
|
||||
// CreateSimplificationPass() creates a lot of problems:
|
||||
// Note: CreateSimplificationPass() used to creates a lot of problems:
|
||||
// - Adreno GPU show artifacts after running simplification passes (Vulkan)
|
||||
// - spirv-cross fails generating working glsl
|
||||
// (https://github.com/KhronosGroup/SPIRV-Cross/issues/2162)
|
||||
// - generally it makes the code more complicated, e.g.: replacing for loops with
|
||||
// while-if-break, unclear if it helps for anything.
|
||||
// However, the simplification passes below are necessary when targeting Metal, otherwise the
|
||||
//
|
||||
// However this problem was addressed in spirv-cross here:
|
||||
// https://github.com/KhronosGroup/SPIRV-Cross/pull/2163
|
||||
//
|
||||
// The simplification passes below are necessary when targeting Metal, otherwise the
|
||||
// result is mismatched half / float assignments in MSL.
|
||||
|
||||
|
||||
@@ -710,11 +712,11 @@ void GLSLPostProcessor::registerPerformancePasses(Optimizer& optimizer, Config c
|
||||
RegisterPass(CreateAggressiveDCEPass());
|
||||
RegisterPass(CreateRedundancyEliminationPass());
|
||||
RegisterPass(CreateCombineAccessChainsPass());
|
||||
RegisterPass(CreateSimplificationPass(), MaterialBuilder::TargetApi::METAL);
|
||||
RegisterPass(CreateSimplificationPass());
|
||||
RegisterPass(CreateVectorDCEPass());
|
||||
RegisterPass(CreateDeadInsertElimPass());
|
||||
RegisterPass(CreateDeadBranchElimPass());
|
||||
RegisterPass(CreateSimplificationPass(), MaterialBuilder::TargetApi::METAL);
|
||||
RegisterPass(CreateSimplificationPass());
|
||||
RegisterPass(CreateIfConversionPass());
|
||||
RegisterPass(CreateCopyPropagateArraysPass());
|
||||
RegisterPass(CreateReduceLoadSizePass());
|
||||
@@ -723,7 +725,7 @@ void GLSLPostProcessor::registerPerformancePasses(Optimizer& optimizer, Config c
|
||||
RegisterPass(CreateRedundancyEliminationPass());
|
||||
RegisterPass(CreateDeadBranchElimPass());
|
||||
RegisterPass(CreateBlockMergePass());
|
||||
RegisterPass(CreateSimplificationPass(), MaterialBuilder::TargetApi::METAL);
|
||||
RegisterPass(CreateSimplificationPass());
|
||||
}
|
||||
|
||||
void GLSLPostProcessor::registerSizePasses(Optimizer& optimizer, Config const& config) {
|
||||
|
||||
@@ -234,7 +234,21 @@ MaterialBuilder& MaterialBuilder::variable(Variable v, const char* name) noexcep
|
||||
case Variable::CUSTOM2:
|
||||
case Variable::CUSTOM3:
|
||||
assert(size_t(v) < MATERIAL_VARIABLES_COUNT);
|
||||
mVariables[size_t(v)] = CString(name);
|
||||
mVariables[size_t(v)] = { CString(name), Precision::DEFAULT, false };
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::variable(Variable v,
|
||||
const char* name, ParameterPrecision precision) noexcept {
|
||||
switch (v) {
|
||||
case Variable::CUSTOM0:
|
||||
case Variable::CUSTOM1:
|
||||
case Variable::CUSTOM2:
|
||||
case Variable::CUSTOM3:
|
||||
assert(size_t(v) < MATERIAL_VARIABLES_COUNT);
|
||||
mVariables[size_t(v)] = { CString(name), precision, true };
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
@@ -1383,7 +1397,7 @@ bool MaterialBuilder::checkMaterialLevelFeatures(MaterialInfo const& info) const
|
||||
|
||||
bool MaterialBuilder::hasCustomVaryings() const noexcept {
|
||||
for (const auto& variable : mVariables) {
|
||||
if (!variable.empty()) {
|
||||
if (!variable.name.empty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,15 +451,20 @@ io::sstream& CodeGenerator::generatePostProcessMain(io::sstream& out, ShaderStag
|
||||
}
|
||||
|
||||
io::sstream& CodeGenerator::generateVariable(io::sstream& out, ShaderStage stage,
|
||||
const CString& name, size_t index) {
|
||||
|
||||
const MaterialBuilder::CustomVariable& variable, size_t index) {
|
||||
auto const& name = variable.name;
|
||||
const char* precisionString = getPrecisionQualifier(variable.precision);
|
||||
if (!name.empty()) {
|
||||
if (stage == ShaderStage::VERTEX) {
|
||||
out << "\n#define VARIABLE_CUSTOM" << index << " " << name.c_str() << "\n";
|
||||
out << "\n#define VARIABLE_CUSTOM_AT" << index << " variable_" << name.c_str() << "\n";
|
||||
out << "LAYOUT_LOCATION(" << index << ") VARYING vec4 variable_" << name.c_str() << ";\n";
|
||||
out << "LAYOUT_LOCATION(" << index << ") VARYING " << precisionString << " vec4 variable_" << name.c_str() << ";\n";
|
||||
} else if (stage == ShaderStage::FRAGMENT) {
|
||||
out << "\nLAYOUT_LOCATION(" << index << ") VARYING highp vec4 variable_" << name.c_str() << ";\n";
|
||||
if (!variable.hasPrecision && variable.precision == Precision::DEFAULT) {
|
||||
// for backward compatibility
|
||||
precisionString = "highp";
|
||||
}
|
||||
out << "\nLAYOUT_LOCATION(" << index << ") VARYING " << precisionString << " vec4 variable_" << name.c_str() << ";\n";
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
|
||||
// generate declarations for custom interpolants
|
||||
static utils::io::sstream& generateVariable(utils::io::sstream& out, ShaderStage stage,
|
||||
const utils::CString& name, size_t index);
|
||||
const MaterialBuilder::CustomVariable& variable, size_t index);
|
||||
|
||||
// generate declarations for non-custom "in" variables
|
||||
utils::io::sstream& generateShaderInputs(utils::io::sstream& out, ShaderStage type,
|
||||
|
||||
@@ -615,14 +615,51 @@ static bool processVariables(MaterialBuilder& builder, const JsonishValue& value
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < elements.size(); i++) {
|
||||
auto elementValue = elements[i];
|
||||
ParameterPrecision precision = ParameterPrecision::DEFAULT;
|
||||
MaterialBuilder::Variable v = intToVariable(i);
|
||||
if (elementValue->getType() != JsonishValue::Type::STRING) {
|
||||
std::string nameString;
|
||||
|
||||
auto elementValue = elements[i];
|
||||
if (elementValue->getType() == JsonishValue::Type::OBJECT) {
|
||||
|
||||
JsonishObject const& jsonObject = *elementValue->toJsonObject();
|
||||
|
||||
const JsonishValue* nameValue = jsonObject.getValue("name");
|
||||
if (!nameValue) {
|
||||
std::cerr << "variables: entry without 'name' key." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (nameValue->getType() != JsonishValue::STRING) {
|
||||
std::cerr << "variables: name value must be STRING." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const JsonishValue* precisionValue = jsonObject.getValue("precision");
|
||||
if (precisionValue) {
|
||||
if (precisionValue->getType() != JsonishValue::STRING) {
|
||||
std::cerr << "variables: precision must be a STRING." << std::endl;
|
||||
return false;
|
||||
}
|
||||
auto precisionString = precisionValue->toJsonString();
|
||||
if (!Enums::isValid<ParameterPrecision>(precisionString->getString())){
|
||||
return logEnumIssue("variables", *precisionString, Enums::map<ParameterPrecision>());
|
||||
}
|
||||
}
|
||||
|
||||
nameString = nameValue->toJsonString()->getString();
|
||||
if (precisionValue) {
|
||||
precision = Enums::toEnum<ParameterPrecision>(
|
||||
precisionValue->toJsonString()->getString());
|
||||
}
|
||||
builder.variable(v, nameString.c_str(), precision);
|
||||
} else if (elementValue->getType() == JsonishValue::Type::STRING) {
|
||||
nameString = elementValue->toJsonString()->getString();
|
||||
builder.variable(v, nameString.c_str());
|
||||
} else {
|
||||
std::cerr << "variables: array index " << i << " is not a STRING. found:" <<
|
||||
JsonishValue::typeToString(elementValue->getType()) << std::endl;
|
||||
return false;
|
||||
}
|
||||
builder.variable(v, elementValue->toJsonString()->getString().c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user