Compare commits
1 Commits
bjd/comman
...
zm/skip-li
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55dbafe0b0 |
@@ -121,6 +121,12 @@ struct ShaderCompilerService::OpenGLProgramToken : ProgramToken {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks the token's completion status. The token is considered ready if the program was
|
||||||
|
// created successfully or if a shader compilation error occurred.
|
||||||
|
bool isReady() const noexcept {
|
||||||
|
return gl.program || compilationFailed;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<CallbackManager::Handle> handle{};
|
std::optional<CallbackManager::Handle> handle{};
|
||||||
|
|
||||||
// Only valid when the blob functions are provided by users. The validity of this variable
|
// Only valid when the blob functions are provided by users. The validity of this variable
|
||||||
@@ -134,6 +140,9 @@ struct ShaderCompilerService::OpenGLProgramToken : ProgramToken {
|
|||||||
|
|
||||||
// Indicate this program was created from the cache blob.
|
// Indicate this program was created from the cache blob.
|
||||||
bool retrievedFromBlobCache = false;
|
bool retrievedFromBlobCache = false;
|
||||||
|
|
||||||
|
// Indicates that shader compilation failed.
|
||||||
|
bool compilationFailed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
ShaderCompilerService::OpenGLProgramToken::~OpenGLProgramToken() {
|
ShaderCompilerService::OpenGLProgramToken::~OpenGLProgramToken() {
|
||||||
@@ -297,22 +306,33 @@ ShaderCompilerService::program_token_t ShaderCompilerService::createProgram(
|
|||||||
|
|
||||||
runAtNextTick(priorityQueue, token, [this, token](Job const&) {
|
runAtNextTick(priorityQueue, token, [this, token](Job const&) {
|
||||||
assert_invariant(mMode != Mode::THREAD_POOL);
|
assert_invariant(mMode != Mode::THREAD_POOL);
|
||||||
if (mMode == Mode::ASYNCHRONOUS) {
|
|
||||||
// Check link completion if link was initiated.
|
if (token->gl.program) {
|
||||||
if (token->gl.program) {
|
// Program linking has been initiated.
|
||||||
|
if (mMode == Mode::ASYNCHRONOUS) {
|
||||||
return isLinkCompleted(token);
|
return isLinkCompleted(token);
|
||||||
}
|
}
|
||||||
// Link hasn't been initiated, then check compile completion.
|
return true; // In sync mode, if program exists, we're done with this job.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Program not linked yet. Check if shaders are compiled.
|
||||||
|
if (mMode == Mode::ASYNCHRONOUS) {
|
||||||
if (!isCompileCompleted(token)) {
|
if (!isCompileCompleted(token)) {
|
||||||
return false;
|
return false; // Wait for compilation to finish.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!token->gl.program) {
|
|
||||||
linkProgram(mDriver.getContext(), token);
|
// Shaders are compiled (or we're in sync mode). Let's link.
|
||||||
if (mMode == Mode::ASYNCHRONOUS) {
|
if (!linkProgram(mDriver.getContext(), token)) {
|
||||||
return false;// Wait until the link finishes.
|
// Shader compilation failed. Stop processing this program.
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Program is now linking.
|
||||||
|
if (mMode == Mode::ASYNCHRONOUS) {
|
||||||
|
return false; // Wait for linking to finish.
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -394,6 +414,14 @@ GLuint ShaderCompilerService::initialize(program_token_t& token) {
|
|||||||
assert_invariant(token);// This function should be called when the token is still alive.
|
assert_invariant(token);// This function should be called when the token is still alive.
|
||||||
|
|
||||||
ensureTokenIsReady(token);
|
ensureTokenIsReady(token);
|
||||||
|
|
||||||
|
if (token->compilationFailed) {
|
||||||
|
// Cleanup the token.
|
||||||
|
token->compiler.cancelTickOp(token);
|
||||||
|
token = nullptr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
assert_invariant(token->gl.program);
|
assert_invariant(token->gl.program);
|
||||||
|
|
||||||
// Check status of program linking. If it failed, errors will be logged.
|
// Check status of program linking. If it failed, errors will be logged.
|
||||||
@@ -419,7 +447,7 @@ GLuint ShaderCompilerService::initialize(program_token_t& token) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ShaderCompilerService::ensureTokenIsReady(program_token_t const& token) {
|
void ShaderCompilerService::ensureTokenIsReady(program_token_t const& token) {
|
||||||
if (token->gl.program) {
|
if (token->isReady()) {
|
||||||
return;// It's ready.
|
return;// It's ready.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,9 +666,10 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ShaderCompilerService::checkCompileStatus(program_token_t const& token) noexcept {
|
/* static */ bool ShaderCompilerService::checkCompileStatus(program_token_t const& token) noexcept {
|
||||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||||
|
|
||||||
|
bool success = true;
|
||||||
UTILS_NOUNROLL
|
UTILS_NOUNROLL
|
||||||
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
|
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
|
||||||
const GLuint shader = token->gl.shaders[i];
|
const GLuint shader = token->gl.shaders[i];
|
||||||
@@ -656,15 +685,21 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
|||||||
// Something went wrong. Log the error message.
|
// Something went wrong. Log the error message.
|
||||||
const ShaderStage type = static_cast<ShaderStage>(i);
|
const ShaderStage type = static_cast<ShaderStage>(i);
|
||||||
logCompilationError(type, token->name.c_str_safe(), shader, token->shaderSourceCode[i]);
|
logCompilationError(type, token->name.c_str_safe(), shader, token->shaderSourceCode[i]);
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void ShaderCompilerService::linkProgram(OpenGLContext const& context,
|
/* static */ bool ShaderCompilerService::linkProgram(OpenGLContext const& context,
|
||||||
program_token_t const& token) noexcept {
|
program_token_t const& token) noexcept {
|
||||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||||
|
|
||||||
// Shader compilation should be completed by now. Check the status and log errors on failure.
|
// Shader compilation should be completed by now. Check the status and log errors on failure.
|
||||||
checkCompileStatus(token);
|
if (!checkCompileStatus(token)) {
|
||||||
|
token->compilationFailed = true;
|
||||||
|
token->trySubmittingCallback();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Link program
|
// Link program
|
||||||
GLuint const program = glCreateProgram();
|
GLuint const program = glCreateProgram();
|
||||||
@@ -681,6 +716,7 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
|||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
token->gl.program = program;
|
token->gl.program = program;
|
||||||
token->trySubmittingCallback();
|
token->trySubmittingCallback();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool ShaderCompilerService::isLinkCompleted(program_token_t const& token) noexcept {
|
/* static */ bool ShaderCompilerService::isLinkCompleted(program_token_t const& token) noexcept {
|
||||||
|
|||||||
@@ -155,13 +155,14 @@ private:
|
|||||||
static bool isCompileCompleted(program_token_t const& token) noexcept;
|
static bool isCompileCompleted(program_token_t const& token) noexcept;
|
||||||
|
|
||||||
// Check compilation status of the shaders and log errors on failure.
|
// Check compilation status of the shaders and log errors on failure.
|
||||||
static void checkCompileStatus(program_token_t const& token) noexcept;
|
static bool checkCompileStatus(program_token_t const& token) noexcept;
|
||||||
|
|
||||||
// Create a program by linking the compiled shaders. `gl.program` is always populated with a
|
// Create a program by linking the compiled shaders. If the previous shader compilation was
|
||||||
// valid program ID after this method. But this doesn't necessarily mean the program is
|
// failed, `compilationFailed` is set, then this function returns false. Otherwise `gl.program`
|
||||||
// successfully linked. Errors can be checked by calling `checkLinkStatusAndCleanupShaders`
|
// is populated with a valid program ID, then returns true. However this doesn't necessarily
|
||||||
// later.
|
// mean the program is successfully linked. The link error can be checked by calling
|
||||||
static void linkProgram(OpenGLContext const& context, program_token_t const& token) noexcept;
|
// `checkLinkStatusAndCleanupShaders` later.
|
||||||
|
static bool linkProgram(OpenGLContext const& context, program_token_t const& token) noexcept;
|
||||||
|
|
||||||
// Check if the program link is completed. You may want to call this when the extension
|
// Check if the program link is completed. You may want to call this when the extension
|
||||||
// `KHR_parallel_shader_compile` is enabled.
|
// `KHR_parallel_shader_compile` is enabled.
|
||||||
|
|||||||
Reference in New Issue
Block a user