Files
Seele/src/Engine/Graphics/Shader.h
T

145 lines
4.4 KiB
C++
Raw Normal View History

2023-10-26 18:37:29 +02:00
#pragma once
2023-11-01 13:38:49 +01:00
#include "CRC.h"
2024-06-09 12:20:04 +02:00
#include "Enums.h"
2023-11-01 23:12:30 +01:00
#include "Resources.h"
2023-11-05 10:36:01 +01:00
#include "VertexData.h"
2023-10-26 18:37:29 +02:00
2024-06-09 12:20:04 +02:00
namespace Seele {
namespace Gfx {
class Shader {};
2023-10-26 18:37:29 +02:00
DEFINE_REF(Shader)
2024-06-09 12:20:04 +02:00
class TaskShader {
public:
2023-10-26 18:37:29 +02:00
TaskShader() {}
virtual ~TaskShader() {}
};
DEFINE_REF(TaskShader)
2024-06-09 12:20:04 +02:00
class MeshShader {
public:
2023-10-26 18:37:29 +02:00
MeshShader() {}
virtual ~MeshShader() {}
};
DEFINE_REF(MeshShader)
2024-06-09 12:20:04 +02:00
class VertexShader {
public:
2023-10-26 18:37:29 +02:00
VertexShader() {}
virtual ~VertexShader() {}
};
DEFINE_REF(VertexShader)
2024-06-09 12:20:04 +02:00
class FragmentShader {
public:
2023-10-26 18:37:29 +02:00
FragmentShader() {}
virtual ~FragmentShader() {}
};
DEFINE_REF(FragmentShader)
2024-06-09 12:20:04 +02:00
class ComputeShader {
public:
2023-10-26 18:37:29 +02:00
ComputeShader() {}
virtual ~ComputeShader() {}
};
DEFINE_REF(ComputeShader)
2024-06-09 12:20:04 +02:00
// Uniquely identifies a permutation of shaders
// using the type parameters used to generate it
struct ShaderPermutation {
2023-11-05 10:36:01 +01:00
char taskFile[32];
char vertexMeshFile[32];
char fragmentFile[32];
char vertexDataName[32];
2023-11-27 22:50:37 +01:00
char materialName[64];
2024-05-01 19:05:48 +02:00
uint8 hasFragment;
uint8 useMeshShading;
uint8 hasTaskShader;
uint8 useMaterial;
2024-05-16 19:47:35 +02:00
uint8 positionOnly;
2024-05-23 14:58:14 +02:00
uint8 viewCulling;
2024-05-31 14:21:32 +02:00
uint8 visibilityPass;
2024-06-09 12:20:04 +02:00
// TODO: lightmapping etc
ShaderPermutation() { std::memset(this, 0, sizeof(ShaderPermutation)); }
void setTaskFile(std::string_view name) {
2023-11-09 22:15:51 +01:00
std::memset(taskFile, 0, sizeof(taskFile));
hasTaskShader = 1;
2024-01-16 19:24:49 +01:00
strncpy(taskFile, name.data(), sizeof(taskFile));
2023-11-09 22:15:51 +01:00
}
2024-06-09 12:20:04 +02:00
void setVertexFile(std::string_view name) {
2023-11-09 22:15:51 +01:00
std::memset(vertexMeshFile, 0, sizeof(vertexMeshFile));
useMeshShading = 0;
2024-01-16 19:24:49 +01:00
strncpy(vertexMeshFile, name.data(), sizeof(vertexMeshFile));
2023-11-09 22:15:51 +01:00
}
2024-06-09 12:20:04 +02:00
void setMeshFile(std::string_view name) {
2023-11-09 22:15:51 +01:00
std::memset(vertexMeshFile, 0, sizeof(vertexMeshFile));
useMeshShading = 1;
2024-01-16 19:24:49 +01:00
strncpy(vertexMeshFile, name.data(), sizeof(vertexMeshFile));
2023-11-09 22:15:51 +01:00
}
2024-06-09 12:20:04 +02:00
void setFragmentFile(std::string_view name) {
2023-11-09 22:15:51 +01:00
std::memset(fragmentFile, 0, sizeof(fragmentFile));
hasFragment = 1;
2024-01-16 19:24:49 +01:00
strncpy(fragmentFile, name.data(), sizeof(fragmentFile));
2023-11-09 22:15:51 +01:00
}
2024-06-09 12:20:04 +02:00
void setVertexData(std::string_view name) {
2023-11-09 22:15:51 +01:00
std::memset(vertexDataName, 0, sizeof(vertexDataName));
2024-01-16 19:24:49 +01:00
strncpy(vertexDataName, name.data(), sizeof(vertexDataName));
2023-11-09 22:15:51 +01:00
}
2024-06-09 12:20:04 +02:00
void setMaterial(std::string_view name) {
2023-11-09 22:15:51 +01:00
std::memset(materialName, 0, sizeof(materialName));
useMaterial = 1;
2024-01-16 19:24:49 +01:00
strncpy(materialName, name.data(), sizeof(materialName));
2023-11-09 22:15:51 +01:00
}
2024-06-09 12:20:04 +02:00
void setPositionOnly(bool enable) { positionOnly = enable; }
void setViewCulling(bool enable) { viewCulling = enable; }
void setVisibilityPass(bool enable) { visibilityPass = enable; }
2023-10-26 18:37:29 +02:00
};
2024-06-09 12:20:04 +02:00
// Hashed ShaderPermutation for fast lookup
struct PermutationId {
2023-10-26 18:37:29 +02:00
uint32 hash;
2024-06-09 12:20:04 +02:00
PermutationId() : hash(0) {}
PermutationId(ShaderPermutation permutation) : hash(CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32())) {}
friend constexpr bool operator==(const PermutationId& lhs, const PermutationId& rhs) { return lhs.hash == rhs.hash; }
friend constexpr auto operator<=>(const PermutationId& lhs, const PermutationId& rhs) { return lhs.hash <=> rhs.hash; }
2023-10-26 18:37:29 +02:00
};
2024-06-09 12:20:04 +02:00
struct ShaderCollection {
2024-04-19 18:23:36 +02:00
OPipelineLayout pipelineLayout;
2023-11-01 23:12:30 +01:00
OVertexShader vertexShader;
OTaskShader taskShader;
OMeshShader meshShader;
OFragmentShader fragmentShader;
2023-10-26 18:37:29 +02:00
};
2024-05-31 14:21:32 +02:00
2024-06-09 12:20:04 +02:00
struct PassConfig {
2024-05-31 14:21:32 +02:00
Gfx::PPipelineLayout baseLayout;
std::string taskFile = "";
std::string mainFile = "";
std::string fragmentFile = "";
bool hasFragmentShader = false;
bool useMeshShading = false;
bool hasTaskShader = false;
bool useMaterial = false;
bool useVisibility = false;
};
2024-06-09 12:20:04 +02:00
class ShaderCompiler {
public:
2023-11-05 10:36:01 +01:00
ShaderCompiler(Gfx::PGraphics graphics);
~ShaderCompiler();
const ShaderCollection* findShaders(PermutationId id) const;
void registerMaterial(PMaterial material);
void registerVertexData(VertexData* vertexData);
2024-05-31 14:21:32 +02:00
void registerRenderPass(std::string name, PassConfig config);
ShaderPermutation getTemplate(std::string name);
2024-06-09 12:20:04 +02:00
private:
2023-11-05 10:36:01 +01:00
void compile();
2024-04-19 18:23:36 +02:00
void createShaders(ShaderPermutation permutation, OPipelineLayout layout);
2023-10-26 18:37:29 +02:00
std::mutex shadersLock;
2023-11-05 10:36:01 +01:00
Map<PermutationId, ShaderCollection> shaders;
Map<std::string, PMaterial> materials;
Map<std::string, VertexData*> vertexData;
Map<std::string, PassConfig> passes;
Gfx::PGraphics graphics;
2023-10-26 18:37:29 +02:00
};
2023-11-05 10:36:01 +01:00
DEFINE_REF(ShaderCompiler)
2024-06-09 12:20:04 +02:00
} // namespace Gfx
2024-04-19 18:23:36 +02:00
} // namespace Seele