Add getVertexIndex API for vertex shaders (#3493)

This commit is contained in:
Ben Doherty
2021-02-04 12:40:21 -08:00
committed by GitHub
parent f6425fdcfb
commit 07ddd52dcf
7 changed files with 32 additions and 9 deletions

View File

@@ -1920,6 +1920,7 @@ The following APIs are only available from the vertex block:
**getCustom0()** to **getCustom7()** | float4 | Custom vertex attribute
**getWorldFromModelMatrix()** | float4x4 | Matrix that converts from model (object) space to world space
**getWorldFromModelNormalMatrix()** | float3x3 | Matrix that converts normals from model (object) space to world space
**getVertexIndex()** | int | Index of the current vertex
### Fragment only

View File

@@ -158,8 +158,11 @@ bool GLSLPostProcessor::process(const std::string& inputShader, Config const& co
std::string* outputGlsl, SpirvBlob* outputSpirv, std::string* outputMsl) {
// If TargetApi is Vulkan, then we need post-processing even if there's no optimization.
// If we're using framebuffer fetch, we also need to force our compilation target to Vulkan, as
// it is only supported in GLSL for Vulkan.
using TargetApi = MaterialBuilder::TargetApi;
const TargetApi targetApi = outputSpirv ? TargetApi::VULKAN : TargetApi::OPENGL;
const TargetApi targetApi = (outputSpirv || config.hasFramebufferFetch) ? TargetApi::VULKAN :
TargetApi::OPENGL;
if (targetApi == TargetApi::OPENGL && mOptimization == MaterialBuilder::Optimization::NONE) {
*outputGlsl = inputShader;
if (mPrintShaders) {
@@ -190,7 +193,8 @@ bool GLSLPostProcessor::process(const std::string& inputShader, Config const& co
tShader.setStrings(&shaderCString, 1);
internalConfig.langVersion = GLSLTools::glslangVersionFromShaderModel(config.shaderModel);
GLSLTools::prepareShaderParser(tShader, internalConfig.shLang, internalConfig.langVersion, mOptimization);
GLSLTools::prepareShaderParser(targetApi, tShader, internalConfig.shLang,
internalConfig.langVersion, mOptimization);
EShMessages msg = GLSLTools::glslangFlagsFromTargetApi(targetApi);
bool ok = tShader.parse(&DefaultTBuiltInResource, internalConfig.langVersion, false, msg);
if (!ok) {
@@ -277,7 +281,7 @@ void GLSLPostProcessor::preprocessOptimization(glslang::TShader& tShader,
const char* shaderCString = glsl.c_str();
spirvShader.setStrings(&shaderCString, 1);
GLSLTools::prepareShaderParser(spirvShader,
GLSLTools::prepareShaderParser(targetApi, spirvShader,
internalConfig.shLang, internalConfig.langVersion, mOptimization);
ok = spirvShader.parse(&DefaultTBuiltInResource, internalConfig.langVersion, false, msg);
program.addShader(&spirvShader);

View File

@@ -50,6 +50,7 @@ public:
struct Config {
filament::backend::ShaderType shaderType;
filament::backend::ShaderModel shaderModel;
bool hasFramebufferFetch;
struct {
std::vector<std::pair<uint32_t, uint32_t>> subpassInputToColorLocation;
} glsl;

View File

@@ -712,6 +712,8 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
.glsl = {}
};
config.hasFramebufferFetch = mEnableFramebufferFetch;
if (mEnableFramebufferFetch) {
config.glsl.subpassInputToColorLocation.emplace_back(0, 0);
}

View File

@@ -332,14 +332,20 @@ EShMessages GLSLTools::glslangFlagsFromTargetApi(MaterialBuilder::TargetApi targ
return msg;
}
void GLSLTools::prepareShaderParser(glslang::TShader& shader, EShLanguage language,
int version, filamat::MaterialBuilder::Optimization optimization) {
void GLSLTools::prepareShaderParser(MaterialBuilder::TargetApi targetApi, glslang::TShader& shader,
EShLanguage language, int version, filamat::MaterialBuilder::Optimization optimization) {
// We must only setup the SPIRV environment when we actually need to output SPIRV
if (optimization == filamat::MaterialBuilder::Optimization::SIZE ||
optimization == filamat::MaterialBuilder::Optimization::PERFORMANCE) {
shader.setAutoMapBindings(true);
shader.setEnvInput(EShSourceGlsl, language, EShClientVulkan, version);
shader.setEnvClient(EShClientVulkan, EShTargetVulkan_1_0);
if (targetApi == MaterialBuilder::TargetApi::VULKAN) {
shader.setEnvInput(EShSourceGlsl, language, EShClientVulkan, version);
shader.setEnvClient(EShClientVulkan, EShTargetVulkan_1_0);
} else {
assert(targetApi == MaterialBuilder::TargetApi::OPENGL);
shader.setEnvInput(EShSourceGlsl, language, EShClientOpenGL, version);
shader.setEnvClient(EShClientOpenGL, EShTargetOpenGL_450);
}
shader.setEnvTarget(EShTargetSpv, EShTargetSpv_1_0);
}
}

View File

@@ -147,8 +147,8 @@ public:
static EShMessages glslangFlagsFromTargetApi(MaterialBuilder::TargetApi targetApi);
static void prepareShaderParser(glslang::TShader& shader, EShLanguage language,
int version, MaterialBuilder::Optimization optimization);
static void prepareShaderParser(MaterialBuilder::TargetApi targetApi, glslang::TShader& shader,
EShLanguage language, int version, MaterialBuilder::Optimization optimization);
private:

View File

@@ -116,6 +116,15 @@ vec4 getCustom6() { return mesh_custom6; }
vec4 getCustom7() { return mesh_custom7; }
#endif
/** @public-api */
int getVertexIndex() {
#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT)
return gl_VertexIndex;
#else
return gl_VertexID;
#endif
}
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------