Add getVertexIndex API for vertex shaders (#3493)
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user