diff options
author | Juan Linietsky <juan@godotengine.org> | 2019-07-28 19:58:32 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2020-02-11 11:53:29 +0100 |
commit | 4fe3ee1730167b90ec8ae70c871c1dad032981d5 (patch) | |
tree | 98b9f82d3a4defc1560245e40c0ba7b3a674fa81 /drivers/vulkan | |
parent | 60c7498cee169b2cd652045ec19bb526d76f9d61 (diff) |
Moved the shader source compilation code outside RenderingDevice and Vulkan
Diffstat (limited to 'drivers/vulkan')
-rw-r--r-- | drivers/vulkan/SCsub | 58 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.cpp | 283 | ||||
-rw-r--r-- | drivers/vulkan/rendering_device_vulkan.h | 7 |
3 files changed, 15 insertions, 333 deletions
diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub index 8ecfd47a0a..2251181704 100644 --- a/drivers/vulkan/SCsub +++ b/drivers/vulkan/SCsub @@ -4,63 +4,5 @@ Import('env') env.add_source_files(env.drivers_sources,"*.cpp") -# Thirdparty source files -# Not unbundled so far since not widespread as shared library -thirdparty_dir = "#thirdparty/glslang/" -thirdparty_sources = [ -"glslang/MachineIndependent/RemoveTree.cpp", -"glslang/MachineIndependent/ParseHelper.cpp", -"glslang/MachineIndependent/iomapper.cpp", -"glslang/MachineIndependent/propagateNoContraction.cpp", -"glslang/MachineIndependent/Intermediate.cpp", -"glslang/MachineIndependent/linkValidate.cpp", -"glslang/MachineIndependent/attribute.cpp", -"glslang/MachineIndependent/Scan.cpp", -"glslang/MachineIndependent/Initialize.cpp", -"glslang/MachineIndependent/Constant.cpp", -"glslang/MachineIndependent/reflection.cpp", -"glslang/MachineIndependent/limits.cpp", -"glslang/MachineIndependent/preprocessor/PpScanner.cpp", -"glslang/MachineIndependent/preprocessor/PpTokens.cpp", -"glslang/MachineIndependent/preprocessor/PpAtom.cpp", -"glslang/MachineIndependent/preprocessor/PpContext.cpp", -"glslang/MachineIndependent/preprocessor/Pp.cpp", -"glslang/MachineIndependent/InfoSink.cpp", -"glslang/MachineIndependent/intermOut.cpp", -"glslang/MachineIndependent/SymbolTable.cpp", -"glslang/MachineIndependent/glslang_tab.cpp", -"glslang/MachineIndependent/pch.cpp", -"glslang/MachineIndependent/Versions.cpp", -"glslang/MachineIndependent/ShaderLang.cpp", -"glslang/MachineIndependent/parseConst.cpp", -"glslang/MachineIndependent/PoolAlloc.cpp", -"glslang/MachineIndependent/ParseContextBase.cpp", -"glslang/MachineIndependent/IntermTraverse.cpp", -"glslang/GenericCodeGen/Link.cpp", -"glslang/GenericCodeGen/CodeGen.cpp", -"OGLCompilersDLL/InitializeDll.cpp", -"SPIRV/InReadableOrder.cpp", -"SPIRV/GlslangToSpv.cpp", -"SPIRV/SpvBuilder.cpp", -"SPIRV/SpvTools.cpp", -"SPIRV/disassemble.cpp", -"SPIRV/doc.cpp", -"SPIRV/SPVRemapper.cpp", -"SPIRV/SpvPostProcess.cpp", -"SPIRV/Logger.cpp" -] - -if (env["platform"]=="windows"): - thirdparty_sources.append("glslang/OSDependent/Windows/ossource.cpp") -else: - thirdparty_sources.append("glslang/OSDependent/Unix/ossource.cpp") - -thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - -env_thirdparty = env.Clone() -#env_thirdparty.disable_warnings() -env_thirdparty.add_source_files(env.drivers_sources, thirdparty_sources) - -env.Prepend(CPPPATH=[thirdparty_dir]) #SConscript("shaders/SCsub") diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 7f4ebd5134..f6154a3cbd 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -3,8 +3,6 @@ #include "core/os/file_access.h" #include "core/project_settings.h" #include "drivers/vulkan/vulkan_context.h" -#include "thirdparty/glslang/SPIRV/GlslangToSpv.h" -#include "thirdparty/glslang/glslang/Include/Types.h" #include "thirdparty/spirv-reflect/spirv_reflect.h" void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) { @@ -3212,103 +3210,6 @@ RID RenderingDeviceVulkan::index_array_create(RID p_index_buffer, uint32_t p_ind /**** SHADER ****/ /****************/ -static const TBuiltInResource default_builtin_resource = { - .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, - .limits = { - .nonInductiveForLoops = 1, - .whileLoops = 1, - .doWhileLoops = 1, - .generalUniformIndexing = 1, - .generalAttributeMatrixVectorIndexing = 1, - .generalVaryingIndexing = 1, - .generalSamplerIndexing = 1, - .generalVariableIndexing = 1, - .generalConstantMatrixVectorIndexing = 1, - } -}; - static const char *shader_stage_names[RenderingDevice::SHADER_STAGE_MAX] = { "Vertex", "Fragment", @@ -3347,7 +3248,7 @@ String RenderingDeviceVulkan::_shader_uniform_debug(RID p_shader, int p_set) { } return ret; } - +#if 0 bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLayoutBinding> > &bindings, Vector<Vector<UniformInfo> > &uniform_infos, const glslang::TObjectReflection &reflection, RenderingDevice::ShaderStage p_stage, Shader::PushConstant &push_constant, String *r_error) { VkDescriptorSetLayoutBinding layout_binding; @@ -3543,30 +3444,12 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa return true; } +#endif -RID RenderingDeviceVulkan::shader_create_from_source(const Vector<ShaderStageSource> &p_stages, String *r_error, ShaderStage *r_error_stage, bool p_allow_cache) { +RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages) { _THREAD_SAFE_METHOD_ - // initialize in case it's not initialized. This is done once per thread - // and it's safe to call multiple times - glslang::InitializeProcess(); - EShLanguage stages[SHADER_STAGE_MAX] = { - EShLangVertex, - EShLangFragment, - EShLangTessControl, - EShLangTessEvaluation, - EShLangCompute - }; - - int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 - glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_0; - glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0; - - Vector<std::vector<unsigned int> > spirv_code; - - glslang::TShader::ForbidIncluder includer; - //descriptor layouts Vector<Vector<VkDescriptorSetLayoutBinding> > set_bindings; Vector<Vector<UniformInfo> > uniform_info; @@ -3581,148 +3464,13 @@ RID RenderingDeviceVulkan::shader_create_from_source(const Vector<ShaderStageSou for (int i = 0; i < p_stages.size(); i++) { - if (stages_processed & (1 << p_stages[i].shader_stage)) { - if (r_error) { - (*r_error) = "Stage " + String(shader_stage_names[p_stages[i].shader_stage]) + " submitted more than once."; - } - return RID(); - } - glslang::TShader shader(stages[p_stages[i].shader_stage]); - CharString cs = p_stages[i].shader_source.utf8(); - const char *cs_strings = cs.get_data(); - shader.setStrings(&cs_strings, 1); - shader.setEnvInput(glslang::EShSourceGlsl, stages[p_stages[i].shader_stage], glslang::EShClientVulkan, ClientInputSemanticsVersion); - shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion); - shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion); - - EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); - const int DefaultVersion = 100; - std::string pre_processed_code; - - //preprocess - if (!shader.preprocess(&default_builtin_resource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) { - - if (r_error) { - (*r_error) = "Failed pre-processing on shader stage: " + String(shader_stage_names[p_stages[i].shader_stage]) + "\n"; - (*r_error) += shader.getInfoLog(); - (*r_error) += "\n"; - (*r_error) += shader.getInfoDebugLog(); - } - - if (r_error_stage) { - *r_error_stage = p_stages[i].shader_stage; - } - - return RID(); - } - //set back.. - cs_strings = pre_processed_code.c_str(); - shader.setStrings(&cs_strings, 1); - - //parse - if (!shader.parse(&default_builtin_resource, DefaultVersion, false, messages)) { - if (r_error) { - (*r_error) = "Failed parsing on shader stage: " + String(shader_stage_names[p_stages[i].shader_stage]) + "\n"; - (*r_error) += shader.getInfoLog(); - (*r_error) += "\n"; - (*r_error) += shader.getInfoDebugLog(); - } - if (r_error_stage) { - *r_error_stage = p_stages[i].shader_stage; - } - - return RID(); - } - - //link - glslang::TProgram program; - program.addShader(&shader); - - if (!program.link(messages)) { - if (r_error) { - (*r_error) = "Failed linking on shader stage: " + String(shader_stage_names[p_stages[i].shader_stage]) + "\n"; - (*r_error) += program.getInfoLog(); - (*r_error) += "\n"; - (*r_error) += program.getInfoDebugLog(); - } - if (r_error_stage) { - *r_error_stage = p_stages[i].shader_stage; - } - - return RID(); - } - -#if 0 - //obtain bindings for descriptor layout - program.mapIO(); - program.buildReflection(EShReflectionAllBlockVariables); - //program.dumpReflection(); - - for (int j = 0; j < program.getNumUniformBlocks(); j++) { - const glslang::TObjectReflection &reflection = program.getUniformBlock(j); - if (reflection.getType()->getBasicType() == glslang::EbtBlock && reflection.getType()->getQualifier().storage == glslang::EvqUniform && reflection.getType()->getQualifier().layoutPushConstant) { - uint32_t len = reflection.size; - if (push_constant_debug.push_constant_size != 0 && push_constant_debug.push_constant_size != len) { - print_line("eep"); - } - - push_constant_debug.push_constant_size = len; - push_constant_debug.push_constants_vk_stage |= shader_stage_masks[p_stages[i].shader_stage]; - //print_line("Debug stage " + String(shader_stage_names[p_stages[i].shader_stage]) + " push constant size: " + itos(push_constant_debug.push_constant_size)); - } - } - - - for (int j = 0; j < program.getNumUniformVariables(); j++) { - if (!_uniform_add_binding(bindings, uniform_info, program.getUniform(j), p_stages[i].shader_stage, push_constant, r_error)) { - return RID(); - } - } - - for (int j = 0; j < program.getNumUniformBlocks(); j++) { - if (!_uniform_add_binding(bindings, uniform_info, program.getUniformBlock(j), p_stages[i].shader_stage, push_constant, r_error)) { - return RID(); - } - } - - for (int j = 0; j < program.getNumBufferVariables(); j++) { - if (!_uniform_add_binding(bindings, uniform_info, program.getBufferVariable(j), p_stages[i].shader_stage, push_constant, r_error)) { - return RID(); - } - } - - for (int j = 0; j < program.getNumBufferBlocks(); j++) { - if (!_uniform_add_binding(bindings, uniform_info, program.getBufferBlock(j), p_stages[i].shader_stage, push_constant, r_error)) { - return RID(); - } - } - - if (p_stages[i].shader_stage == SHADER_STAGE_VERTEX) { - for (int j = 0; j < program.getNumPipeInputs(); j++) { - if (program.getPipeInput(i).getType()->getQualifier().hasLocation()) { - int location = program.getPipeInput(i).getType()->getQualifier().layoutLocation; - - if (vertex_input_locations.find(location) == -1) { - vertex_input_locations.push_back(location); - } - } - } - } - - if (p_stages[i].shader_stage == SHADER_STAGE_FRAGMENT) { - - fragment_outputs = program.getNumPipeOutputs(); - } - -#endif - std::vector<uint32_t> SpirV; - spv::SpvBuildLogger logger; - glslang::SpvOptions spvOptions; - glslang::GlslangToSpv(*program.getIntermediate(stages[p_stages[i].shader_stage]), SpirV, &logger, &spvOptions); + ERR_FAIL_COND_V_MSG(stages_processed & (1 << p_stages[i].shader_stage), RID(), + "Stage " + String(shader_stage_names[p_stages[i].shader_stage]) + " submitted more than once."); { SpvReflectShaderModule module; - SpvReflectResult result = spvReflectCreateShaderModule(SpirV.size() * sizeof(uint32_t), &SpirV[0], &module); + PoolVector<uint8_t>::Read spirv = p_stages[i].spir_v.read(); + SpvReflectResult result = spvReflectCreateShaderModule(p_stages[i].spir_v.size(), spirv.ptr(), &module); ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(), "Reflection of SPIR-V shader stage '" + String(shader_stage_names[p_stages[i].shader_stage]) + "' failed parsing shader."); @@ -3941,8 +3689,6 @@ RID RenderingDeviceVulkan::shader_create_from_source(const Vector<ShaderStageSou spvReflectDestroyShaderModule(&module); } - spirv_code.push_back(SpirV); - stages_processed |= (1 << p_stages[i].shader_stage); } @@ -3962,8 +3708,10 @@ RID RenderingDeviceVulkan::shader_create_from_source(const Vector<ShaderStageSou shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shader_module_create_info.pNext = NULL; shader_module_create_info.flags = 0; - shader_module_create_info.codeSize = spirv_code[i].size() * sizeof(uint32_t); - shader_module_create_info.pCode = &spirv_code[i][0]; + shader_module_create_info.codeSize = p_stages[i].spir_v.size(); + PoolVector<uint8_t>::Read r = p_stages[i].spir_v.read(); + + shader_module_create_info.pCode = (const uint32_t *)r.ptr(); VkShaderModule module; VkResult res = vkCreateShaderModule(device, &shader_module_create_info, NULL, &module); @@ -4087,14 +3835,7 @@ RID RenderingDeviceVulkan::shader_create_from_source(const Vector<ShaderStageSou vkDestroyDescriptorSetLayout(device, shader.sets[i].descriptor_set_layout, NULL); } - if (r_error) { - *r_error = error_text; - } - if (r_error_stage) { - *r_error_stage = SHADER_STAGE_MAX; - } - - return RID(); + ERR_FAIL_V_MSG(RID(), error_text); } return shader_owner.make_rid(shader); diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 2420e62aab..5b3b7a5f47 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -5,7 +5,7 @@ #include "core/os/thread_safe.h" #include "core/rid_owner.h" #include "servers/visual/rendering_device.h" -#include "thirdparty/glslang/glslang/Public/ShaderLang.h" + #ifdef DEBUG_ENABLED #define _DEBUG #endif @@ -494,7 +494,6 @@ class RenderingDeviceVulkan : public RenderingDevice { }; String _shader_uniform_debug(RID p_shader, int p_set = -1); - bool _uniform_add_binding(Vector<Vector<VkDescriptorSetLayoutBinding> > &bindings, Vector<Vector<UniformInfo> > &uniform_infos, const glslang::TObjectReflection &reflection, RenderingDevice::ShaderStage p_stage, Shader::PushConstant &push_constant, String *r_error); RID_Owner<Shader> shader_owner; @@ -608,7 +607,7 @@ class RenderingDeviceVulkan : public RenderingDevice { // was not supplied as intended. struct RenderPipeline { - //Cached values for validation + //Cached values for validation #ifdef DEBUG_ENABLED struct Validation { FramebufferFormatID framebuffer_format; @@ -853,7 +852,7 @@ public: /**** SHADER ****/ /****************/ - virtual RID shader_create_from_source(const Vector<ShaderStageSource> &p_stages, String *r_error = NULL, ShaderStage *r_error_stage = NULL, bool p_allow_cache = true); + virtual RID shader_create(const Vector<ShaderStageData> &p_stages); virtual Vector<int> shader_get_vertex_input_locations_used(RID p_shader); /*****************/ |