235 lines
5.3 KiB
C++
235 lines
5.3 KiB
C++
/* Copyright (c) 2019-2025, Arm Limited and Contributors
|
|
*
|
|
* 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/helpers.h"
|
|
#include "common/vk_common.h"
|
|
|
|
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
|
# undef None
|
|
#endif
|
|
|
|
namespace vkb
|
|
{
|
|
namespace core
|
|
{
|
|
template <vkb::BindingType bindingType>
|
|
class Device;
|
|
using DeviceC = Device<vkb::BindingType::C>;
|
|
} // namespace core
|
|
|
|
/// Types of shader resources
|
|
enum class ShaderResourceType
|
|
{
|
|
Input,
|
|
InputAttachment,
|
|
Output,
|
|
Image,
|
|
ImageSampler,
|
|
ImageStorage,
|
|
Sampler,
|
|
BufferUniform,
|
|
BufferStorage,
|
|
PushConstant,
|
|
SpecializationConstant,
|
|
All
|
|
};
|
|
|
|
/// This determines the type and method of how descriptor set should be created and bound
|
|
enum class ShaderResourceMode
|
|
{
|
|
Static,
|
|
Dynamic,
|
|
UpdateAfterBind
|
|
};
|
|
|
|
/// A bitmask of qualifiers applied to a resource
|
|
struct ShaderResourceQualifiers
|
|
{
|
|
enum : uint32_t
|
|
{
|
|
None = 0,
|
|
NonReadable = 1,
|
|
NonWritable = 2,
|
|
};
|
|
};
|
|
|
|
/// Store shader resource data.
|
|
/// Used by the shader module.
|
|
struct ShaderResource
|
|
{
|
|
VkShaderStageFlags stages;
|
|
|
|
ShaderResourceType type;
|
|
|
|
ShaderResourceMode mode;
|
|
|
|
uint32_t set;
|
|
|
|
uint32_t binding;
|
|
|
|
uint32_t location;
|
|
|
|
uint32_t input_attachment_index;
|
|
|
|
uint32_t vec_size;
|
|
|
|
uint32_t columns;
|
|
|
|
uint32_t array_size;
|
|
|
|
uint32_t offset;
|
|
|
|
uint32_t size;
|
|
|
|
uint32_t constant_id;
|
|
|
|
uint32_t qualifiers;
|
|
|
|
std::string name;
|
|
};
|
|
|
|
/**
|
|
* @brief Adds support for C style preprocessor macros to glsl shaders
|
|
* enabling you to define or undefine certain symbols
|
|
*/
|
|
class ShaderVariant
|
|
{
|
|
public:
|
|
ShaderVariant() = default;
|
|
|
|
size_t get_id() const;
|
|
|
|
/**
|
|
* @brief Specifies the size of a named runtime array for automatic reflection. If already specified, overrides the size.
|
|
* @param runtime_array_name String under which the runtime array is named in the shader
|
|
* @param size Integer specifying the wanted size of the runtime array (in number of elements, not size in bytes), used for automatic allocation of buffers.
|
|
* See get_declared_struct_size_runtime_array() in spirv_cross.h
|
|
*/
|
|
void add_runtime_array_size(const std::string &runtime_array_name, size_t size);
|
|
|
|
void set_runtime_array_sizes(const std::unordered_map<std::string, size_t> &sizes);
|
|
|
|
const std::unordered_map<std::string, size_t> &get_runtime_array_sizes() const;
|
|
|
|
void clear();
|
|
|
|
private:
|
|
size_t id;
|
|
|
|
std::unordered_map<std::string, size_t> runtime_array_sizes;
|
|
};
|
|
|
|
class ShaderSource
|
|
{
|
|
public:
|
|
ShaderSource() = default;
|
|
|
|
ShaderSource(const std::string &filename);
|
|
|
|
size_t get_id() const;
|
|
|
|
const std::string &get_filename() const;
|
|
|
|
void set_source(const std::string &source);
|
|
|
|
const std::string &get_source() const;
|
|
|
|
private:
|
|
size_t id;
|
|
|
|
std::string filename;
|
|
|
|
std::string source;
|
|
};
|
|
|
|
/**
|
|
* @brief Contains shader code, with an entry point, for a specific shader stage.
|
|
* It is needed by a PipelineLayout to create a Pipeline.
|
|
* ShaderModule can do auto-pairing between shader code and textures.
|
|
* The low level code can change bindings, just keeping the name of the texture.
|
|
* Variants for each texture are also generated, such as HAS_BASE_COLOR_TEX.
|
|
* It works similarly for attribute locations. A current limitation is that only set 0
|
|
* is considered. Uniform buffers are currently hardcoded as well.
|
|
*/
|
|
class ShaderModule
|
|
{
|
|
public:
|
|
ShaderModule(vkb::core::DeviceC &device,
|
|
VkShaderStageFlagBits stage,
|
|
const ShaderSource &shader_source,
|
|
const std::string &entry_point,
|
|
const ShaderVariant &shader_variant);
|
|
|
|
ShaderModule(const ShaderModule &) = delete;
|
|
|
|
ShaderModule(ShaderModule &&other);
|
|
|
|
ShaderModule &operator=(const ShaderModule &) = delete;
|
|
|
|
ShaderModule &operator=(ShaderModule &&) = delete;
|
|
|
|
size_t get_id() const;
|
|
|
|
VkShaderStageFlagBits get_stage() const;
|
|
|
|
const std::string &get_entry_point() const;
|
|
|
|
const std::vector<ShaderResource> &get_resources() const;
|
|
|
|
const std::vector<uint32_t> &get_binary() const;
|
|
|
|
inline const std::string &get_debug_name() const
|
|
{
|
|
return debug_name;
|
|
}
|
|
|
|
inline void set_debug_name(const std::string &name)
|
|
{
|
|
debug_name = name;
|
|
}
|
|
|
|
/**
|
|
* @brief Flags a resource to use a different method of being bound to the shader
|
|
* @param resource_name The name of the shader resource
|
|
* @param resource_mode The mode of how the shader resource will be bound
|
|
*/
|
|
void set_resource_mode(const std::string &resource_name, const ShaderResourceMode &resource_mode);
|
|
|
|
private:
|
|
vkb::core::DeviceC &device;
|
|
|
|
/// Shader unique id
|
|
size_t id;
|
|
|
|
/// Stage of the shader (vertex, fragment, etc)
|
|
VkShaderStageFlagBits stage{};
|
|
|
|
/// Name of the main function
|
|
std::string entry_point;
|
|
|
|
/// Human-readable name for the shader
|
|
std::string debug_name;
|
|
|
|
/// Compiled source
|
|
std::vector<uint32_t> spirv;
|
|
|
|
std::vector<ShaderResource> resources;
|
|
};
|
|
} // namespace vkb
|