File ComputeShader.cpp
File List > render > shaders > ComputeShader.cpp
Go to the documentation of this file
#include "ComputeShader.h"
std::unordered_map<std::string, std::shared_ptr<ComputeShader>> ComputeShader::comp_list = {};
std::unordered_map<std::string, std::vector<ComputeShader::Default>> ComputeShader::config_list = {};
void ComputeShader::PushDefult(std::string name, std::string para_name, AvailUnis def)
{
if (config_list.find(name) == config_list.end())
config_list[name] = std::vector<ComputeShader::Default>();
config_list[name].emplace_back(para_name, def);
}
void ComputeShader::PushDefult(std::string name, std::string para_name, GLuint _size, float* _data, ArrayType _type)
{
PushDefult(name, para_name, AvailUnis(Shaders::ArrayUni(_size, _data, _type)));
}
#include "xdz_math.h"
void ComputeShader::InitComputeLib(RenderConfigs* config)
{
static auto pos_offset = xdzm::rand3nv(16); // must be static
ComputeShader::ImportShaderConfigs("shadow/Shadow_Point", Uni("U_opt_flow", 6), Uni("Shadow_Map", 31));
ComputeShader::ImportShaderConfigs("shadow/Shadow_Sun", Uni("U_opt_flow", 6), Uni("Shadow_Map", 31));
ComputeShader::ImportShaderConfigs("shadow/Shadow_Spot", Uni("U_opt_flow", 6), Uni("Shadow_Map", 31));
ComputeShader::ImportShaderConfigs("shadow/Shadow_Area", Uni("U_opt_flow", 6), Uni("Shadow_Map", 31));
ComputeShader::ImportShaderConfigs("shadow/Shadow_Point_SDF", Uni("U_opt_flow", 6), Uni("Shadow_Map", 31));
ComputeShader::ImportShaderConfigs("shadow/Shadow_Sun_SDF", Uni("U_opt_flow", 6), Uni("Shadow_Map", 31));
// TODO: Shadow_Spot_SDF
ComputeShader::ImportShaderConfigs("shadow/Shadow_Area_SDF", Uni("U_opt_flow", 6), Uni("Shadow_Map", 31));
// TODO: Shadow_Area_VSSM
ComputeShader::ImportShaderConfigs("shadow/Shadow_Point_VSSM", Uni("U_opt_flow", 6), Uni("Shadow_Map", 31));
// TODO: Shadow_Spot_VSSM
ComputeShader::ImportShaderConfigs("shadow/Shadow_Sun_VSSM", Uni("U_opt_flow", 6), Uni("Shadow_Map", 31));
static std::vector<glm::vec3> kernel = xdzm::rand3hKernel(config->r_ao_ksize);
for (const auto& pref : ShaderLib::AO_prefix)
ComputeShader::ImportShaderConfigs("pps/" + pref + "AO", Uni("incre_average", true), Uni("kernel_length", GLuint(config->r_ao_ksize)), Uni("kernel", GLuint(config->r_ao_ksize), (float*)kernel.data(), VEC3_ARRAY), Uni("noise_size", 16), Uni("radius", config->r_ao_radius), Uni("U_opt_flow", 1));
for (const auto& pref : ShaderLib::SSR_prefix)
ComputeShader::ImportShaderConfigs("pps/SSR" + pref, Uni("U_pos", 1), Uni("U_dir_diff", 7), Uni("U_dir_spec", 8), Uni("U_ind_diff", 9), Uni("U_ind_spec", 10), Uni("U_emission", 11), Uni("U_opt_flow", 12), Uni("LTC1", 13));
}
void ComputeShader::ResetComputeLib()
{
comp_list.clear();
config_list.clear();
}
ComputeShader::ComputeShader(const std::string& name)
{
comp_shader.sh_name = name;
std::string code = Shaders::ReadShaderFile(COMPUTE_SHADER, name);
CreateShader(code);
comp_shader.sh_code = code;
comp_shader.sh_type = COMPUTE_SHADER;
ResetDefult(name);
}
ComputeShader::ComputeShader()
{
}
ComputeShader::~ComputeShader()
{
}
void ComputeShader::ResetID(ShaderType tar, GLuint _id)
{
if (comp_shader.sh_ID != _id)
glDeleteShader(comp_shader.sh_ID);
comp_shader.sh_ID = _id;
}
void ComputeShader::ResetDefult(std::string name)
{
if (ComputeShader::config_list.find(name) == ComputeShader::config_list.end()) {
DEBUG("no defult configs for: " + name);
return;
}
UseShader();
for (auto& [p_name, def] : ComputeShader::config_list[name]) {
std::visit([this, p_name](auto& p_value) {SetValue(p_name, p_value); }, def);
}
}
void ComputeShader::CreateShader(const std::string& compShader)
{
program_id = glCreateProgram();
comp_shader.sh_ID = CompileShaderCode(COMPUTE_SHADER, compShader);
glAttachShader(program_id, comp_shader.sh_ID);
glLinkProgram(program_id);
GLint linked = 0;
glGetProgramiv(program_id, GL_LINK_STATUS, &linked);
if (!linked) {
char log[4096];
glGetProgramInfoLog(program_id, sizeof(log), nullptr, log);
printf("Link error:\n%s\n", log);
}
}
void ComputeShader::ParseShaderCode(const std::string& _code, ShaderType tar)
{
if (tar == COMPUTE_SHADER)
comp_shader.sh_code = _code;
}
void ComputeShader::RelinkShader(ShaderType tar)
{
GLint program_id = glCreateProgram();
GLint shader_id = CompileShaderCode(COMPUTE_SHADER, comp_shader.sh_code);
glAttachShader(program_id, shader_id);
glLinkProgram(program_id);
_resetProgramID(program_id);
ResetID(COMPUTE_SHADER, shader_id);
GLint linked = 0;
glGetProgramiv(program_id, GL_LINK_STATUS, &linked);
if (!linked) {
char log[4096];
glGetProgramInfoLog(program_id, sizeof(log), nullptr, log);
printf("Link error:\n%s\n", log);
}
ResetDefult(comp_shader.sh_name);
}
Shaders::ShaderUnit* ComputeShader::GetShaderUnit(ShaderType tar /*= NONE_SHADER*/)
{
if (tar != COMPUTE_SHADER)
return nullptr;
return &comp_shader;
}
void ComputeShader::RunComputeShaderSCR(const glm::vec2& _scr_size, GLuint _batch, bool _edge_fix /*= true*/)
{
RunComputeShader(_scr_size / _batch + (_edge_fix ? glm::vec2(1) : glm::vec2(0)));
}
void ComputeShader::RunComputeShader(GLuint workgroup_count_x /*= 1*/, GLuint workgroup_count_y /*= 1*/, GLuint workgroup_count_z /*= 1*/) const
{
glDispatchCompute(workgroup_count_x, workgroup_count_y, workgroup_count_z);
glMemoryBarrier(GL_ALL_BARRIER_BITS);
}
void ComputeShader::RunComputeShader(const glm::vec2& _size)
{
UseShader();
RunComputeShader(GLuint(_size.x), GLuint(_size.y), 1);
UnuseShader();
}
GLuint ComputeShader::GetShaderID(ShaderType type) const
{
return comp_shader.sh_ID;
}
void ComputeShader::LocalDebug() const
{
#ifdef _DEBUG
//DEBUG(comp_shader)
#endif // _DEBUG
}
ComputeShader& ComputeShader::ImportShader(std::string _name)
{
return *ImportShaderSrc(_name).get();
}
std::shared_ptr<ComputeShader> ComputeShader::ImportShaderSrc(std::string _name)
{
if (comp_list.find(_name) != comp_list.end())
return comp_list[_name];
comp_list[_name] = std::make_shared<ComputeShader>(_name);
return comp_list[_name];
}
std::string ComputeShader::GetSSRShaderName(RenderConfigs* config)
{
int alg = (int)config->r_ssr_algorithm;
assert(alg < ShaderLib::SSR_prefix.size() && "unknown SSR type");
return "pps/SSR" + ShaderLib::SSR_prefix[alg];
}
std::string ComputeShader::GetAOShaderName(RenderConfigs* config)
{
int alg = (int)config->r_ao_algorithm;
assert(alg < ShaderLib::AO_prefix.size() && "unknown AO type");
return "pps/" + ShaderLib::AO_prefix[alg] + "AO";
}
std::string ComputeShader::GetAAShaderName(RenderConfigs* config)
{
int alg = (int)config->r_anti_alias;
assert(alg < ShaderLib::AA_prefix.size() && "unknown AA type");
return "pps/" + ShaderLib::AA_prefix[alg] + "AA";
}
std::string ComputeShader::GetShadowShaderName(char _type, char _light_type)
{
static std::string light_prefix[4] = { "_Point", "_Sun", "_Spot", "_Area" };
assert(_type < ShaderLib::Shadow_prefix.size());
assert(_type != 0);
return "shadow/Shadow" + light_prefix[_light_type] + ShaderLib::Shadow_prefix[_type];
}