engine/engine/inc/uf/ext/vulkan/shader.h

173 lines
6.6 KiB
C++

#pragma once
#include <uf/ext/vulkan/device.h>
#include <uf/ext/vulkan/swapchain.h>
#include <uf/ext/vulkan/initializers.h>
#include <uf/ext/vulkan/texture.h>
#include <uf/utils/mesh/mesh.h>
#define UF_GRAPHIC_POINTERED_USERDATA 1
#define IS_DYNAMIC(name) true
// name.ends_with("_d")
namespace ext {
namespace vulkan {
#if UF_GRAPHIC_POINTERED_USERDATA
typedef uf::PointeredUserdata userdata_t;
#else
typedef uf::Userdata userdata_t;
#endif
ext::json::Value definitionToJson(/*const*/ ext::json::Value& definition );
ext::vulkan::userdata_t jsonToUserdata( const ext::json::Value& payload, const ext::json::Value& definition );
struct RenderMode;
struct UF_API Shader : public Buffers {
bool aliased = false;
Device* device = NULL;
uf::stl::string filename = "";
VkShaderModule module = VK_NULL_HANDLE;
VkPipelineShaderStageCreateInfo descriptor = {};
uf::stl::map<size_t, uf::stl::vector<VkDescriptorSetLayoutBinding>> descriptorSetLayoutBindings;
uf::stl::vector<VkSpecializationMapEntry> specializationMapEntries;
VkSpecializationInfo specializationInfo = {};
struct Metadata {
uf::Serializer json;
uf::stl::string pipeline = "";
uf::stl::string type = "";
bool autoInitializeUniformBuffers = true;
bool autoInitializeUniformUserdatas = false;
struct Definition {
uf::stl::string name = "";
uint32_t index = 0;
uint32_t set = 0;
uint32_t binding = 0;
uint32_t size = 0;
// int32_t buffer = -1;
ext::vulkan::enums::Image::viewType_t type{};
};
struct Definitions {
// unused?
typedef Metadata::Definition InOut;
typedef Metadata::Definition Texture;
typedef Metadata::Definition Uniform;
typedef Metadata::Definition Storage;
typedef Metadata::Definition AccelerationStructure;
typedef Metadata::Definition PushConstant;
struct SpecializationConstants {
uf::stl::string name = "";
uint32_t index = 0;
uf::stl::string type = "";
bool validate = false;
union {
int32_t i;
uint32_t ui;
float f;
} value;
};
uf::stl::unordered_map<uf::stl::string, InOut> inputs;
uf::stl::unordered_map<uf::stl::string, InOut> outputs;
uf::stl::unordered_map<uf::stl::string, Texture> textures;
uf::stl::unordered_map<uf::stl::string, Uniform> uniforms;
uf::stl::unordered_map<uf::stl::string, Storage> storage;
uf::stl::unordered_map<uf::stl::string, AccelerationStructure> accelerationStructure;
uf::stl::unordered_map<uf::stl::string, PushConstant> pushConstants;
uf::stl::unordered_map<uf::stl::string, SpecializationConstants> specializationConstants;
pod::Vector3ui localSize{};
} definitions;
// to automatically grab attachments from the target renderMode
struct AttachmentDescriptor {
uf::stl::string name{};
const ext::vulkan::RenderMode* renderMode{};
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
VkFilter filter = VK_FILTER_NEAREST;
};
struct BufferDescriptor {
uf::stl::string name{};
ext::vulkan::Buffer fallback;
const ext::vulkan::RenderMode* renderMode{};
VkBufferUsageFlags flags{};
};
struct {
uf::stl::vector<AttachmentDescriptor> attachments;
uf::stl::vector<BufferDescriptor> buffers;
} aliases;
uf::stl::vector<uint32_t> dynamicRanges;
} metadata;
ext::vulkan::userdata_t specializationConstants;
uf::stl::vector<ext::vulkan::userdata_t> pushConstants;
uf::stl::vector<ext::vulkan::userdata_t> uniforms;
// for per-shader texture allotment, needed for our bloom pipeline
uf::stl::vector<Texture2D> textures;
// ~Shader();
void initialize( Device& device, const uf::stl::string&, VkShaderStageFlagBits );
void destroy();
bool validate();
bool hasAttachment( const uf::stl::string& name );
void aliasAttachment( const Metadata::AttachmentDescriptor& descriptor );
void aliasAttachment( const uf::stl::string& name, const ext::vulkan::RenderMode* renderMode = NULL, VkImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, VkFilter filter = VK_FILTER_NEAREST );
bool hasBuffer( const uf::stl::string& name );
void aliasBuffer( const Metadata::BufferDescriptor& descriptor );
void aliasBuffer( const ext::vulkan::Buffer& buffer );
void aliasBuffer( const uf::stl::string& name, const ext::vulkan::Buffer& = {}, const ext::vulkan::RenderMode* renderMode = NULL, VkBufferUsageFlags = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT );
bool hasUniform( const uf::stl::string& name ) const;
Buffer& getUniformBuffer( const uf::stl::string& name );
const Buffer& getUniformBuffer( const uf::stl::string& name ) const;
ext::vulkan::userdata_t& getUniform( const uf::stl::string& name );
const ext::vulkan::userdata_t& getUniform( const uf::stl::string& name ) const ;
bool updateUniform( const uf::stl::string& name, const void*, size_t ) const;
inline bool updateUniform( const uf::stl::string& name ) const {
if ( !hasUniform(name) ) return false;
return updateUniform(name, getUniform(name));
}
inline bool updateUniform( const uf::stl::string& name, const ext::vulkan::userdata_t& userdata ) const {
return updateUniform(name, (const void*) userdata, userdata.size() );
}
bool hasStorage( const uf::stl::string& name ) const;
Buffer& getStorageBuffer( const uf::stl::string& name );
const Buffer& getStorageBuffer( const uf::stl::string& name ) const;
bool updateStorage( const uf::stl::string& name, const void*, size_t ) const;
inline bool updateStorage( const uf::stl::string& name, const ext::vulkan::userdata_t& userdata ) const {
return updateStorage(name, (const void*) userdata, userdata.size() );
}
void setSpecializationConstants( const uf::stl::unordered_map<uf::stl::string, uint32_t>& values );
void setDescriptorCounts( const uf::stl::unordered_map<uf::stl::string, uint32_t>& values );
Metadata::Definition getDefinition( const uf::stl::string& );
/*
uf::Serializer getUniformJson( const uf::stl::string& name, bool cache = true );
bool updateUniform( const uf::stl::string& name, const ext::json::Value& payload );
ext::vulkan::userdata_t getUniformUserdata( const uf::stl::string& name, const ext::json::Value& payload );
uf::Serializer getStorageJson( const uf::stl::string& name, bool cache = true );
ext::vulkan::userdata_t getStorageUserdata( const uf::stl::string& name, const ext::json::Value& payload );
*/
};
}
}