Skip to content

Commit

Permalink
Add new plugin: real time shader selection (#733)
Browse files Browse the repository at this point in the history
* Add new plugin real time shader selection

* Add new plugin real time shader selection

* Add new plugin: real time shader selection

* Add new plugin: real time shader selection

* Add new plugin: real time shader selection

* Remove unnecessary code after merge.

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>

* Remove plugin support for Samples.

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>

* Fix return value and code style.

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>

* Add missing new line.

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>

* Remove unneeded shaders.

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>

* Remove unneeded copyright.

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>

* Fix copyright year.

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>

* Remove unneeded changes.

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>

* Update copyright year.

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>

* Fix build issues in hpp_oit_linked_lists sample

* Update copyright year

* Fix formatting

* Remove unnecessary copyright year updates and add missing blank line
in "dynamic_uniform_buffers.cpp"

* Small change to re-trigger CI checks

* Revert "Small change to re-trigger CI checks"

This reverts commit 5051505.

---------

Signed-off-by: pawel-jastrzebski-mobica <[email protected]>
Co-authored-by: Dawid Lorenz <[email protected]>
Co-authored-by: pawel-jastrzebski-mobica <[email protected]>
Co-authored-by: Seweryn Zielas <[email protected]>
  • Loading branch information
4 people authored Feb 27, 2024
1 parent 4353c55 commit 8ee282f
Show file tree
Hide file tree
Showing 44 changed files with 823 additions and 707 deletions.
1 change: 1 addition & 0 deletions .copyrightignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ khrplatform.h
clang_format.py
run-clang-tidy.py
package-list.txt
.spv
.pre-commit-config.yaml
106 changes: 106 additions & 0 deletions app/plugins/real_time_shader_selection/real_time_shader_selection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* Copyright (c) 2024, Mobica Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "real_time_shader_selection.h"

#include "platform/platform.h"

namespace plugins
{
RealTimeShaderSelection::RealTimeShaderSelection() :
RealTimeShaderSelectionTags("Real Time Shader Selection",
"Enable dynamic shader selection for samples.",
{vkb::Hook::OnAppStart, vkb::Hook::OnUpdateUi},
{&realtimeshaderselection_flag}),
active_shader(0),
min_size_for_shaders(2)
{
}

bool RealTimeShaderSelection::is_active(const vkb::CommandParser &parser)
{
return parser.contains(&realtimeshaderselection_flag);
}

void RealTimeShaderSelection::init(const vkb::CommandParser &parser)
{
}

void RealTimeShaderSelection::on_app_start(const std::string &app_info)
{
if (platform->get_app().get_available_shaders().size() < min_size_for_shaders)
{
LOGE("Sample doesn't support RealTimeShaderSelection plugin, sample should add available shaders please see Application::store_shaders.");
LOGE("Sample, defined {} shaders, minimum number of defined shaders is {}", platform->get_app().get_available_shaders().size(), min_size_for_shaders);
return;
}

for (auto const &shader : platform->get_app().get_available_shaders())
{
switch (shader.first)
{
case vkb::ShaderSourceLanguage::GLSL:
language_names.emplace_back("GLSL");
break;
case vkb::ShaderSourceLanguage::HLSL:
language_names.emplace_back("HLSL");
break;
case vkb::ShaderSourceLanguage::SPV:
language_names.emplace_back("SPV");
break;
default:
LOGE("Not supported shader language");
assert(false);
}
}
}

void RealTimeShaderSelection::on_update_ui_overlay(vkb::Drawer &drawer)
{
if (platform->get_app().get_available_shaders().size() >= min_size_for_shaders)
{
if (drawer.header("Real Time Shader Selection"))
{
if (drawer.combo_box("Shader language", &active_shader, language_names))
{
std::string selectedShader = language_names[active_shader];
vkb::ShaderSourceLanguage shaderType = vkb::ShaderSourceLanguage::GLSL;
if (selectedShader == "GLSL")
{
shaderType = vkb::ShaderSourceLanguage::GLSL;
}
else if (selectedShader == "HLSL")
{
shaderType = vkb::ShaderSourceLanguage::HLSL;
}
else if (selectedShader == "SPV")
{
shaderType = vkb::ShaderSourceLanguage::SPV;
}
else
{
LOGE("Not supported shader language");
assert(false);
}
auto it = platform->get_app().get_available_shaders().find(shaderType);
platform->get_app().change_shader(it->first);
}
}
}
}

} // namespace plugins
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* Copyright (c) 2024, Mobica Limited
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "common/vk_common.h"
#include "platform/plugins/plugin_base.h"
#include <map>
#include <vector>

namespace plugins
{
class RealTimeShaderSelection;

// Passive behaviour
using RealTimeShaderSelectionTags = vkb::PluginBase<RealTimeShaderSelection, vkb::tags::Passive>;

/**
* @brief Real Time Shader Selection
*
* When this option is enabled, the samples get the ability to dynamically choose which shaders are available for a given sample.
*
* Usage: vulkan_samples sample afbc --realtimeshaderselection
*
*/
class RealTimeShaderSelection : public RealTimeShaderSelectionTags
{
public:
RealTimeShaderSelection();

virtual ~RealTimeShaderSelection() = default;

virtual bool is_active(const vkb::CommandParser &parser) override;

virtual void init(const vkb::CommandParser &parser) override;

virtual void on_app_start(const std::string &app_info) override;

virtual void on_update_ui_overlay(vkb::Drawer &drawer) override;

vkb::FlagCommand realtimeshaderselection_flag = {vkb::FlagType::FlagOnly, "realtimeshaderselection", "", "Enable dynamic shader selection"};

private:
std::vector<std::string> language_names;
int active_shader;
const int min_size_for_shaders;
};
} // namespace plugins
2 changes: 2 additions & 0 deletions framework/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ project(framework LANGUAGES C CXX)
set(FRAMEWORK_FILES
# Header Files
gui.h
drawer.h
glsl_compiler.h
spirv_reflection.h
gltf_loader.h
Expand Down Expand Up @@ -52,6 +53,7 @@ set(FRAMEWORK_FILES
hpp_vulkan_sample.h
# Source Files
gui.cpp
drawer.cpp
glsl_compiler.cpp
spirv_reflection.cpp
gltf_loader.cpp
Expand Down
11 changes: 5 additions & 6 deletions framework/api_vulkan_sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ void ApiVulkanSample::update(float delta_time)
view_changed();
}

update_overlay(delta_time);

render(delta_time);
camera.update(delta_time);
if (camera.moving())
Expand Down Expand Up @@ -437,24 +435,25 @@ void ApiVulkanSample::create_pipeline_cache()
VK_CHECK(vkCreatePipelineCache(device->get_handle(), &pipeline_cache_create_info, nullptr, &pipeline_cache));
}

VkPipelineShaderStageCreateInfo ApiVulkanSample::load_shader(const std::string &file, VkShaderStageFlagBits stage)
VkPipelineShaderStageCreateInfo ApiVulkanSample::load_shader(const std::string &file, VkShaderStageFlagBits stage, vkb::ShaderSourceLanguage src_language)
{
VkPipelineShaderStageCreateInfo shader_stage = {};
shader_stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shader_stage.stage = stage;
shader_stage.module = vkb::load_shader(file.c_str(), device->get_handle(), stage);
shader_stage.module = vkb::load_shader(file.c_str(), device->get_handle(), stage, src_language);
shader_stage.pName = "main";
assert(shader_stage.module != VK_NULL_HANDLE);
shader_modules.push_back(shader_stage.module);
return shader_stage;
}

void ApiVulkanSample::update_overlay(float delta_time)
void ApiVulkanSample::update_overlay(float delta_time, const std::function<void()> &additional_ui)
{
if (gui)
{
gui->show_simple_window(get_name(), vkb::to_u32(1.0f / delta_time), [this]() {
gui->show_simple_window(get_name(), vkb::to_u32(1.0f / delta_time), [this, additional_ui]() {
on_update_ui_overlay(gui->get_drawer());
additional_ui();
});

gui->update(delta_time);
Expand Down
5 changes: 4 additions & 1 deletion framework/api_vulkan_sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ class ApiVulkanSample : public vkb::VulkanSample

virtual void update(float delta_time) override;

virtual void update_overlay(float delta_time, const std::function<void()> &additional_ui) override;

virtual bool resize(const uint32_t width, const uint32_t height) override;

virtual void render(float delta_time) = 0;
Expand Down Expand Up @@ -347,8 +349,9 @@ class ApiVulkanSample : public vkb::VulkanSample
* @brief Load a SPIR-V shader
* @param file The file location of the shader relative to the shaders folder
* @param stage The shader stage
* @param src_language The shader language
*/
VkPipelineShaderStageCreateInfo load_shader(const std::string &file, VkShaderStageFlagBits stage);
VkPipelineShaderStageCreateInfo load_shader(const std::string &file, VkShaderStageFlagBits stage, vkb::ShaderSourceLanguage src_language = vkb::ShaderSourceLanguage::GLSL);

/**
* @brief Updates the overlay
Expand Down
4 changes: 2 additions & 2 deletions framework/common/hpp_vk_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ inline bool is_dynamic_buffer_descriptor_type(vk::DescriptorType descriptor_type
return vkb::is_dynamic_buffer_descriptor_type(static_cast<VkDescriptorType>(descriptor_type));
}

inline vk::ShaderModule load_shader(const std::string &filename, vk::Device device, vk::ShaderStageFlagBits stage)
inline vk::ShaderModule load_shader(const std::string &filename, vk::Device device, vk::ShaderStageFlagBits stage, ShaderSourceLanguage src_language = ShaderSourceLanguage::GLSL)
{
return static_cast<vk::ShaderModule>(vkb::load_shader(filename, device, static_cast<VkShaderStageFlagBits>(stage)));
return static_cast<vk::ShaderModule>(vkb::load_shader(filename, device, static_cast<VkShaderStageFlagBits>(stage), src_language));
}

inline void image_layout_transition(vk::CommandBuffer command_buffer,
Expand Down
33 changes: 23 additions & 10 deletions framework/common/vk_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,24 +374,37 @@ int32_t get_bits_per_pixel(VkFormat format)
}
}

VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage)
VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage, vkb::ShaderSourceLanguage src_language)
{
vkb::GLSLCompiler glsl_compiler;

auto buffer = vkb::fs::read_shader_binary(filename);
auto buffer = vkb::fs::read_shader_binary(filename);
std::vector<uint32_t> spirv;

std::string file_ext = filename;
if (vkb::ShaderSourceLanguage::GLSL == src_language)
{
std::string file_ext = filename;

// Extract extension name from the glsl shader file
file_ext = file_ext.substr(file_ext.find_last_of(".") + 1);
// Extract extension name from the glsl shader file
file_ext = file_ext.substr(file_ext.find_last_of(".") + 1);

std::vector<uint32_t> spirv;
std::string info_log;
std::string info_log;

// Compile the GLSL source
if (!glsl_compiler.compile_to_spirv(vkb::find_shader_stage(file_ext), buffer, "main", {}, spirv, info_log))
// Compile the GLSL source
if (!glsl_compiler.compile_to_spirv(vkb::find_shader_stage(file_ext), buffer, "main", {}, spirv, info_log))
{
LOGE("Failed to compile shader, Error: {}", info_log.c_str());
return VK_NULL_HANDLE;
}
}
else if (vkb::ShaderSourceLanguage::SPV == src_language)
{
spirv = std::vector<uint32_t>(reinterpret_cast<uint32_t *>(buffer.data()),
reinterpret_cast<uint32_t *>(buffer.data()) + buffer.size() / sizeof(uint32_t));
}
else
{
LOGE("Failed to compile shader, Error: {}", info_log.c_str());
LOGE("The format is not supported");
return VK_NULL_HANDLE;
}

Expand Down
11 changes: 10 additions & 1 deletion framework/common/vk_common.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Copyright (c) 2018-2024, Arm Limited and Contributors
* Copyright (c) 2019-2024, Sascha Willems
* Copyright (c) 2024, Mobica Limited
*
* SPDX-License-Identifier: Apache-2.0
*
Expand Down Expand Up @@ -105,14 +106,22 @@ bool is_buffer_descriptor_type(VkDescriptorType descriptor_type);
*/
int32_t get_bits_per_pixel(VkFormat format);

enum class ShaderSourceLanguage
{
GLSL,
HLSL,
SPV,
};

/**
* @brief Helper function to create a VkShaderModule
* @param filename The shader location
* @param device The logical device
* @param stage The shader stage
* @param src_language The shader language
* @return The string to return.
*/
VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage);
VkShaderModule load_shader(const std::string &filename, VkDevice device, VkShaderStageFlagBits stage, ShaderSourceLanguage src_language = ShaderSourceLanguage::GLSL);

/**
* @brief Helper function to select a VkSurfaceFormatKHR
Expand Down
Loading

0 comments on commit 8ee282f

Please sign in to comment.