mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-08 07:51:28 +12:00
rsx/vp: CodeGen improvements
- Fix double destination writes on conditional write masking - Fix codegen to simplify simple scalar comparisons vs vector functions
This commit is contained in:
parent
2c34195954
commit
d78957d1cf
10 changed files with 87 additions and 39 deletions
|
@ -110,23 +110,45 @@ namespace glsl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string compareFunctionImpl(COMPARE f, const std::string &Op0, const std::string &Op1)
|
static std::string compareFunctionImpl(COMPARE f, const std::string &Op0, const std::string &Op1, bool scalar = false)
|
||||||
{
|
{
|
||||||
switch (f)
|
if (scalar)
|
||||||
{
|
{
|
||||||
case COMPARE::FUNCTION_SEQ:
|
switch (f)
|
||||||
return "equal(" + Op0 + ", " + Op1 + ")";
|
{
|
||||||
case COMPARE::FUNCTION_SGE:
|
case COMPARE::FUNCTION_SEQ:
|
||||||
return "greaterThanEqual(" + Op0 + ", " + Op1 + ")";
|
return Op0 + " == " + Op1;
|
||||||
case COMPARE::FUNCTION_SGT:
|
case COMPARE::FUNCTION_SGE:
|
||||||
return "greaterThan(" + Op0 + ", " + Op1 + ")";
|
return Op0 + " >= " + Op1;
|
||||||
case COMPARE::FUNCTION_SLE:
|
case COMPARE::FUNCTION_SGT:
|
||||||
return "lessThanEqual(" + Op0 + ", " + Op1 + ")";
|
return Op0 + " > " + Op1;
|
||||||
case COMPARE::FUNCTION_SLT:
|
case COMPARE::FUNCTION_SLE:
|
||||||
return "lessThan(" + Op0 + ", " + Op1 + ")";
|
return Op0 + " <= " + Op1;
|
||||||
case COMPARE::FUNCTION_SNE:
|
case COMPARE::FUNCTION_SLT:
|
||||||
return "notEqual(" + Op0 + ", " + Op1 + ")";
|
return Op0 + " < " + Op1;
|
||||||
|
case COMPARE::FUNCTION_SNE:
|
||||||
|
return Op0 + " != " + Op1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (f)
|
||||||
|
{
|
||||||
|
case COMPARE::FUNCTION_SEQ:
|
||||||
|
return "equal(" + Op0 + ", " + Op1 + ")";
|
||||||
|
case COMPARE::FUNCTION_SGE:
|
||||||
|
return "greaterThanEqual(" + Op0 + ", " + Op1 + ")";
|
||||||
|
case COMPARE::FUNCTION_SGT:
|
||||||
|
return "greaterThan(" + Op0 + ", " + Op1 + ")";
|
||||||
|
case COMPARE::FUNCTION_SLE:
|
||||||
|
return "lessThanEqual(" + Op0 + ", " + Op1 + ")";
|
||||||
|
case COMPARE::FUNCTION_SLT:
|
||||||
|
return "lessThan(" + Op0 + ", " + Op1 + ")";
|
||||||
|
case COMPARE::FUNCTION_SNE:
|
||||||
|
return "notEqual(" + Op0 + ", " + Op1 + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fmt::throw_exception("Unknown compare function" HERE);
|
fmt::throw_exception("Unknown compare function" HERE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,20 @@ public:
|
||||||
ShaderVariable() = default;
|
ShaderVariable() = default;
|
||||||
ShaderVariable(const std::string& var)
|
ShaderVariable(const std::string& var)
|
||||||
{
|
{
|
||||||
auto var_blocks = fmt::split(var, { "." });
|
// Separate 'double destination' variables 'X=Y=SRC'
|
||||||
|
std::string simple_var;
|
||||||
|
const auto pos = var.find("=");
|
||||||
|
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
simple_var = var.substr(0, pos - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
simple_var = var;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto var_blocks = fmt::split(simple_var, { "." });
|
||||||
|
|
||||||
verify(HERE), (var_blocks.size() != 0);
|
verify(HERE), (var_blocks.size() != 0);
|
||||||
|
|
||||||
|
|
|
@ -283,32 +283,45 @@ void VertexProgramDecompiler::AddCodeCond(const std::string& dst, const std::str
|
||||||
COMPARE::FUNCTION_SGE,
|
COMPARE::FUNCTION_SGE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
|
||||||
|
|
||||||
std::string swizzle;
|
|
||||||
swizzle += f[d0.mask_x];
|
|
||||||
swizzle += f[d0.mask_y];
|
|
||||||
swizzle += f[d0.mask_z];
|
|
||||||
swizzle += f[d0.mask_w];
|
|
||||||
|
|
||||||
swizzle = swizzle == "xyzw" ? "" : "." + swizzle;
|
|
||||||
|
|
||||||
std::string cond = compareFunction(cond_string_table[d0.cond], AddCondReg() + swizzle, getFloatTypeName(4) + "(0., 0., 0., 0.)");
|
|
||||||
|
|
||||||
ShaderVariable dst_var(dst);
|
ShaderVariable dst_var(dst);
|
||||||
dst_var.simplify();
|
dst_var.simplify();
|
||||||
|
|
||||||
//const char *c_mask = f;
|
static const char f[4] = { 'x', 'y', 'z', 'w' };
|
||||||
|
const u32 mask_index[4] = { d0.mask_x, d0.mask_y, d0.mask_z, d0.mask_w };
|
||||||
|
|
||||||
|
auto get_masked_dst = [](const std::string& dest, const char mask)
|
||||||
|
{
|
||||||
|
const auto selector = std::string(".") + mask;
|
||||||
|
const auto pos = dest.find("=");
|
||||||
|
|
||||||
|
std::string result = dest + selector;
|
||||||
|
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
result.insert(pos - 1, selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto get_cond_func = [this, &mask_index](COMPARE op, int index)
|
||||||
|
{
|
||||||
|
// Condition reg check for single element (x,y,z,w)
|
||||||
|
const auto cond_mask = f[mask_index[index]];
|
||||||
|
return compareFunction(op, AddCondReg() + "." + cond_mask, "0.", true);
|
||||||
|
};
|
||||||
|
|
||||||
if (dst_var.swizzles[0].length() == 1)
|
if (dst_var.swizzles[0].length() == 1)
|
||||||
{
|
{
|
||||||
AddCode("if (" + cond + ".x) " + dst + " = " + src + ";");
|
const std::string cond = get_cond_func(cond_string_table[d0.cond], 0);
|
||||||
|
AddCode("if (" + cond + ") " + dst + " = " + src + ";");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < dst_var.swizzles[0].length(); ++i)
|
for (int i = 0; i < dst_var.swizzles[0].length(); ++i)
|
||||||
{
|
{
|
||||||
AddCode("if (" + cond + "." + f[i] + ") " + dst + "." + f[i] + " = " + src + "." + f[i] + ";");
|
const std::string cond = get_cond_func(cond_string_table[d0.cond], i);
|
||||||
|
AddCode("if (" + cond + ") " + get_masked_dst(dst, f[i]) + " = " + src + "." + f[i] + ";");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ protected:
|
||||||
|
|
||||||
/** returns string calling comparison function on 2 args passed as strings.
|
/** returns string calling comparison function on 2 args passed as strings.
|
||||||
*/
|
*/
|
||||||
virtual std::string compareFunction(COMPARE, const std::string &, const std::string &) = 0;
|
virtual std::string compareFunction(COMPARE, const std::string &, const std::string &, bool scalar = false) = 0;
|
||||||
|
|
||||||
/** Insert header of shader file (eg #version, "system constants"...)
|
/** Insert header of shader file (eg #version, "system constants"...)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,7 +21,7 @@ std::string D3D12VertexProgramDecompiler::getFunction(enum class FUNCTION f)
|
||||||
return getFunctionImp(f);
|
return getFunctionImp(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string D3D12VertexProgramDecompiler::compareFunction(COMPARE f, const std::string &Op0, const std::string &Op1)
|
std::string D3D12VertexProgramDecompiler::compareFunction(COMPARE f, const std::string &Op0, const std::string &Op1, bool /*scalar*/)
|
||||||
{
|
{
|
||||||
return compareFunctionImp(f, Op0, Op1);
|
return compareFunctionImp(f, Op0, Op1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ protected:
|
||||||
virtual std::string getFloatTypeName(size_t elementCount) override;
|
virtual std::string getFloatTypeName(size_t elementCount) override;
|
||||||
std::string getIntTypeName(size_t elementCount) override;
|
std::string getIntTypeName(size_t elementCount) override;
|
||||||
virtual std::string getFunction(enum class FUNCTION) override;
|
virtual std::string getFunction(enum class FUNCTION) override;
|
||||||
virtual std::string compareFunction(enum class COMPARE, const std::string &, const std::string &) override;
|
virtual std::string compareFunction(enum class COMPARE, const std::string &, const std::string &, bool scalar) override;
|
||||||
|
|
||||||
virtual void insertHeader(std::stringstream &OS);
|
virtual void insertHeader(std::stringstream &OS);
|
||||||
virtual void insertInputs(std::stringstream &OS, const std::vector<ParamType> &inputs);
|
virtual void insertInputs(std::stringstream &OS, const std::vector<ParamType> &inputs);
|
||||||
|
|
|
@ -23,9 +23,9 @@ std::string GLVertexDecompilerThread::getFunction(FUNCTION f)
|
||||||
return glsl::getFunctionImpl(f);
|
return glsl::getFunctionImpl(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GLVertexDecompilerThread::compareFunction(COMPARE f, const std::string &Op0, const std::string &Op1)
|
std::string GLVertexDecompilerThread::compareFunction(COMPARE f, const std::string &Op0, const std::string &Op1, bool scalar)
|
||||||
{
|
{
|
||||||
return glsl::compareFunctionImpl(f, Op0, Op1);
|
return glsl::compareFunctionImpl(f, Op0, Op1, scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
||||||
|
|
|
@ -20,7 +20,7 @@ protected:
|
||||||
virtual std::string getFloatTypeName(size_t elementCount) override;
|
virtual std::string getFloatTypeName(size_t elementCount) override;
|
||||||
std::string getIntTypeName(size_t elementCount) override;
|
std::string getIntTypeName(size_t elementCount) override;
|
||||||
virtual std::string getFunction(FUNCTION) override;
|
virtual std::string getFunction(FUNCTION) override;
|
||||||
virtual std::string compareFunction(COMPARE, const std::string&, const std::string&) override;
|
virtual std::string compareFunction(COMPARE, const std::string&, const std::string&, bool scalar) override;
|
||||||
|
|
||||||
virtual void insertHeader(std::stringstream &OS) override;
|
virtual void insertHeader(std::stringstream &OS) override;
|
||||||
virtual void insertInputs(std::stringstream &OS, const std::vector<ParamType> &inputs) override;
|
virtual void insertInputs(std::stringstream &OS, const std::vector<ParamType> &inputs) override;
|
||||||
|
|
|
@ -20,9 +20,9 @@ std::string VKVertexDecompilerThread::getFunction(FUNCTION f)
|
||||||
return glsl::getFunctionImpl(f);
|
return glsl::getFunctionImpl(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VKVertexDecompilerThread::compareFunction(COMPARE f, const std::string &Op0, const std::string &Op1)
|
std::string VKVertexDecompilerThread::compareFunction(COMPARE f, const std::string &Op0, const std::string &Op1, bool scalar)
|
||||||
{
|
{
|
||||||
return glsl::compareFunctionImpl(f, Op0, Op1);
|
return glsl::compareFunctionImpl(f, Op0, Op1, scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
void VKVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
||||||
|
|
|
@ -14,7 +14,7 @@ protected:
|
||||||
virtual std::string getFloatTypeName(size_t elementCount) override;
|
virtual std::string getFloatTypeName(size_t elementCount) override;
|
||||||
std::string getIntTypeName(size_t elementCount) override;
|
std::string getIntTypeName(size_t elementCount) override;
|
||||||
virtual std::string getFunction(FUNCTION) override;
|
virtual std::string getFunction(FUNCTION) override;
|
||||||
virtual std::string compareFunction(COMPARE, const std::string&, const std::string&) override;
|
virtual std::string compareFunction(COMPARE, const std::string&, const std::string&, bool scalar) override;
|
||||||
|
|
||||||
virtual void insertHeader(std::stringstream &OS) override;
|
virtual void insertHeader(std::stringstream &OS) override;
|
||||||
virtual void insertInputs(std::stringstream &OS, const std::vector<ParamType> &inputs) override;
|
virtual void insertInputs(std::stringstream &OS, const std::vector<ParamType> &inputs) override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue