diff --git a/lib/ivis_opengl/gfx_api.h b/lib/ivis_opengl/gfx_api.h index f823facaaef..d4de8c4be13 100644 --- a/lib/ivis_opengl/gfx_api.h +++ b/lib/ivis_opengl/gfx_api.h @@ -432,6 +432,8 @@ namespace gfx_api virtual bool supportsInstancedRendering() = 0; virtual void draw_instanced(const std::size_t& offset, const std::size_t &count, const primitive_type &primitive, std::size_t instance_count) = 0; virtual void draw_elements_instanced(const std::size_t& offset, const std::size_t& count, const primitive_type& primitive, const index_type& index, std::size_t instance_count) = 0; + // debug apis for recompiling pipelines + virtual bool debugRecompileAllPipelines() = 0; public: // High-level API for getting a texture object from file / uncompressed bitmap gfx_api::texture* loadTextureFromFile(const char *filename, gfx_api::texture_type textureType, int maxWidth = -1, int maxHeight = -1, bool quiet = false); diff --git a/lib/ivis_opengl/gfx_api_gl.cpp b/lib/ivis_opengl/gfx_api_gl.cpp index c9599cca4a0..daa1505bfc8 100644 --- a/lib/ivis_opengl/gfx_api_gl.cpp +++ b/lib/ivis_opengl/gfx_api_gl.cpp @@ -4361,6 +4361,20 @@ bool gl_context::setShadowConstants(gfx_api::lighting_constants newValues) return true; } +bool gl_context::debugRecompileAllPipelines() +{ + bool patchFragmentShaderMipLodBias = true; // provide the constant to the shader directly + for (auto& pipelineInfo : createdPipelines) + { + if (pipelineInfo.pso) + { + delete pipelineInfo.pso; + pipelineInfo.pso = new gl_pipeline_state_object(gles, fragmentHighpFloatAvailable, fragmentHighpIntAvailable, patchFragmentShaderMipLodBias, pipelineInfo.createInfo, mipLodBias, shadowConstants); + } + } + return true; +} + static const char *cbframebuffererror(GLenum err) { switch (err) diff --git a/lib/ivis_opengl/gfx_api_gl.h b/lib/ivis_opengl/gfx_api_gl.h index 45f377cd753..0b33b408fb5 100644 --- a/lib/ivis_opengl/gfx_api_gl.h +++ b/lib/ivis_opengl/gfx_api_gl.h @@ -348,6 +348,8 @@ struct gl_context final : public gfx_api::context virtual bool supportsInstancedRendering() override; virtual void draw_instanced(const std::size_t& offset, const std::size_t &count, const gfx_api::primitive_type &primitive, std::size_t instance_count) override; virtual void draw_elements_instanced(const std::size_t& offset, const std::size_t& count, const gfx_api::primitive_type& primitive, const gfx_api::index_type& index, std::size_t instance_count) override; + // debug apis for recompiling pipelines + virtual bool debugRecompileAllPipelines() override; private: virtual bool _initialize(const gfx_api::backend_Impl_Factory& impl, int32_t antialiasing, swap_interval_mode mode, optional mipLodBias, uint32_t depthMapResolution) override; void initPixelFormatsSupport(); diff --git a/lib/ivis_opengl/gfx_api_null.cpp b/lib/ivis_opengl/gfx_api_null.cpp index 0e7de7e99e6..c78d0ee0b1b 100644 --- a/lib/ivis_opengl/gfx_api_null.cpp +++ b/lib/ivis_opengl/gfx_api_null.cpp @@ -506,6 +506,11 @@ bool null_context::setShadowConstants(gfx_api::lighting_constants newValues) return true; } +bool null_context::debugRecompileAllPipelines() +{ + return true; +} + bool null_context::supportsInstancedRendering() { return false; diff --git a/lib/ivis_opengl/gfx_api_null.h b/lib/ivis_opengl/gfx_api_null.h index 2360d5c8024..5db017f96da 100644 --- a/lib/ivis_opengl/gfx_api_null.h +++ b/lib/ivis_opengl/gfx_api_null.h @@ -159,6 +159,8 @@ struct null_context final : public gfx_api::context virtual bool supportsInstancedRendering() override; virtual void draw_instanced(const std::size_t& offset, const std::size_t &count, const gfx_api::primitive_type &primitive, std::size_t instance_count) override; virtual void draw_elements_instanced(const std::size_t& offset, const std::size_t& count, const gfx_api::primitive_type& primitive, const gfx_api::index_type& index, std::size_t instance_count) override; + // debug apis for recompiling pipelines + virtual bool debugRecompileAllPipelines() override; private: virtual bool _initialize(const gfx_api::backend_Impl_Factory& impl, int32_t antialiasing, swap_interval_mode mode, optional mipLodBias, uint32_t depthMapResolution) override; private: diff --git a/lib/ivis_opengl/gfx_api_vk.cpp b/lib/ivis_opengl/gfx_api_vk.cpp index cc0912ff393..bdcaadb16b9 100644 --- a/lib/ivis_opengl/gfx_api_vk.cpp +++ b/lib/ivis_opengl/gfx_api_vk.cpp @@ -6185,4 +6185,26 @@ bool VkRoot::setShadowConstants(gfx_api::lighting_constants newValues) return true; } +bool VkRoot::debugRecompileAllPipelines() +{ + for (auto& pipelineInfo : createdPipelines) + { + for (size_t renderPassId = 0; renderPassId < pipelineInfo.renderPassPSO.size(); ++renderPassId) + { + auto pipeline = pipelineInfo.renderPassPSO[renderPassId]; + if (pipeline == nullptr) + { + continue; + } + + auto& renderPass = renderPasses[renderPassId]; + + ASSERT(pipeline->renderpass_compat, "Pipeline has no associated renderpass compat structure"); + buffering_mechanism::get_current_resources().pso_to_delete.emplace_back(pipeline); + pipelineInfo.renderPassPSO[renderPassId] = new VkPSO(dev, physDeviceProps.limits, pipelineInfo.createInfo, renderPass.rp, renderPass.rp_compat_info, renderPass.msaaSamples, vkDynLoader, *this); + } + } + return true; +} + #endif // defined(WZ_VULKAN_ENABLED) diff --git a/lib/ivis_opengl/gfx_api_vk.h b/lib/ivis_opengl/gfx_api_vk.h index 8859094a5e1..323990caae0 100644 --- a/lib/ivis_opengl/gfx_api_vk.h +++ b/lib/ivis_opengl/gfx_api_vk.h @@ -875,6 +875,8 @@ struct VkRoot final : gfx_api::context virtual bool supportsInstancedRendering() override; virtual void draw_instanced(const std::size_t& offset, const std::size_t &count, const gfx_api::primitive_type &primitive, std::size_t instance_count) override; virtual void draw_elements_instanced(const std::size_t& offset, const std::size_t& count, const gfx_api::primitive_type& primitive, const gfx_api::index_type& index, std::size_t instance_count) override; + // debug apis for recompiling pipelines + virtual bool debugRecompileAllPipelines() override; private: virtual bool _initialize(const gfx_api::backend_Impl_Factory& impl, int32_t antialiasing, swap_interval_mode mode, optional mipLodBias, uint32_t depthMapResolution) override; void initPixelFormatsSupport(); diff --git a/src/wzscriptdebug.cpp b/src/wzscriptdebug.cpp index 331b84fb364..65c55d9e5c9 100644 --- a/src/wzscriptdebug.cpp +++ b/src/wzscriptdebug.cpp @@ -927,16 +927,11 @@ class WzGraphicsPanel : public W_FORM debug(LOG_INFO, "Done"); }, prevButton); - prevButton = panel->createButton(1, "Recompile terrain", [](){ - debug(LOG_INFO, "Recompiling terrain"); - gfx_api::TerrainLayer::get().recompile(); + prevButton = panel->createButton(1, "Recompile All Shaders", [](){ + debug(LOG_INFO, "Recompiling all shader pipelines"); + gfx_api::context::get().debugRecompileAllPipelines(); debug(LOG_INFO, "Done"); }); - prevButton =panel->createButton(1, "Recompile decals", [](){ - debug(LOG_INFO, "Recompiling decals"); - gfx_api::TerrainDecals::get().recompile(); - debug(LOG_INFO, "Done"); - }, prevButton); prevButton =panel->createButton(1, "Recompile terrainCombined", [](){ debug(LOG_INFO, "Recompiling terrainCombined"); switch (getTerrainShaderQuality())