rpcsx/rpcs3/Emu/RSX/Common/ShaderParam.h
kd-11 6b96a2022a rsx: Add support for non-projective shadow sampling
- Fixes missing shadows in persona 5

vk: Enable polygon depth bias a.k.a polygonOffset
- Fixes shadow acne in persona 5
2017-09-21 16:17:06 +03:00

264 lines
5.3 KiB
C++

#pragma once
#include <string>
#include <vector>
#include "Utilities/StrUtil.h"
enum class FUNCTION {
FUNCTION_DP2,
FUNCTION_DP2A,
FUNCTION_DP3,
FUNCTION_DP4,
FUNCTION_DPH,
FUNCTION_SFL, // Set zero
FUNCTION_STR, // Set One
FUNCTION_FRACT,
FUNCTION_DFDX,
FUNCTION_DFDY,
FUNCTION_REFL,
FUNCTION_TEXTURE_SAMPLE1D,
FUNCTION_TEXTURE_SAMPLE1D_PROJ,
FUNCTION_TEXTURE_SAMPLE1D_LOD,
FUNCTION_TEXTURE_SAMPLE1D_GRAD,
FUNCTION_TEXTURE_SAMPLE2D,
FUNCTION_TEXTURE_SAMPLE2D_PROJ,
FUNCTION_TEXTURE_SAMPLE2D_LOD,
FUNCTION_TEXTURE_SAMPLE2D_GRAD,
FUNCTION_TEXTURE_SHADOW2D,
FUNCTION_TEXTURE_SHADOW2D_PROJ,
FUNCTION_TEXTURE_SAMPLECUBE,
FUNCTION_TEXTURE_SAMPLECUBE_PROJ,
FUNCTION_TEXTURE_SAMPLECUBE_LOD,
FUNCTION_TEXTURE_SAMPLECUBE_GRAD,
FUNCTION_TEXTURE_SAMPLE3D,
FUNCTION_TEXTURE_SAMPLE3D_PROJ,
FUNCTION_TEXTURE_SAMPLE3D_LOD,
FUNCTION_TEXTURE_SAMPLE3D_GRAD,
FUNCTION_VERTEX_TEXTURE_FETCH1D,
FUNCTION_VERTEX_TEXTURE_FETCH2D,
FUNCTION_VERTEX_TEXTURE_FETCH3D,
FUNCTION_VERTEX_TEXTURE_FETCHCUBE,
FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA
};
enum class COMPARE {
FUNCTION_SEQ,
FUNCTION_SGE,
FUNCTION_SGT,
FUNCTION_SLE,
FUNCTION_SLT,
FUNCTION_SNE,
};
enum ParamFlag
{
PF_PARAM_IN,
PF_PARAM_OUT,
PF_PARAM_UNIFORM,
PF_PARAM_CONST,
PF_PARAM_NONE,
PF_PARAM_COUNT,
};
struct ParamItem
{
std::string name;
std::string value;
int location;
ParamItem(const std::string& _name, int _location, const std::string& _value = "")
: name(_name)
, value(_value),
location(_location)
{ }
};
struct ParamType
{
const ParamFlag flag;
std::string type;
std::vector<ParamItem> items;
ParamType(const ParamFlag _flag, const std::string& _type)
: flag(_flag)
, type(_type)
{
}
bool SearchName(const std::string& name)
{
for (u32 i = 0; i<items.size(); ++i)
{
if (items[i].name.compare(name) == 0) return true;
}
return false;
}
};
struct ParamArray
{
std::vector<ParamType> params[PF_PARAM_COUNT];
ParamType* SearchParam(const ParamFlag &flag, const std::string& type)
{
for (u32 i = 0; i<params[flag].size(); ++i)
{
if (params[flag][i].type.compare(type) == 0)
return &params[flag][i];
}
return nullptr;
}
bool HasParamTypeless(const ParamFlag flag, const std::string& name)
{
for (u32 i = 0; i<params[flag].size(); ++i)
{
if (params[flag][i].SearchName(name))
return true;
}
return false;
}
bool HasParam(const ParamFlag flag, std::string type, const std::string& name)
{
ParamType* t = SearchParam(flag, type);
return t && t->SearchName(name);
}
std::string AddParam(const ParamFlag flag, std::string type, const std::string& name, const std::string& value)
{
ParamType* t = SearchParam(flag, type);
if (t)
{
if (!t->SearchName(name)) t->items.emplace_back(name, -1, value);
}
else
{
params[flag].emplace_back(flag, type);
params[flag].back().items.emplace_back(name, -1, value);
}
return name;
}
std::string AddParam(const ParamFlag flag, std::string type, const std::string& name, int location = -1)
{
ParamType* t = SearchParam(flag, type);
if (t)
{
if (!t->SearchName(name)) t->items.emplace_back(name, location);
}
else
{
params[flag].emplace_back(flag, type);
params[flag].back().items.emplace_back(name, location);
}
return name;
}
};
class ShaderVariable
{
public:
std::string name;
std::vector<std::string> swizzles;
ShaderVariable() = default;
ShaderVariable(const std::string& var)
{
auto var_blocks = fmt::split(var, { "." });
verify(HERE), (var_blocks.size() != 0);
name = var_blocks[0];
if (var_blocks.size() == 1)
{
swizzles.push_back("xyzw");
}
else
{
swizzles = std::vector<std::string>(var_blocks.begin() + 1, var_blocks.end());
}
}
size_t get_vector_size() const
{
return swizzles[swizzles.size() - 1].length();
}
ShaderVariable& symplify()
{
std::unordered_map<char, char> swizzle;
static std::unordered_map<int, char> pos_to_swizzle =
{
{ 0, 'x' },
{ 1, 'y' },
{ 2, 'z' },
{ 3, 'w' }
};
for (auto &i : pos_to_swizzle)
{
swizzle[i.second] = swizzles[0].length() > i.first ? swizzles[0][i.first] : 0;
}
for (int i = 1; i < swizzles.size(); ++i)
{
std::unordered_map<char, char> new_swizzle;
for (auto &sw : pos_to_swizzle)
{
new_swizzle[sw.second] = swizzle[swizzles[i].length() <= sw.first ? '\0' : swizzles[i][sw.first]];
}
swizzle = new_swizzle;
}
swizzles.clear();
std::string new_swizzle;
for (auto &i : pos_to_swizzle)
{
if (swizzle[i.second] != '\0')
new_swizzle += swizzle[i.second];
}
swizzles.push_back(new_swizzle);
return *this;
}
std::string get() const
{
if (swizzles.size() == 1 && swizzles[0] == "xyzw")
{
return name;
}
return name + "." + fmt::merge({ swizzles }, ".");
}
};
struct vertex_reg_info
{
std::string name; //output name
bool need_declare; //needs explicit declaration as output (not language in-built)
std::string src_reg; //reg to get data from
std::string src_reg_mask; //input swizzle mask
bool need_cast; //needs casting
std::string cond; //update on condition
std::string default_val; //fallback value on cond fail
std::string dst_alias; //output name override
bool check_mask; //check program output control mask for this output
u32 check_mask_value; //program output control mask for testing
};