[Feat] (MG_Backend|MG_State/ProgramState): Add default fragment shader if missing for backends requiring FS.

This commit is contained in:
BZLZHH
2025-12-31 21:09:19 +08:00
parent c902721683
commit 58b620dee3
6 changed files with 53 additions and 9 deletions
@@ -12,6 +12,11 @@
#include <MG_Util/Converters/MGToGL/ProgramEnumConverter.h>
#include <MG_Util/Converters/SPIRVCrossToGL/SpvcTypeConverter.h>
const char* kDefaultFragmentShaderSource = R"(#version 460 core
layout(location = 0) out vec4 FragColor;
void main() {}
)";
namespace MobileGL {
namespace MG_State {
namespace GLState {
@@ -58,7 +63,38 @@ namespace MobileGL {
return count;
}
void ProgramObject::Link() {
void ProgramObject::AddDefaultFragmentShaderIfMissing() {
Bool needsDefaultFS = false;
for (const auto& shader : m_shaders) {
auto stage = shader->GetShaderStage();
if (stage == ShaderStage::Vertex) {
needsDefaultFS = true;
continue;
}
if (stage == ShaderStage::Fragment) {
needsDefaultFS = false;
return;
}
}
if (!needsDefaultFS) return;
MGLOG_D("ProgramObject %u: No fragment shader attached, adding default fragment shader.",
m_externalIndex);
SharedPtr<ShaderObject> defaultFS = MakeShared<ShaderObject>(ShaderStage::Fragment, 0);
defaultFS->SetShaderSource(kDefaultFragmentShaderSource);
defaultFS->Compile(); // TODO: use a global default FS object.
auto status = defaultFS->GetCompileStatus();
if (!status) {
MGLOG_E("ProgramObject %u: Failed to compile default fragment shader. InfoLog:\n%s",
m_externalIndex, defaultFS->GetInfoLog().c_str());
return;
}
m_shaders.push_back(defaultFS);
MGLOG_D("ProgramObject %u: Default fragment shader added.", m_externalIndex);
}
void ProgramObject::Link(Bool addDefaultFSIfMissingForRenderingPipelineProgram) {
MGLOG_D("ProgramObject %u: Link start, shaders to link: %zu", m_externalIndex, m_shaders.size());
// Remove detached shaders first
for (const auto& detachedShader : m_detachedShaders) {
@@ -69,6 +105,10 @@ namespace MobileGL {
Vector<GLenum> shaderTypes(m_shaders.size());
Vector<SharedPtr<glslang::TShader>> shaders(m_shaders.size());
if (addDefaultFSIfMissingForRenderingPipelineProgram) {
AddDefaultFragmentShaderIfMissing();
}
for (SizeT i = 0; i < m_shaders.size(); i++) {
shaderTypes[i] = MG_Util::ConvertShaderStageToGLEnum(m_shaders[i]->GetShaderStage());
MGLOG_D("ProgramObject %u: Preparing shader[%zu] stage %s at %p", m_externalIndex, i,
@@ -21,7 +21,7 @@ namespace MobileGL {
bool AttachShader(SharedPtr<ShaderObject> shader);
SizeT DetachShader(SharedPtr<ShaderObject> shader);
SizeT RemoveShader(SharedPtr<ShaderObject> shader);
void Link();
void Link(Bool addDefaultFSIfMissingForRenderingPipelineProgram = false);
void MarkAsDeleted();
void SetExplicitVertexInLocation(Uint index, const char* name);
@@ -120,6 +120,7 @@ namespace MobileGL {
void DoReflection();
void GenerateBinary();
void WaitUntilGenerationCompleted();
void AddDefaultFragmentShaderIfMissing();
const Uint m_externalIndex = 0;
Vector<SharedPtr<ShaderObject>> m_shaders;