diff --git a/kraken/KRShaderManager.cpp b/kraken/KRShaderManager.cpp index bc4c468..7701408 100644 --- a/kraken/KRShaderManager.cpp +++ b/kraken/KRShaderManager.cpp @@ -31,6 +31,8 @@ #include "KRShaderManager.h" #include "KREngine-common.h" +#include "KRContext.h" +#include "KRSourceManager.h" KRShaderManager::KRShaderManager(KRContext &context) : KRResourceManager(context) , m_initializedGlslang(false) @@ -119,12 +121,191 @@ const unordered_map &KRShaderManager::get(const std::st return m_shaders[lower_extension]; } +// From glslang/StandAlone/ResourceLimits.cpp +const TBuiltInResource DefaultTBuiltInResource = { + /* .MaxLights = */ 32, + /* .MaxClipPlanes = */ 6, + /* .MaxTextureUnits = */ 32, + /* .MaxTextureCoords = */ 32, + /* .MaxVertexAttribs = */ 64, + /* .MaxVertexUniformComponents = */ 4096, + /* .MaxVaryingFloats = */ 64, + /* .MaxVertexTextureImageUnits = */ 32, + /* .MaxCombinedTextureImageUnits = */ 80, + /* .MaxTextureImageUnits = */ 32, + /* .MaxFragmentUniformComponents = */ 4096, + /* .MaxDrawBuffers = */ 32, + /* .MaxVertexUniformVectors = */ 128, + /* .MaxVaryingVectors = */ 8, + /* .MaxFragmentUniformVectors = */ 16, + /* .MaxVertexOutputVectors = */ 16, + /* .MaxFragmentInputVectors = */ 15, + /* .MinProgramTexelOffset = */ -8, + /* .MaxProgramTexelOffset = */ 7, + /* .MaxClipDistances = */ 8, + /* .MaxComputeWorkGroupCountX = */ 65535, + /* .MaxComputeWorkGroupCountY = */ 65535, + /* .MaxComputeWorkGroupCountZ = */ 65535, + /* .MaxComputeWorkGroupSizeX = */ 1024, + /* .MaxComputeWorkGroupSizeY = */ 1024, + /* .MaxComputeWorkGroupSizeZ = */ 64, + /* .MaxComputeUniformComponents = */ 1024, + /* .MaxComputeTextureImageUnits = */ 16, + /* .MaxComputeImageUniforms = */ 8, + /* .MaxComputeAtomicCounters = */ 8, + /* .MaxComputeAtomicCounterBuffers = */ 1, + /* .MaxVaryingComponents = */ 60, + /* .MaxVertexOutputComponents = */ 64, + /* .MaxGeometryInputComponents = */ 64, + /* .MaxGeometryOutputComponents = */ 128, + /* .MaxFragmentInputComponents = */ 128, + /* .MaxImageUnits = */ 8, + /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, + /* .MaxCombinedShaderOutputResources = */ 8, + /* .MaxImageSamples = */ 0, + /* .MaxVertexImageUniforms = */ 0, + /* .MaxTessControlImageUniforms = */ 0, + /* .MaxTessEvaluationImageUniforms = */ 0, + /* .MaxGeometryImageUniforms = */ 0, + /* .MaxFragmentImageUniforms = */ 8, + /* .MaxCombinedImageUniforms = */ 8, + /* .MaxGeometryTextureImageUnits = */ 16, + /* .MaxGeometryOutputVertices = */ 256, + /* .MaxGeometryTotalOutputComponents = */ 1024, + /* .MaxGeometryUniformComponents = */ 1024, + /* .MaxGeometryVaryingComponents = */ 64, + /* .MaxTessControlInputComponents = */ 128, + /* .MaxTessControlOutputComponents = */ 128, + /* .MaxTessControlTextureImageUnits = */ 16, + /* .MaxTessControlUniformComponents = */ 1024, + /* .MaxTessControlTotalOutputComponents = */ 4096, + /* .MaxTessEvaluationInputComponents = */ 128, + /* .MaxTessEvaluationOutputComponents = */ 128, + /* .MaxTessEvaluationTextureImageUnits = */ 16, + /* .MaxTessEvaluationUniformComponents = */ 1024, + /* .MaxTessPatchComponents = */ 120, + /* .MaxPatchVertices = */ 32, + /* .MaxTessGenLevel = */ 64, + /* .MaxViewports = */ 16, + /* .MaxVertexAtomicCounters = */ 0, + /* .MaxTessControlAtomicCounters = */ 0, + /* .MaxTessEvaluationAtomicCounters = */ 0, + /* .MaxGeometryAtomicCounters = */ 0, + /* .MaxFragmentAtomicCounters = */ 8, + /* .MaxCombinedAtomicCounters = */ 8, + /* .MaxAtomicCounterBindings = */ 1, + /* .MaxVertexAtomicCounterBuffers = */ 0, + /* .MaxTessControlAtomicCounterBuffers = */ 0, + /* .MaxTessEvaluationAtomicCounterBuffers = */ 0, + /* .MaxGeometryAtomicCounterBuffers = */ 0, + /* .MaxFragmentAtomicCounterBuffers = */ 1, + /* .MaxCombinedAtomicCounterBuffers = */ 1, + /* .MaxAtomicCounterBufferSize = */ 16384, + /* .MaxTransformFeedbackBuffers = */ 4, + /* .MaxTransformFeedbackInterleavedComponents = */ 64, + /* .MaxCullDistances = */ 8, + /* .MaxCombinedClipAndCullDistances = */ 8, + /* .MaxSamples = */ 4, + /* .maxMeshOutputVerticesNV = */ 256, + /* .maxMeshOutputPrimitivesNV = */ 512, + /* .maxMeshWorkGroupSizeX_NV = */ 32, + /* .maxMeshWorkGroupSizeY_NV = */ 1, + /* .maxMeshWorkGroupSizeZ_NV = */ 1, + /* .maxTaskWorkGroupSizeX_NV = */ 32, + /* .maxTaskWorkGroupSizeY_NV = */ 1, + /* .maxTaskWorkGroupSizeZ_NV = */ 1, + /* .maxMeshViewCountNV = */ 4, + + /* .limits = */ { + /* .nonInductiveForLoops = */ 1, + /* .whileLoops = */ 1, + /* .doWhileLoops = */ 1, + /* .generalUniformIndexing = */ 1, + /* .generalAttributeMatrixVectorIndexing = */ 1, + /* .generalVaryingIndexing = */ 1, + /* .generalSamplerIndexing = */ 1, + /* .generalVariableIndexing = */ 1, + /* .generalConstantMatrixVectorIndexing = */ 1, +} }; + bool KRShaderManager::compileAll() { + bool success = true; if (!m_initializedGlslang) { glslang::InitializeProcess(); m_initializedGlslang = true; } - return true; + + KRSourceManager* pSourceManager = getContext().getSourceManager(); + const unordered_map vertSources = pSourceManager->get("vert"); + for (const std::pair vertSourceEntry : vertSources) { + KRSource* vertSource = vertSourceEntry.second; + KRSource* fragSource = pSourceManager->get(vertSourceEntry.first, "frag"); + const char* programName = vertSourceEntry.first.c_str(); + + TBuiltInResource resources; + resources = DefaultTBuiltInResource; + + EShMessages messages = EShMsgDefault; + bool desktop = true; + const int defaultVersion = desktop ? 110 : 100; + + glslang::TShader::ForbidIncluder includer; + glslang::TShader vertShader(EShLangVertex); + glslang::TShader fragShader(EShLangFragment); + glslang::TProgram program; // this must be declared after the TShader's to ensure it is deallocated before the TShader's + if (vertSource) { + vertSource->getData()->lock(); + } + if (fragSource) { + fragSource->getData()->lock(); + } + const char* vertSourceText[1]; + const char* fragSourceText[1]; + int vertSourceLen[1]; + int fragSourceLen[1]; + const char* vertSourceNameStr[1]; + const char* fragSourceNameStr[1]; + std::string vertSourceName; + std::string fragSourceName; + + auto parse_shader = [&](KRSource* source, glslang::TShader& shader, const char** sourceText, int* sourceLen, const char** sourceNameStr, std::string& sourceName) { + if(source == nullptr) { + return; + } + sourceName = source->getName() + "." + source->getExtension(); + sourceText[0] = (char *)source->getData()->getStart(); + sourceLen[0] = source->getData()->getSize(); + sourceNameStr[0] = sourceName.c_str(); + shader.setStringsWithLengthsAndNames(sourceText, sourceLen, sourceNameStr, 1); + //shader.setStrings(&sourceStr, 1); + + if (shader.parse(&resources, defaultVersion, false, messages)) { + program.addShader(&shader); + } else { + const char* log = shader.getInfoLog(); + printf("Failed to compile shader, %s. Log:\n%s\n", sourceName.c_str(), log); + success = false; + } + }; + + parse_shader(vertSource, vertShader, vertSourceText, vertSourceLen, vertSourceNameStr, vertSourceName); + parse_shader(fragSource, fragShader, fragSourceText, fragSourceLen, fragSourceNameStr, fragSourceName); + + if (!program.link(messages)) { + const char* log = program.getInfoLog(); + printf("Link failed. Log:\n%s\n", log); + success = false; + } + + if (vertSource) { + vertSource->getData()->unlock(); + } + if (fragSource) { + fragSource->getData()->unlock(); + } + } + + return success; }