Added draft projects

Most features is broken/unstable/unimplemented/disabled
This commit is contained in:
DH
2015-11-16 19:57:49 +02:00
parent 2fc488f02a
commit 9974b95e12
24 changed files with 3164 additions and 49 deletions

38
rsx_decompiler/cache.h Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include <unordered_map>
template<typename InfoType, typename DataType, typename Hasher = InfoType::hash_t, typename Equal = std::equal_to<InfoType>>
class cache_t
{
std::unordered_map<InfoType, DataType, Hasher, Equal> m_entries;
public:
bool invalidate(const InfoType& key)
{
if (auto found = m_entries.find(key))
{
m_entries.erase(found);
return true;
}
return false;
}
DataType& entry(const InfoType& key)
{
return m_entries[key];
}
const DataType& entry(const InfoType& key) const
{
return m_entries.at(key);
}
void each(std::function<void(std::pair<const InfoType, DataType>)> function)
{
for (auto &entry : m_entries)
{
function(entry);
}
}
};

1
rsx_decompiler/pch.cpp Normal file
View File

@@ -0,0 +1 @@
#include "pch.h"

2
rsx_decompiler/pch.h Normal file
View File

@@ -0,0 +1,2 @@
#pragma once

View File

@@ -0,0 +1,865 @@
#include "pch.h"
#include "clike_builder.h"
#include <unordered_set>
#include <functional>
#include <memory>
#include <iostream>
namespace rsx
{
static const std::string index_to_channel[4] = { "x", "y", "z", "w" };
static const std::unordered_map<char, int> channel_to_index = { { 'x', 0 },{ 'y', 1 },{ 'z', 2 },{ 'w', 3 } };
template<typename Language>
struct decompiler_base : shader_code::clike_builder<Language>
{
template<type_class_t Type, int DstCount, int SrcCount>
static writer_t move_if(const expression_from<float_point_t<DstCount>> &cond, const std::string& operation, expression_t<Type, DstCount> dst, const expression_t<Type, SrcCount> &src)
{
writer_t result;
int dst_to_cond_swizzle[DstCount];
for (int i = 0; i < DstCount; ++i)
{
dst_to_cond_swizzle[i] = -1;
}
for (int i = 0; i < DstCount; ++i)
{
int dst_mask = channel_to_index.at(dst.swizzle(i).mask[0]);
int cond_mask = channel_to_index.at(cond.swizzle(i).mask[0]);
if (dst_to_cond_swizzle[dst_mask] != -1)
{
if (dst_to_cond_swizzle[dst_mask] != cond_mask)
{
std::cerr << "Bad conditional move swizzle! (old = " << dst_mask << ", new = " << cond_mask << ")" << std::endl;
}
}
else
{
dst_to_cond_swizzle[dst_mask] = cond_mask;
}
}
for (int cond_index = 0; cond_index < 4; ++cond_index)
{
std::string dst_swizzle_text;
std::string src_swizzle_text;
for (int dst_index = 0; dst_index < DstCount; ++dst_index)
{
if (dst_to_cond_swizzle[dst_index] == cond_index)
{
if (dst_index >= SrcCount)
{
//std::cerr << "Bad conditional move destination swizzle! (dst_index = " << dst_index << ") << std::endl;
continue;
}
dst_swizzle_text += dst.swizzle(dst_index).mask;
src_swizzle_text += src.swizzle(dst_index).mask;
}
}
if (dst_swizzle_text.empty())
continue;
if (dst_swizzle_text == "xyzw")
dst_swizzle_text.clear();
if (src_swizzle_text == "xyzw")
src_swizzle_text.clear();
expression_from<float_point_t<1>> cond_expr(cond.text, index_to_channel[cond_index], false, cond.base_count);
expression_from<float_point_t<1>> dst_expr(dst.text, dst_swizzle_text, false, dst.base_count);
expression_from<float_point_t<1>> src_expr(src.text, src_swizzle_text, src.is_single, src.base_count);
static const expression_from<float_point_t<1>> condition_value{ 0.0 };
result += if_(cond_expr.call_operator<boolean_t<1>>(operation, condition_value), dst_expr = src_expr);
}
return result;
}
template<type_class_t Type, int DstCount, int SrcCount>
static writer_t move(expression_t<Type, DstCount> dst, const expression_t<Type, SrcCount> &src)
{
writer_t result;
std::string src_swizzle_text;
for (int i = 0; i < DstCount; ++i)
{
int dst_index = channel_to_index.at(dst.swizzle(i).mask[0]);
src_swizzle_text += src.swizzle(dst_index).mask[0];
}
if (src_swizzle_text == "xyzw")
src_swizzle_text.clear();
expression_from<float_point_t<1>> dst_expr(dst.text, dst_swizzle_text, false, false);
expression_from<float_point_t<1>> src_expr(src.text, src_swizzle_text, src.is_single, false);
static const expression_from<float_point_t<1>> condition_value{ 0.0 };
result += if_(cond_expr.call_operator<boolean_t<1>>(operation, condition_value), dst_expr = src_expr);
return result;
}
};
}
#include "glsl_language.h"
#include "rsx_fp_ucode.h"
namespace rsx
{
namespace fragment_program
{
class decompiler : public decompiler_base<shader_code::glsl_language>
{
enum class variable_modifier
{
none,
in,
out,
constant
};
struct context_t
{
struct variable_info
{
std::string type;
std::string name;
};
u32 offset;
std::vector<u32> constants_offsets;
std::unordered_map<variable_modifier, variable_info> variables;
template<typename Type = float_point_t<4>>
expression_from<Type> variable(const std::string& name, variable_modifier modifier = variable_modifier::none)
{
variables[modifier] = { Type::name(), name };
return{ name };
}
expression_from<float_point_t<4>> constant()
{
return variable("fc" + std::to_string(offset + sizeof(instruction_t)));
}
expression_from<float_point_t<4>> temp(int index)
{
return variable("tmp" + std::to_string(index));
}
expression_from<float_point_t<4>> input(int index)
{
return variable(input_attrib_map[index]);
}
};
struct instruction_t
{
ucode_instr data;
struct src_t
{
src_reg_type_t reg_type;
u32 tmp_index;
u32 swizzle_x;
u32 swizzle_y;
u32 swizzle_z;
u32 swizzle_w;
bool fp16;
bool neg;
bool abs;
};
template<typename SrcType>
static src_t unpack_src(const SrcType& src)
{
src_t result;
result.reg_type = src.reg_type;
result.tmp_index = src.tmp_reg_index;
result.swizzle_x = src.swizzle_x;
result.swizzle_y = src.swizzle_y;
result.swizzle_z = src.swizzle_z;
result.swizzle_w = src.swizzle_w;
result.fp16 = src.fp16;
result.abs = src.abs;
result.neg = src.neg;
return result;
}
expression_from<float_point_t<4>> src(context_t& context, int index) const
{
src_t src;
switch (index)
{
case 0: src = unpack_src(data.src0); break;
case 1: src = unpack_src(data.src1); break;
case 2: src = unpack_src(data.src2); break;
}
auto get_variable = [&](const src_t& src)
{
switch (src.reg_type)
{
case src_reg_type_t::temporary: return context.temp(src.tmp_index);
case src_reg_type_t::input: return context.input(data.dst.src_attr_reg_num);
case src_reg_type_t::constant: return context.constant();
}
};
expression_from<float_point_t<4>> result = get_variable(src);
if (src.abs)
{
result.assign(abs(result));
}
if (src.neg)
{
result.assign(-result);
}
return result.swizzle(src.swizzle_x, src.swizzle_y, src.swizzle_z, src.swizzle_w);
}
expression_from<float_point_t<4>> output(context_t& context) const
{
}
expression_from<float_point_t<4>> dst(context_t& context) const
{
}
};
static_assert(sizeof(instruction_t) == 16, "Bad instruction_t implementation");
public:
instruction_t* instruction;
context_t context;
writer_t writer;
expression_from<float_point_t<4>> src(int index)
{
return instruction->src(context, index);
}
expression_from<boolean_t<4>> modify_condition()
{
return{ "" };
}
expression_from<boolean_t<4>> execution_condition()
{
return{ "" };
}
expression_from<sampler2D_t> tex()
{
return{ "" };
}
template<typename ExprType>
expression_from<void_t> conditional(const ExprType& expr)
{
bool need_condition = false;
if (need_condition)
{
return if_(any(execution_condition()), expr);
}
return expr;
}
//template<type_class_t Type, int Count>
writer_t set_dst(const expression_t<type_class_t::type_float, 4>& arg)
{
writer_t result;
auto modify_cond = modify_condition();
auto dest = instruction->dst(context);
if (!instruction->data.src0.exec_if_eq || !instruction->data.src0.exec_if_gr || !instruction->data.src0.exec_if_lt)
{
std::string cond_mask;
cond_mask += index_to_channel[instruction->data.src0.cond_swizzle_x];
cond_mask += index_to_channel[instruction->data.src0.cond_swizzle_y];
cond_mask += index_to_channel[instruction->data.src0.cond_swizzle_z];
cond_mask += index_to_channel[instruction->data.src0.cond_swizzle_w];
auto cond = execution_condition();
std::string operation;
if (instruction->data.src0.exec_if_gr && instruction->data.src0.exec_if_lt)
{
operation = "!=";
}
else if (!instruction->data.src0.exec_if_gr && !instruction->data.src0.exec_if_lt)
{
operation = "==";
}
else
{
if (instruction->data.src0.exec_if_gr)
operation += ">";
else if (instruction->data.src0.exec_if_lt)
operation += "<";
if (instruction->data.src0.exec_if_eq)
operation += "=";
}
auto set_channel = [&](int index)
{
if (instruction->data.dst.set_cond)
{
if (instruction->data.dst.no_dest)
{
result += if_(cond.swizzle(index).call_operator<boolean_t<1>>(operation, 0.0f), modify_cond.swizzle(index) = boolean_t<1>::ctor(arg.swizzle(index)));
}
else
{
result += if_(cond.swizzle(index).call_operator(operation, 0.0f), modify_cond.swizzle(index) = boolean_t<1>::ctor(dest.swizzle(index) = arg.swizzle(index)));
}
}
else
{
if (instruction->data.dst.no_dest)
{
result += if_(cond.swizzle(index).call_operator(operation, 0.0f), arg.swizzle(index));
}
else
{
result += if_(cond.swizzle(index).call_operator(operation, 0.0f), dest.swizzle(index) = arg.swizzle(index));
}
}
};
if (instruction->data.dst.mask_x) set_channel(0);
if (instruction->data.dst.mask_y) set_channel(1);
if (instruction->data.dst.mask_z) set_channel(2);
if (instruction->data.dst.mask_w) set_channel(3);
}
return result;
}
writer_t comment(const std::string& lines)
{
writer_t result;
result += "//" + lines;
return result;
}
writer_t unimplemented(const std::string& lines)
{
return comment(lines);
}
expression_base_t decode_instruction()
{
switch (instruction->data.dst.opcode)
{
case opcode::NOP: return comment("nop");
case opcode::MOV: return set_dst(src(0));
case opcode::MUL: return set_dst(src(0) * src(1));
case opcode::ADD: return set_dst(src(0) + src(1));
case opcode::MAD: return set_dst(src(0) * src(1) + src(2));
case opcode::DP3: return set_dst(float_point_t<4>::ctor(dot(src(0).xyz(), src(1).xyz())));
case opcode::DP4: return set_dst(float_point_t<4>::ctor(dot(src(0), src(1))));
case opcode::DST:
{
auto src_0 = src(0);
auto src_1 = src(1);
return set_dst(float_point_t<4>::ctor(1.0f, src_0.y() * src_1.y(), src_0.z(), src_1.w()));
}
case opcode::MIN: return set_dst(min(src(0), src(1)));
case opcode::MAX: return set_dst(max(src(0), src(1)));
case opcode::SLT: return set_dst(float_point_t<4>::ctor(less(src(0), src(1))));
case opcode::SGE: return set_dst(float_point_t<4>::ctor(greater_equal(src(0), src(1))));
case opcode::SLE: return set_dst(float_point_t<4>::ctor(less_equal(src(0), src(1))));
case opcode::SGT: return set_dst(float_point_t<4>::ctor(greater(src(0), src(1))));
case opcode::SNE: return set_dst(float_point_t<4>::ctor(not_equal(src(0), src(1))));
case opcode::SEQ: return set_dst(float_point_t<4>::ctor(equal(src(0), src(1))));
case opcode::FRC: return set_dst(fract(src(0)));
case opcode::FLR: return set_dst(floor(src(0)));
case opcode::KIL: return conditional(expression_from<void_t>("discard"));
case opcode::PK4: return unimplemented("PK4");
case opcode::UP4: return unimplemented("UP4");
case opcode::DDX: return set_dst(ddx(src(0)));
case opcode::DDY: return set_dst(ddy(src(0)));
case opcode::TEX: return set_dst(texture(tex(), src(0).xy()));
case opcode::TXP: return set_dst(texture(tex(), src(0).xy() / src(0).w()));
case opcode::TXD: return set_dst(texture_grad(tex(), src(0).xy(), src(1).xy(), src(2).xy()));
case opcode::RCP: return set_dst(float_point_t<1>::ctor(1.0f) / src(0));
case opcode::RSQ: return set_dst(rsqrt(src(0)));
case opcode::EX2: return set_dst(exp2(src(0)));
case opcode::LG2: return set_dst(log2(src(0)));
case opcode::LIT: return unimplemented("LIT");
case opcode::LRP: return unimplemented("LRP");
case opcode::STR: return set_dst(float_point_t<4>::ctor(1.0f));
case opcode::SFL: return set_dst(float_point_t<4>::ctor(0.0f));
case opcode::COS: return set_dst(cos(src(0)));
case opcode::SIN: return set_dst(sin(src(0)));
case opcode::PK2: return unimplemented("PK2");
case opcode::UP2: return unimplemented("UP2");
case opcode::POW: return set_dst(pow(src(0), src(1)));
case opcode::PKB: return unimplemented("PKB");
case opcode::UPB: return unimplemented("UPB");
case opcode::PK16: return unimplemented("PK16");
case opcode::UP16: return unimplemented("UP16");
case opcode::BEM: return unimplemented("BEM");
case opcode::PKG: return unimplemented("PKG");
case opcode::UPG: return unimplemented("UPG");
case opcode::DP2A:
{
auto src_0 = src(0);
auto src_1 = src(1);
return set_dst(float_point_t<4>::ctor(src_0.x() * src_1.x() + src_0.y() * src_1.y() + src(2).z()));
}
case opcode::TXL: return set_dst(texture_lod(tex(), src(0).xy(), src(1).x()));
case opcode::TXB: return set_dst(texture_bias(tex(), src(0).xy(), src(1).x()));
case opcode::TEXBEM: return unimplemented("TEXBEM");
case opcode::TXPBEM: return unimplemented("TXPBEM");
case opcode::BEMLUM: return unimplemented("BEMLUM");
case opcode::REFL: return unimplemented("REFL");
case opcode::TIMESWTEX: return unimplemented("TIMESWTEX");
case opcode::DP2: return set_dst(float_point_t<4>::ctor(dot(src(0).xy(), src(1).xy())));
case opcode::NRM: return set_dst(normalize(src(0).xyz()).xyzx());
case opcode::DIV: return set_dst(src(0) / src(1));
case opcode::DIVSQ: return set_dst(src(0) / sqrt(src(1)));
case opcode::LIF: return unimplemented("LIF");
case opcode::FENCT: return comment("fenct");
case opcode::FENCB: return comment("fencb");
case opcode::BRK: return conditional(expression_from<void_t>("break"));
case opcode::CAL: return unimplemented("CAL");
case opcode::IFE: return unimplemented("IFE");
case opcode::LOOP: return unimplemented("LOOP");
case opcode::REP: return unimplemented("REP");
case opcode::RET: return conditional(expression_from<void_t>("return"));
}
}
void decompile(std::size_t offset, instruction_t* instructions)
{
for (std::size_t index = offset; index < 512; ++index, writer.next())
{
instruction = instructions + index;
writer += decode_instruction();
if (instruction->data.dst.end)
break;
}
}
void test()
{
expression_from<float_point_t<4>> C{ "C", "wwww" };
expression_from<float_point_t<4>> A{ "A" };
expression_from<float_point_t<4>> B{ "B" };
expression_from<sampler2D_t> tex = { "tex0" };
std::cout << move_if(C.xyz(), "!=", -A.xyz(), texture(tex, A.xy() / B.zw() + C.xw()).xyz()).build();
}
};
}
}
/*
struct vp_shader : shader_code::clike_builder<shader_code::glsl_language>
{
writer_t writer;
struct variable_info
{
std::string type;
std::string name;
bool operator ==(const variable_info& rhs) const
{
return type == rhs.type && name == rhs.name;
}
struct hash
{
std::size_t operator()(const variable_info& arg) const
{
return
std::hash<std::string>()(arg.type) ^
(std::hash<std::string>()(arg.name) - 1);
}
};
};
std::unordered_set<variable_info, variable_info::hash> uniforms;
template<typename Type>
expression_from<Type> make_uniform(const std::string& name, expression_from<Type> initializer)
{
return{ name };
}
template<typename Type>
expression_from<Type> make_uniform(const std::string& name)
{
return{ name };
}
struct else_t : expression_base_t
{
};
struct if_t : expression_from<void_t>
{
if_t(expression_from<boolean_t<1>> condition, std::function<void()> body = nullptr)
: expression_t("if (" + condition.to_string() + ")")
{
}
std::string finalize() const override
{
return to_string();
}
};
vp_shader()
{
auto A = make_uniform<boolean_t<4>>("A", boolean_t<4>::ctor(true));
auto B = make_uniform<float_point_t<4>>("B", float_point_t<4>::ctor(0.f));
auto C = make_uniform<float_point_t<4>>("C");
auto K = make_uniform<float_point_t<2>>("K");
auto D = make_uniform<sampler2D_t>("D");
writer.lines(
texture(D).xyzw(),
float_point_t<4>::ctor(1),
float_point_t<1>::ctor(1.f) / float_point_t<1>::ctor(),
if_t(A.x()),
A.x() = !(K.xy().y() != C.x()),
K.xy(),
A.y() = B.x() != C.x()
);
}
};
#include <unordered_map>
struct rsx_fragment_shader
{
std::vector<unsigned int> data;
struct hash_t
{
std::size_t operator ()(const rsx_fragment_shader& arg) const
{
return 0;
//return arg.hash;
}
};
bool operator ==(const rsx_fragment_shader& rhs) const
{
if (data.size() != rhs.data.size())
return false;
for (std::size_t i = 0; i < data.size(); ++i)
{
if (data[i] != rhs.data[i])
return false;
}
return true;
}
};
struct decompiled_rsx_fragment_shader
{
std::vector<std::size_t> constant_offsets;
std::vector<std::string> uniforms;
int input_attributes;
int output_attributes;
std::string code;
};
struct glsl_shader_t
{
int id;
};
template<typename CompiledType>
struct finalized_rsx_fragment_shader
{
int input_attributes;
int output_attributes;
int control;
std::string code;
CompiledType shader;
};
template<typename Type>
struct rsx_program
{
std::shared_ptr<finalized_rsx_fragment_shader<glsl_shader_t>> fragment_shader;
std::shared_ptr<finalized_rsx_fragment_shader<glsl_shader_t>> vertex_shader;
};
/*
namespace fmt
{
bool mask_test(const std::string &source, const std::string &mask, std::size_t source_offset = 0, std::size_t mask_offset = 0)
{
while (char sym = mask[mask_offset])
{
if (source[source_offset] == '\0')
return false;
switch (sym)
{
case '*':
while (source[source_offset])
{
if (mask_test(source, mask, source_offset, mask_offset + 1))
return true;
++source_offset;
}
return false;
case '\\':
sym = mask[++mask_offset];
default:
if (sym != source[source_offset])
return false;
case '?':
++source_offset; ++mask_offset;
break;
}
}
return source[source_offset] == '\0';
}
}
#include <filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::tr2::sys;
void _load_fragment_cache_file(const fs::path& data_path, const fs::path &source_path)
{
rsx_fragment_shader shader;
{
std::ifstream data_f(data_path, std::ios::ate | std::ios::binary);
if (!data_f)
return;
shader.data.resize(data_f.tellg() / sizeof(rsx_fragment_shader::data[0]));
data_f.seekg(0, data_f.beg);
data_f.read((char*)shader.data.data(), shader.data.size() * sizeof(rsx_fragment_shader::data[0]));
}
cache_t<rsx_fragment_shader, decompiled_rsx_fragment_shader> cache;
decompiled_rsx_fragment_shader &decompiled_shader = cache.entry(shader);
{
std::ifstream data_f(data_path, std::ios::ate);
if (!data_f)
return;
data_f
>> decompiled_shader.input_attributes
>> decompiled_shader.output_attributes;
int constants_count;
data_f >> constants_count;
if (constants_count)
{
decompiled_shader.constant_offsets.resize(constants_count);
for (auto &offset : decompiled_shader.constant_offsets)
{
data_f >> offset;
}
}
int uniforms_count;
data_f >> uniforms_count;
if (uniforms_count)
{
decompiled_shader.uniforms.resize(uniforms_count);
for (auto &uniform : decompiled_shader.uniforms)
{
data_f >> uniform;
}
}
auto from_pos = data_f.tellg();
data_f.seekg(0, data_f.end);
auto end_pos = data_f.tellg();
decompiled_shader.code.resize(end_pos - from_pos);
data_f.seekg(from_pos);
data_f.read((char*)decompiled_shader.code.data(), decompiled_shader.code.size());
}
}
void _save_fragment_cache_file(const fs::path& data_path, const fs::path &source_path, std::pair<const rsx_fragment_shader&, decompiled_rsx_fragment_shader&> data)
{
rsx_fragment_shader shader;
{
std::ifstream data_f(data_path, std::ios::ate | std::ios::binary);
if (!data_f)
return;
shader.data.resize(data_f.tellg() / sizeof(rsx_fragment_shader::data[0]));
data_f.seekg(0, data_f.beg);
data_f.read((char*)shader.data.data(), shader.data.size() * sizeof(rsx_fragment_shader::data[0]));
}
cache_t<rsx_fragment_shader, decompiled_rsx_fragment_shader> cache;
decompiled_rsx_fragment_shader &decompiled_shader = cache.entry(shader);
{
std::ifstream data_f(data_path, std::ios::ate);
if (!data_f)
return;
data_f
>> decompiled_shader.input_attributes
>> decompiled_shader.output_attributes;
int constants_count;
data_f >> constants_count;
if (constants_count)
{
decompiled_shader.constant_offsets.resize(constants_count);
for (auto &offset : decompiled_shader.constant_offsets)
{
data_f >> offset;
}
}
int uniforms_count;
data_f >> uniforms_count;
if (uniforms_count)
{
decompiled_shader.uniforms.resize(uniforms_count);
for (auto &uniform : decompiled_shader.uniforms)
{
data_f >> uniform;
}
}
auto from_pos = data_f.tellg();
data_f.seekg(0, data_f.end);
auto end_pos = data_f.tellg();
decompiled_shader.code.resize(end_pos - from_pos);
data_f.seekg(from_pos);
data_f.read((char*)decompiled_shader.code.data(), decompiled_shader.code.size());
}
}
void _load_shader_cache(const std::string &cache_path)
{
if (!fs::exists(cache_path))
{
if (!fs::create_directories(cache_path))
return;
}
for (auto entry : fs::directory_iterator{ fs::path(cache_path).parent_path() })
{
if (entry.status().type() != fs::file_type::regular)
{
continue;
}
if (fmt::mask_test(entry.path().filename().string(), "*.vp.data"))
{
fs::path(entry.path()).replace_extension("glsl");
}
if (fmt::mask_test(entry.path().filename().string(), "*.fp.data"))
{
_load_fragment_cache_file(entry.path(), fs::path(entry.path()).replace_extension("glsl").string());
}
}
}
void load_shader_cache(const std::string &game_id)
{
_load_shader_cache("./data/cache/rsx/");
if (!game_id.empty())
_load_shader_cache("./data/" + game_id + "/cache/rsx/");
cache_t<rsx_fragment_shader, decompiled_rsx_fragment_shader> cache;
cache.each([](std::pair<const rsx_fragment_shader&, decompiled_rsx_fragment_shader&> elem)
{
elem.first.data;
});
}
*/
#include <iostream>
namespace vs
{
int main()
{
//load_shader_cache("SUPER12321");
//vp_shader a{};
//for (auto& line : a.writer.code)
// std::cout << line.second << std::endl;
rsx::fragment_program::decompiler{}.test();
std::cin.get();
return 0;
}
}

View File

@@ -0,0 +1,117 @@
#pragma once
#include <vector>
struct rsx_vertex_shader
{
std::vector<unsigned int> data;
struct hash_t
{
std::size_t operator ()(const rsx_vertex_shader& arg) const
{
return 0;
//return arg.hash;
}
};
bool operator ==(const rsx_vertex_shader& rhs) const
{
if (data.size() != rhs.data.size())
return false;
for (std::size_t i = 0; i < data.size(); ++i)
{
if (data[i] != rhs.data[i])
return false;
}
return true;
}
};
struct rsx_fragment_shader
{
std::vector<unsigned int> data;
struct hash_t
{
std::size_t operator ()(const rsx_fragment_shader& arg) const
{
return 0;
//return arg.hash;
}
};
bool operator ==(const rsx_fragment_shader& rhs) const
{
if (data.size() != rhs.data.size())
return false;
for (std::size_t i = 0; i < data.size(); ++i)
{
if (data[i] != rhs.data[i])
return false;
}
return true;
}
};
struct decompiled_rsx_shader
{
std::vector<std::size_t> constant_offsets;
std::vector<std::string> uniforms;
int input_attributes;
int output_attributes;
std::string code;
};
struct finalized_rsx_vertex_shader
{
int input_attributes;
std::string code;
struct hash_t
{
std::size_t operator ()(const finalized_rsx_vertex_shader& arg) const
{
return 0;
//return arg.hash;
}
};
bool operator ==(const finalized_rsx_vertex_shader& rhs) const
{
return
input_attributes == rhs.input_attributes &&
code == rhs.code;
}
};
struct finalized_rsx_fragment_shader
{
int output_attributes;
int control;
std::string code;
struct hash_t
{
std::size_t operator ()(const finalized_rsx_fragment_shader& arg) const
{
return 0;
//return arg.hash;
}
};
bool operator ==(const finalized_rsx_fragment_shader& rhs) const
{
return
output_attributes == rhs.output_attributes &&
control == rhs.control &&
code == rhs.code;
}
};

View File

@@ -0,0 +1,257 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7d73447b-3d2d-4dfe-bf62-57e644c1d09f}</ProjectGuid>
<Keyword>StaticLibrary</Keyword>
<ProjectName>rsx_decompiler</ProjectName>
<RootNamespace>rsx_decompiler</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<GenerateManifest>false</GenerateManifest>
<IncludePath>$(SolutionDir)shader_code\;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration);$(LibraryPath)</LibraryPath>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<GenerateManifest>false</GenerateManifest>
<IncludePath>$(SolutionDir)shader_code\;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration);$(LibraryPath)</LibraryPath>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<GenerateManifest>false</GenerateManifest>
<IncludePath>$(SolutionDir)shader_code\;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration);$(LibraryPath)</LibraryPath>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<GenerateManifest>false</GenerateManifest>
<IncludePath>$(SolutionDir)shader_code\;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration);$(LibraryPath)</LibraryPath>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<GenerateManifest>false</GenerateManifest>
<IncludePath>$(SolutionDir)shader_code\;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration);$(LibraryPath)</LibraryPath>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<GenerateManifest>false</GenerateManifest>
<IncludePath>$(SolutionDir)shader_code\;$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration);$(LibraryPath)</LibraryPath>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<CompileAsWinRT>false</CompileAsWinRT>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
</Link>
<Lib>
<AdditionalDependencies>shader_code.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<CompileAsWinRT>false</CompileAsWinRT>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
</Link>
<Lib>
<AdditionalDependencies>shader_code.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<CompileAsWinRT>false</CompileAsWinRT>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
</Link>
<Lib>
<AdditionalDependencies>shader_code.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<CompileAsWinRT>false</CompileAsWinRT>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
</Link>
<Lib>
<AdditionalDependencies>shader_code.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<CompileAsWinRT>false</CompileAsWinRT>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
</Link>
<Lib>
<AdditionalDependencies>shader_code.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<CompileAsWinRT>false</CompileAsWinRT>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
</Link>
<Lib>
<AdditionalDependencies>shader_code.lib</AdditionalDependencies>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="cache.h" />
<ClInclude Include="rsx_decompiler.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="rsx_decompiler.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="rsx_fp_ucode.cpp" />
<ClInclude Include="rsx_fp_ucode.h">
<FileType>CppCode</FileType>
</ClInclude>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="rsx_decompiler.cpp" />
<ClCompile Include="pch.cpp" />
<ClCompile Include="rsx_fp_ucode.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="rsx_decompiler.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="cache.h" />
<ClInclude Include="rsx_fp_ucode.h" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,49 @@
#include "pch.h"
#include "rsx_fp_ucode.h"
namespace rsx
{
namespace fragment_program
{
const std::string input_attrib_map[16] =
{
"in_wpos", //0
"in_col0", //1
"in_col1", //2
"in_fogc", //3
"in_tex0", //4
"in_tex1", //5
"in_tex2", //6
"in_tex3", //7
"in_tex4", //8
"in_tex5", //9
"in_tex6", //10
"in_tex7", //11
"in_tex8", //12
"in_tex9", //13
"in_ssa", //14
"in_unk" //15
};
const std::string input_attr_regs[16] =
{
"WPOS", "COL0", "COL1", "FOGC", "TEX0",
"TEX1", "TEX2", "TEX3", "TEX4", "TEX5",
"TEX6", "TEX7", "TEX8", "TEX9", "SSA"
};
const std::string instructions_names[128] =
{
"NOP", "MOV", "MUL", "ADD", "MAD", "DP3", "DP4",
"DST", "MIN", "MAX", "SLT", "SGE", "SLE", "SGT",
"SNE", "SEQ", "FRC", "FLR", "KIL", "PK4", "UP4",
"DDX", "DDY", "TEX", "TXP", "TXD", "RCP", "RSQ",
"EX2", "LG2", "LIT", "LRP", "STR", "SFL", "COS",
"SIN", "PK2", "UP2", "POW", "PKB", "UPB", "PK16",
"UP16", "BEM", "PKG", "UPG", "DP2A", "TXL", "NULL",
"TXB", "NULL", "TEXBEM", "TXPBEM", "BEMLUM", "REFL", "TIMESWTEX",
"DP2", "NRM", "DIV", "DIVSQ", "LIF", "FENCT", "FENCB",
"NULL", "BRK", "CAL", "IFE", "LOOP", "REP", "RET"
};
}
}

View File

@@ -0,0 +1,212 @@
#pragma once
#include <string>
namespace rsx
{
using u32 = unsigned int;
namespace fragment_program
{
enum class opcode : u32
{
NOP = 0x00, // No-Operation
MOV = 0x01, // Move
MUL = 0x02, // Multiply
ADD = 0x03, // Add
MAD = 0x04, // Multiply-Add
DP3 = 0x05, // 3-component Dot Product
DP4 = 0x06, // 4-component Dot Product
DST = 0x07, // Distance
MIN = 0x08, // Minimum
MAX = 0x09, // Maximum
SLT = 0x0A, // Set-If-LessThan
SGE = 0x0B, // Set-If-GreaterEqual
SLE = 0x0C, // Set-If-LessEqual
SGT = 0x0D, // Set-If-GreaterThan
SNE = 0x0E, // Set-If-NotEqual
SEQ = 0x0F, // Set-If-Equal
FRC = 0x10, // Fraction (fract)
FLR = 0x11, // Floor
KIL = 0x12, // Kill fragment
PK4 = 0x13, // Pack four signed 8-bit values
UP4 = 0x14, // Unpack four signed 8-bit values
DDX = 0x15, // Partial-derivative in x (Screen space derivative w.r.t. x)
DDY = 0x16, // Partial-derivative in y (Screen space derivative w.r.t. y)
TEX = 0x17, // Texture lookup
TXP = 0x18, // Texture sample with projection (Projective texture lookup)
TXD = 0x19, // Texture sample with partial differentiation (Texture lookup with derivatives)
RCP = 0x1A, // Reciprocal
RSQ = 0x1B, // Reciprocal Square Root
EX2 = 0x1C, // Exponentiation base 2
LG2 = 0x1D, // Log base 2
LIT = 0x1E, // Lighting coefficients
LRP = 0x1F, // Linear Interpolation
STR = 0x20, // Set-If-True
SFL = 0x21, // Set-If-False
COS = 0x22, // Cosine
SIN = 0x23, // Sine
PK2 = 0x24, // Pack two 16-bit floats
UP2 = 0x25, // Unpack two 16-bit floats
POW = 0x26, // Power
PKB = 0x27, // Pack bytes
UPB = 0x28, // Unpack bytes
PK16 = 0x29, // Pack 16 bits
UP16 = 0x2A, // Unpack 16
BEM = 0x2B, // Bump-environment map (a.k.a. 2D coordinate transform)
PKG = 0x2C, // Pack with sRGB transformation
UPG = 0x2D, // Unpack gamma
DP2A = 0x2E, // 2-component dot product with scalar addition
TXL = 0x2F, // Texture sample with explicit LOD
TXB = 0x31, // Texture sample with bias
TEXBEM = 0x33,
TXPBEM = 0x34,
BEMLUM = 0x35,
REFL = 0x36, // Reflection vector
TIMESWTEX = 0x37,
DP2 = 0x38, // 2-component dot product
NRM = 0x39, // Normalize
DIV = 0x3A, // Division
DIVSQ = 0x3B, // Divide by Square Root
LIF = 0x3C, // Final part of LIT
FENCT = 0x3D, // Fence T?
FENCB = 0x3E, // Fence B?
BRK = 0x40, // Break
CAL = 0x41, // Subroutine call
IFE = 0x42, // If
LOOP = 0x43, // Loop
REP = 0x44, // Repeat
RET = 0x45 // Return
};
enum class src_reg_type_t : u32
{
temporary,
input,
constant
};
union alignas(4) OPDEST
{
u32 _u32;
struct
{
u32 end : 1; // Set to 1 if this is the last instruction
u32 dest_reg : 6; // Destination register index
u32 fp16 : 1; // Destination is a half register (H0 to H47)
u32 set_cond : 1; // Condition Code Registers (CC0 and CC1) are updated
u32 mask_x : 1;
u32 mask_y : 1;
u32 mask_z : 1;
u32 mask_w : 1;
u32 src_attr_reg_num : 4;
u32 tex_num : 4;
u32 exp_tex : 1; // _bx2
u32 prec : 2;
opcode opcode : 6;
u32 no_dest : 1;
u32 saturate : 1; // _sat
};
};
union alignas(4) SRC0
{
u32 _u32;
struct
{
src_reg_type_t reg_type : 2;
u32 tmp_reg_index : 6;
u32 fp16 : 1;
u32 swizzle_x : 2;
u32 swizzle_y : 2;
u32 swizzle_z : 2;
u32 swizzle_w : 2;
u32 neg : 1;
u32 exec_if_lt : 1;
u32 exec_if_eq : 1;
u32 exec_if_gr : 1;
u32 cond_swizzle_x : 2;
u32 cond_swizzle_y : 2;
u32 cond_swizzle_z : 2;
u32 cond_swizzle_w : 2;
u32 abs : 1;
u32 cond_mod_reg_index : 1;
u32 cond_reg_index : 1;
};
};
union alignas(4) SRC1
{
u32 _u32;
struct
{
src_reg_type_t reg_type : 2;
u32 tmp_reg_index : 6;
u32 fp16 : 1;
u32 swizzle_x : 2;
u32 swizzle_y : 2;
u32 swizzle_z : 2;
u32 swizzle_w : 2;
u32 neg : 1;
u32 abs : 1;
u32 input_mod_src0 : 3;
u32: 6;
u32 scale : 3;
u32 opcode_is_branch : 1;
};
struct
{
u32 else_offset : 31;
u32: 1;
};
// LOOP, REP
struct
{
u32: 2;
u32 end_counter : 8; // End counter value for LOOP or rep count for REP
u32 init_counter : 8; // Initial counter value for LOOP
u32: 1;
u32 increment : 8; // Increment value for LOOP
};
};
union alignas(4) SRC2
{
u32 _u32;
u32 end_offset;
struct
{
src_reg_type_t reg_type : 2;
u32 tmp_reg_index : 6;
u32 fp16 : 1;
u32 swizzle_x : 2;
u32 swizzle_y : 2;
u32 swizzle_z : 2;
u32 swizzle_w : 2;
u32 neg : 1;
u32 abs : 1;
u32 addr_reg : 11;
u32 use_index_reg : 1;
u32 perspective_corr : 1;
};
};
struct alignas(16) ucode_instr
{
OPDEST dst;
SRC0 src0;
SRC1 src1;
SRC2 src2;
};
extern const std::string input_attr_regs[16];
extern const std::string instructions_names[128];
extern const std::string input_attrib_map[16];
}
}

View File

@@ -8,40 +8,39 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rsx_program_decompiler", "rsx_program_decompiler\rsx_program_decompiler.vcxproj", "{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}"
ProjectSection(ProjectDependencies) = postProject
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE} = {F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}
{97E17077-A21F-45EF-9C3A-73A0BC092D7E} = {97E17077-A21F-45EF-9C3A-73A0BC092D7E}
{7D73447B-3D2D-4DFE-BF62-57E644C1D09F} = {7D73447B-3D2D-4DFE-BF62-57E644C1D09F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shader_code", "shader_code\shader_code.vcxproj", "{97E17077-A21F-45EF-9C3A-73A0BC092D7E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rsx_decompiler", "rsx_decompiler\rsx_decompiler.vcxproj", "{7D73447B-3D2D-4DFE-BF62-57E644C1D09F}"
ProjectSection(ProjectDependencies) = postProject
{97E17077-A21F-45EF-9C3A-73A0BC092D7E} = {97E17077-A21F-45EF-9C3A-73A0BC092D7E}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Debug|ARM.ActiveCfg = Debug|ARM
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Debug|ARM.Build.0 = Debug|ARM
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Debug|x64.ActiveCfg = Debug|x64
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Debug|x64.Build.0 = Debug|x64
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Debug|x86.ActiveCfg = Debug|Win32
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Debug|x86.Build.0 = Debug|Win32
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Release|ARM.ActiveCfg = Release|ARM
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Release|ARM.Build.0 = Release|ARM
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Release|x64.ActiveCfg = Release|x64
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Release|x64.Build.0 = Release|x64
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Release|x86.ActiveCfg = Release|Win32
{F7AAD20D-BCFA-4B17-A178-BD8606B4E1FE}.Release|x86.Build.0 = Release|Win32
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Debug|ARM.ActiveCfg = Debug|Win32
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Debug|x64.ActiveCfg = Debug|x64
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Debug|x64.Build.0 = Debug|x64
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Debug|x86.ActiveCfg = Debug|Win32
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Debug|x86.Build.0 = Debug|Win32
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Release|ARM.ActiveCfg = Release|Win32
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Release|x64.ActiveCfg = Release|x64
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Release|x64.Build.0 = Release|x64
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Release|x86.ActiveCfg = Release|Win32
{9DAF4DF3-0E31-4C55-B367-6992C35F89CE}.Release|x86.Build.0 = Release|Win32
{97E17077-A21F-45EF-9C3A-73A0BC092D7E}.Debug|x64.ActiveCfg = Debug|x64
{97E17077-A21F-45EF-9C3A-73A0BC092D7E}.Debug|x64.Build.0 = Debug|x64
{97E17077-A21F-45EF-9C3A-73A0BC092D7E}.Release|x64.ActiveCfg = Release|x64
{97E17077-A21F-45EF-9C3A-73A0BC092D7E}.Release|x64.Build.0 = Release|x64
{7D73447B-3D2D-4DFE-BF62-57E644C1D09F}.Debug|x64.ActiveCfg = Debug|x64
{7D73447B-3D2D-4DFE-BF62-57E644C1D09F}.Debug|x64.Build.0 = Debug|x64
{7D73447B-3D2D-4DFE-BF62-57E644C1D09F}.Release|x64.ActiveCfg = Release|x64
{7D73447B-3D2D-4DFE-BF62-57E644C1D09F}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,3 +1,4 @@
/*
#include <rsx/rsx.h>
#include <unordered_map>
#include <iostream>
@@ -7,6 +8,7 @@
#include "elf64.h"
#include <cctype>
template<typename DecompilerType>
int process_ucode(const std::string& ipath, const std::string& opath)
{
@@ -163,10 +165,17 @@ void help()
std::cout << profile.first << " ";
}
std::cout << std::endl;
}*/
namespace vs
{
int main();
}
int main(int argc, char** argv)
{
return vs::main();
/*
if (argc != 4)
{
help();
@@ -190,5 +199,5 @@ int main(int argc, char** argv)
std::cerr << ex.what() << std::endl;
return -5;
}
*/
}

View File

@@ -74,20 +74,20 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<LibraryPath>$(SolutionDir)lib\;$(LibraryPath)</LibraryPath>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration)\;$(LibraryPath)</LibraryPath>
<IncludePath>$(SolutionDir)rsx_program_decompiler_lib\;$(IncludePath)</IncludePath>
<OutDir>$(SolutionDir)bin\</OutDir>
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<LibraryPath>$(SolutionDir)lib\;$(LibraryPath)</LibraryPath>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration)\;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)bin\</OutDir>
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<IncludePath>$(SolutionDir)rsx_program_decompiler_lib\;$(IncludePath)</IncludePath>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis>
@@ -95,9 +95,9 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)bin\</OutDir>
<LibraryPath>$(SolutionDir)lib\;$(LibraryPath)</LibraryPath>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration)\;$(LibraryPath)</LibraryPath>
<IncludePath>$(SolutionDir)rsx_program_decompiler_lib\;$(IncludePath)</IncludePath>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis>
@@ -106,8 +106,8 @@
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)-$(Platform)-$(Configuration)</TargetName>
<OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<LibraryPath>$(SolutionDir)lib\;$(LibraryPath)</LibraryPath>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<LibraryPath>$(SolutionDir)lib\$(Platform)-$(Configuration)\;$(LibraryPath)</LibraryPath>
<IncludePath>$(SolutionDir)rsx_program_decompiler_lib\;$(IncludePath)</IncludePath>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis>
@@ -123,7 +123,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>rsx_program_decompiler-$(Platform)-$(Configuration).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>rsx_decompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -137,7 +137,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>rsx_program_decompiler-$(Platform)-$(Configuration).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>rsx_decompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -155,7 +155,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>rsx_program_decompiler-$(Platform)-$(Configuration).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>rsx_decompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -173,7 +173,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>rsx_program_decompiler-$(Platform)-$(Configuration).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>rsx_decompiler.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -102,39 +102,39 @@
<GenerateManifest>false</GenerateManifest>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis>
<OutDir>$(SolutionDir)lib\</OutDir>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<TargetName>rsx_program_decompiler-$(Platform)-$(Configuration)</TargetName>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<TargetName>rsx_program_decompiler</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<GenerateManifest>false</GenerateManifest>
<OutDir>$(SolutionDir)lib\</OutDir>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<TargetName>rsx_program_decompiler-$(Platform)-$(Configuration)</TargetName>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<TargetName>rsx_program_decompiler</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<GenerateManifest>false</GenerateManifest>
<OutDir>$(SolutionDir)lib\</OutDir>
<TargetName>rsx_program_decompiler-$(Platform)-$(Configuration)</TargetName>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<TargetName>rsx_program_decompiler</TargetName>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<GenerateManifest>false</GenerateManifest>
<OutDir>$(SolutionDir)lib\</OutDir>
<TargetName>rsx_program_decompiler-$(Platform)-$(Configuration)</TargetName>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<TargetName>rsx_program_decompiler</TargetName>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<GenerateManifest>false</GenerateManifest>
<OutDir>$(SolutionDir)lib\</OutDir>
<TargetName>rsx_program_decompiler-$(Platform)-$(Configuration)</TargetName>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<TargetName>rsx_program_decompiler</TargetName>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<GenerateManifest>false</GenerateManifest>
<OutDir>$(SolutionDir)lib\</OutDir>
<TargetName>rsx_program_decompiler-$(Platform)-$(Configuration)</TargetName>
<IntDir>tmp\$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<TargetName>rsx_program_decompiler</TargetName>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>

30
shader_code/builder.cpp Normal file
View File

@@ -0,0 +1,30 @@
#include "pch.h"
#include "builder.h"
namespace shader_code
{
builder::expression_base_t::expression_base_t(const std::string& text)
: text(text)
{
}
std::string builder::expression_base_t::to_string() const
{
return text;
}
std::string builder::expression_base_t::finalize(bool put_end) const
{
return to_string();
}
builder::writer_t::writer_to builder::writer_t::operator()(std::size_t position)
{
return{ &code[position] };
}
void builder::writer_t::next()
{
++position;
}
}

78
shader_code/builder.h Normal file
View File

@@ -0,0 +1,78 @@
#pragma once
#include <string>
#include <unordered_map>
namespace shader_code
{
struct builder
{
template<typename TypeType, TypeType Type, int Count>
struct type_t
{
static constexpr TypeType type = Type;
static constexpr int count = Count;
};
struct expression_base_t
{
std::string text;
expression_base_t() = default;
expression_base_t(const std::string& text);
virtual std::string to_string() const;
virtual std::string finalize(bool put_end) const;
};
struct writer_t : expression_base_t
{
std::unordered_map<std::size_t, std::string> code;
std::size_t position = 0;
struct writer_to
{
std::string *code;
};
writer_to operator()(std::size_t position);
template<typename... T>
void lines(const T&... exprs)
{
for (auto& expr : { exprs.finalize(true)... })
{
code[position] += expr + "\n";
}
}
void lines(const std::string& string)
{
code[position] += string + "\n";
}
void next();
template<typename T>
writer_t& operator +=(const T& expr)
{
lines(expr);
return *this;
}
std::string build()
{
for (auto entry : code)
{
text += entry.second;
}
code.clear();
return text;
}
std::string to_string() const override
{
return const_cast<writer_t*>(this)->build();
}
};
};
}

337
shader_code/clike_builder.h Normal file
View File

@@ -0,0 +1,337 @@
#pragma once
#include "builder.h"
#include "clike_language.h"
namespace shader_code
{
template<typename Language>
struct clike_builder : clike_language, builder
{
using language = Language;
template<type_class_t Type, int Count>
struct type_helper_t : clike_language::type_t<Type, Count>
{
protected:
template<type_class_t ExprType = Type, int ExprCount = Count>
using expression_t = typename clike_language::expression_t<ExprType, ExprCount>;
public:
static expression_t<> ctor()
{
return invoke();
}
static expression_t<> ctor(typename native_type_t<Type>::type value)
{
return invoke(expression_t<Type, 1>(native_type_t<Type>::to_string(value)));
}
template<type_class_t FromType>
static expression_t<> ctor(expression_t<FromType> expr)
{
return invoke(expr);
}
constexpr static const char* name()
{
return language::type_name_t<Type, Count>::name;
}
protected:
template<typename... T>
static expression_t<> invoke(T... exprs)
{
return function_t<clike_language::type_t<Type, Count>, language::type_name_t<Type, Count>>::invoke(exprs...);
}
};
template<type_class_t Type, int Count>
struct type_t;
template<type_class_t Type>
struct type_t<Type, 1> : type_helper_t<Type, 1>
{
using type_helper_t::ctor;
};
template<type_class_t Type>
struct type_t<Type, 2> : type_helper_t<Type, 2>
{
using type_helper_t::ctor;
template<type_class_t FromType>
static expression_t<> ctor(expression_t<FromType, 1> expr)
{
return invoke(expr);
}
static expression_t<> ctor(expression_t<Type, 1> a, expression_t<Type, 1> b)
{
return invoke(a, b);
}
};
template<type_class_t Type>
struct type_t<Type, 3> : type_helper_t<Type, 3>
{
using type_helper_t::ctor;
template<type_class_t FromType>
static expression_t<> ctor(expression_t<FromType, 1> expr)
{
return invoke(expr);
}
static expression_t<> ctor(expression_t<Type, 1> a, expression_t<Type, 2> b)
{
return invoke(a, b);
}
static expression_t<> ctor(expression_t<Type, 2> a, expression_t<Type, 1> b)
{
return invoke(a, b);
}
static expression_t<> ctor(expression_t<Type, 1> a, expression_t<Type, 1> b, expression_t<Type, 1> c)
{
return invoke(a, b, c);
}
};
template<type_class_t Type>
struct type_t<Type, 4> : type_helper_t<Type, 4>
{
using type_helper_t::ctor;
template<type_class_t FromType>
static expression_t<> ctor(expression_t<FromType, 1> expr)
{
return invoke(expr);
}
static expression_t<> ctor(expression_t<Type, 1> a, expression_t<Type, 3> b)
{
return invoke(a, b);
}
static expression_t<> ctor(expression_t<Type, 3> a, expression_t<Type, 1> b)
{
return invoke(a, b);
}
static expression_t<> ctor(expression_t<Type, 2> a, expression_t<Type, 2> b)
{
return invoke(a, b);
}
static expression_t<> ctor(expression_t<Type, 1> a, expression_t<Type, 1> b, expression_t<Type, 1> c, expression_t<Type, 1> d)
{
return invoke(a, b, c, d);
}
static expression_t<> ctor(expression_t<Type, 2> a, expression_t<Type, 1> b, expression_t<Type, 1> c)
{
return invoke(a, b, c);
}
static expression_t<> ctor(expression_t<Type, 1> a, expression_t<Type, 2> b, expression_t<Type, 1> c)
{
return invoke(a, b, c);
}
static expression_t<> ctor(expression_t<Type, 1> a, expression_t<Type, 1> b, expression_t<Type, 2> c)
{
return invoke(a, b, c);
}
};
using sampler1D_t = typename type_t<type_class_t::type_sampler1D, 1>;
using sampler2D_t = typename type_t<type_class_t::type_sampler2D, 1>;
using sampler3D_t = typename type_t<type_class_t::type_sampler3D, 1>;
template<size_t Count>
using boolean_t = typename type_t<type_class_t::type_bool, Count>;
template<size_t Count>
using integer_t = typename type_t<type_class_t::type_int, Count>;
template<size_t Count>
using float_point_t = typename type_t<type_class_t::type_float, Count>;
static expression_from<float_point_t<4>> texture(const expression_from<sampler1D_t>& texture, const expression_from<float_point_t<1>>& coord)
{
return function_t<float_point_t<4>, language::function_name_t<function_class_t::function_texture>>::invoke(texture, coord);
}
static expression_from<float_point_t<4>> texture(const expression_from<sampler2D_t>& texture, const expression_from<float_point_t<2>>& coord)
{
return function_t<float_point_t<4>, language::function_name_t<function_class_t::function_texture>>::invoke(texture, coord);
}
static expression_from<float_point_t<4>> texture_lod(const expression_from<sampler2D_t>& texture, const expression_from<float_point_t<2>>& coord, const expression_from<float_point_t<1>>& lod)
{
return function_t<float_point_t<4>, language::function_name_t<function_class_t::function_texture_lod>>::invoke(texture, coord, lod);
}
static expression_from<float_point_t<4>> texture_bias(const expression_from<sampler2D_t>& texture, const expression_from<float_point_t<2>>& coord, const expression_from<float_point_t<1>>& bias)
{
return function_t<float_point_t<4>, language::function_name_t<function_class_t::function_texture_bias>>::invoke(texture, coord, bias);
}
static expression_from<float_point_t<4>> texture_grad(const expression_from<sampler2D_t>& texture, const expression_from<float_point_t<2>>& coord, const expression_from<float_point_t<2>>& ddx, const expression_from<float_point_t<2>>& ddy)
{
return function_t<float_point_t<4>, language::function_name_t<function_class_t::function_texture_grad>>::invoke(texture, coord, ddx, ddy);
}
static expression_from<float_point_t<4>> texture(const expression_from<sampler3D_t>& texture, const expression_from<float_point_t<3>>& coord)
{
return function_t<float_point_t<4>, language::function_name_t<function_class_t::function_texture>>::invoke(texture, coord);
}
template<int Count>
static expression_from<float_point_t<Count>> normalize(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_normalize>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> abs(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_abs>>::invoke(arg);
}
template<int Count>
static expression_from<integer_t<Count>> abs(const expression_t<type_class_t::type_int, Count>& arg)
{
return function_t<integer_t<Count>, language::function_name_t<function_class_t::function_abs>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> normalize(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_normalize>>::invoke(arg);
}
template<int Count>
static expression_from<boolean_t<1>> any(const expression_t<type_class_t::type_bool, Count>& arg)
{
return function_t<boolean_t<1>, language::function_name_t<function_class_t::function_any>>::invoke(arg);
}
template<int Count, typename = std::enable_if_t<(Count > 1)>>
static expression_from<boolean_t<1>> all(const expression_t<type_class_t::type_bool, Count>& arg)
{
return function_t<boolean_t<1>, language::function_name_t<function_class_t::function_all>>::invoke(arg);
}
template<int Count, typename = std::enable_if_t<(Count > 1)>>
static expression_from<float_point_t<1>> dot(const expression_t<type_class_t::type_float, Count>& a, const expression_t<type_class_t::type_float, Count>& b)
{
return function_t<float_point_t<1>, language::function_name_t<function_class_t::function_dot>>::invoke(a, b);
}
template<type_class_t Type, int Count>
static expression_t<Type, Count> min(const expression_t<Type, Count>& a, const expression_t<Type, Count>& b)
{
return function_t<type_t<Type, Count>, language::function_name_t<function_class_t::function_min>>::invoke(a, b);
}
template<type_class_t Type, int Count>
static expression_t<Type, Count> max(const expression_t<Type, Count>& a, const expression_t<Type, Count>& b)
{
return function_t<type_t<Type, Count>, language::function_name_t<function_class_t::function_max>>::invoke(a, b);
}
template<type_class_t Type, int Count, typename = std::enable_if_t<(Count > 1)>>
static expression_from<boolean_t<Count>> greater(const expression_t<Type, Count>& a, const expression_t<Type, Count>& b)
{
return function_t<boolean_t<Count>, language::function_name_t<function_class_t::function_greater>>::invoke(a, b);
}
template<type_class_t Type, int Count, typename = std::enable_if_t<(Count > 1)>>
static expression_from<boolean_t<Count>> less(const expression_t<Type, Count>& a, const expression_t<Type, Count>& b)
{
return function_t<boolean_t<Count>, language::function_name_t<function_class_t::function_less>>::invoke(a, b);
}
template<type_class_t Type, int Count, typename = std::enable_if_t<(Count > 1)>>
static expression_from<boolean_t<Count>> equal(const expression_t<Type, Count>& a, const expression_t<Type, Count>& b)
{
return function_t<boolean_t<Count>, language::function_name_t<function_class_t::function_equal>>::invoke(a, b);
}
template<type_class_t Type, int Count, typename = std::enable_if_t<(Count > 1)>>
static expression_from<boolean_t<Count>> greater_equal(const expression_t<Type, Count>& a, const expression_t<Type, Count>& b)
{
return function_t<boolean_t<Count>, language::function_name_t<function_class_t::function_greater_equal>>::invoke(a, b);
}
template<type_class_t Type, int Count, typename = std::enable_if_t<(Count > 1)>>
static expression_from<boolean_t<Count>> less_equal(const expression_t<Type, Count>& a, const expression_t<Type, Count>& b)
{
return function_t<boolean_t<Count>, language::function_name_t<function_class_t::function_less_equal>>::invoke(a, b);
}
template<type_class_t Type, int Count, typename = std::enable_if_t<(Count > 1)>>
static expression_from<boolean_t<Count>> not_equal(const expression_t<Type, Count>& a, const expression_t<Type, Count>& b)
{
return function_t<boolean_t<Count>, language::function_name_t<function_class_t::function_not_equal>>::invoke(a, b);
}
template<int Count>
static expression_from<float_point_t<Count>> fract(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_fract>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> floor(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_floor>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> sin(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_sin>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> cos(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_cos>>::invoke(arg);
}
template<type_class_t Type, int Count>
static expression_from<expression_t<Type, Count>> clamp(const expression_t<Type, Count>& a, const expression_t<Type, 1>& b, const expression_t<Type, 1>& c)
{
return function_t<type_t<Type, Count>, language::function_name_t<function_class_t::function_clamp>>::invoke(a, b, c);
}
template<int Count>
static expression_from<float_point_t<Count>> sqrt(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_sqrt>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> rsqrt(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_rsqrt>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> pow(const expression_t<type_class_t::type_float, Count>& a, const expression_t<type_class_t::type_float, Count>& b)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_pow>>::invoke(a, b);
}
template<int Count>
static expression_from<float_point_t<Count>> exp2(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_exp2>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> log2(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_log2>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> ddx(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_ddx>>::invoke(arg);
}
template<int Count>
static expression_from<float_point_t<Count>> ddy(const expression_t<type_class_t::type_float, Count>& arg)
{
return function_t<float_point_t<Count>, language::function_name_t<function_class_t::function_ddy>>::invoke(arg);
}
};
}

View File

@@ -0,0 +1,15 @@
#include "pch.h"
#include "clike_language.h"
namespace shader_code
{
clike_language::expression_from<clike_language::void_t> clike_language::begin_block()
{
return expression<void_t>("\n{\n");
}
clike_language::expression_from<clike_language::void_t> clike_language::end_block()
{
return expression<void_t>("\n}\n");
}
}

View File

@@ -0,0 +1,579 @@
#pragma once
#include "builder.h"
namespace shader_code
{
struct clike_language
{
enum class type_class_t
{
type_void,
type_bool,
type_int,
type_float,
type_sampler1D,
type_sampler2D,
type_sampler3D
};
template<typename Type>
struct native_type_base_t
{
using type = Type;
static std::string to_string(Type value)
{
return std::to_string(value);
}
};
template<type_class_t Type>
struct native_type_t;
template<>
struct native_type_t<type_class_t::type_bool>
{
using type = bool;
static std::string to_string(type value)
{
return value ? "true" : "false";
}
};
template<>
struct native_type_t<type_class_t::type_int> : native_type_base_t<int>
{
};
template<>
struct native_type_t<type_class_t::type_float> : native_type_base_t<float>
{
};
template<>
struct native_type_t<type_class_t::type_sampler1D> : native_type_base_t<int>
{
};
template<>
struct native_type_t<type_class_t::type_sampler2D> : native_type_base_t<int>
{
};
template<>
struct native_type_t<type_class_t::type_sampler3D> : native_type_base_t<int>
{
};
template<type_class_t Type, int Count>
using type_t = builder::type_t<type_class_t, Type, Count>;
template<size_t Count>
using boolean_t = typename type_t<type_class_t::type_bool, Count>;
template<size_t Count>
using integer_t = typename type_t<type_class_t::type_int, Count>;
template<size_t Count>
using float_point_t = typename type_t<type_class_t::type_float, Count>;
using sampler1D_t = type_t<type_class_t::type_sampler1D, 1>;
using sampler2D_t = type_t<type_class_t::type_sampler2D, 1>;
using sampler3D_t = type_t<type_class_t::type_sampler3D, 1>;
using void_t = type_t<type_class_t::type_void, 0>;
enum function_class_t
{
function_abs,
function_fract,
function_floor,
function_exp2,
function_log2,
function_pow,
function_texture,
function_texture_lod,
function_texture_bias,
function_texture_grad,
function_normalize,
function_any,
function_all,
function_dot,
function_min,
function_max,
function_greater,
function_less,
function_equal,
function_greater_equal,
function_less_equal,
function_not_equal,
function_sin,
function_cos,
function_clamp,
function_sqrt,
function_rsqrt,
function_ddx,
function_ddy
};
template<type_class_t Type, int Count>
struct expression_t;
template<typename Type>
using expression_from = expression_t<Type::type, Type::count>;
template<type_class_t Type, int Count>
struct expression_helper_t : builder::expression_base_t
{
using type = type_t<Type, Count>;
std::string mask;
bool is_single;
int base_count = Count;
expression_helper_t(const std::string& text, bool is_single = true)
: expression_base_t{ text }
, is_single(is_single)
, mask{ std::string("xyzw").substr(0, Count) }
{
}
expression_helper_t(const std::string& text, const std::string& mask, bool is_single = true, int base_count = Count)
: expression_base_t{ text }
, is_single(is_single)
, mask(mask)
, base_count(base_count)
{
}
template<size_t N>
expression_helper_t(const std::string& text, const char (&mask)[N], bool is_single = true, int base_count = Count)
: expression_helper_t{ text, std::string(mask), is_single, base_count }
{
static_assert(N == Count + 1, "Bad swizzle!");
}
void assign(const expression_helper_t& rhs)
{
text = rhs.text;
mask = rhs.mask;
is_single = rhs.is_single;
}
template<typename... Channels>
auto swizzle(Channels... channels) const -> expression_t<Type, sizeof...(channels)>
{
static_assert(sizeof...(channels) <= 4 && sizeof...(channels) > 0, "bad swizzle");
std::string new_mask;
using sw = std::string[]; sw{ (new_mask += mask.substr(channels, 1))... };
return{ !is_single ? "(" + text + ")" : text, new_mask, is_single, base_count };
}
std::string to_string() const override
{
if (mask.empty() || mask == std::string("xyzw").substr(0, base_count))
{
if (!is_single)
{
return "(" + text + ")";
}
return text;
}
if (!is_single)
{
return "(" + text + ")." + mask;
}
return text + "." + mask;
}
std::string finalize(bool put_end) const override
{
if (mask.empty() || mask == std::string("xyzw").substr(0, base_count))
{
return text + (put_end ? ";" : "");
}
return text + "." + mask + (put_end ? ";" : "");
}
expression_t<Type, Count> scope() const
{
return{ to_string() };
}
//protected:
template<typename RetType = type, typename ArgType>
expression_t<RetType::type, RetType::count> call_operator(const std::string& opname, const ArgType& rhs) const
{
return{ to_string() + " " + opname + " " + rhs.to_string(), false };
}
template<typename RetType = type>
expression_t<RetType::type, RetType::count> call_operator(const std::string& opname) const
{
return{ opname + to_string(), true };
}
};
template<type_class_t Type, int Count>
struct expression_ctors_t : expression_helper_t<Type, Count>
{
using expression_helper_t::expression_helper_t;
};
template<type_class_t Type>
struct expression_ctors_t<Type, 1> : expression_helper_t<Type, 1>
{
expression_ctors_t(typename native_type_t<Type>::type value)
: expression_helper_t(native_type_t<Type>::to_string(value))
{
}
using expression_helper_t::expression_helper_t;
};
#define _SWIZZLE_MASK(pos) mask.substr(pos, 1)
#define _SWIZZLE_FUNC(Count, Name, ...) expression_t<Type, Count> Name() const { return swizzle(__VA_ARGS__); }
#define SWIZZLE1(Xn, Xv) _SWIZZLE_FUNC(1, Xn, (Xv))
#define SWIZZLE2(Xn, Xv, Yn, Yv) _SWIZZLE_FUNC(2, Xn##Yn, Xv, Yv)
#define SWIZZLE3(Xn, Xv, Yn, Yv, Zn, Zv) _SWIZZLE_FUNC(3, Xn##Yn##Zn, Xv, Yv, Zv)
#define SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, Wn, Wv) _SWIZZLE_FUNC(4, Xn##Yn##Zn##Wn, Xv, Yv, Zv, Wv)
#define SWIZZLE4_2_1(Xn, Xv) \
SWIZZLE2(Xn, Xv, x, 0) \
SWIZZLE2(Xn, Xv, y, 1) \
SWIZZLE2(Xn, Xv, z, 2) \
SWIZZLE2(Xn, Xv, w, 3) \
#define SWIZZLE3_2_1(Xn, Xv) \
SWIZZLE2(Xn, Xv, x, 0) \
SWIZZLE2(Xn, Xv, y, 1) \
SWIZZLE2(Xn, Xv, z, 2) \
#define SWIZZLE2_2_1(Xn, Xv) \
SWIZZLE2(Xn, Xv, x, 0) \
SWIZZLE2(Xn, Xv, y, 1) \
#define SWIZZLE4_3_2(Xn, Xv, Yn, Yv) \
SWIZZLE3(Xn, Xv, Yn, Yv, x, 0) \
SWIZZLE3(Xn, Xv, Yn, Yv, y, 1) \
SWIZZLE3(Xn, Xv, Yn, Yv, z, 2) \
SWIZZLE3(Xn, Xv, Yn, Yv, w, 3) \
#define SWIZZLE3_3_2(Xn, Xv, Yn, Yv) \
SWIZZLE3(Xn, Xv, Yn, Yv, x, 0) \
SWIZZLE3(Xn, Xv, Yn, Yv, y, 1) \
SWIZZLE3(Xn, Xv, Yn, Yv, z, 2) \
#define SWIZZLE2_3_2(Xn, Xv, Yn, Yv) \
SWIZZLE3(Xn, Xv, Yn, Yv, x, 0) \
SWIZZLE3(Xn, Xv, Yn, Yv, y, 1) \
#define SWIZZLE4_3_1(Xn, Xv) \
SWIZZLE4_3_2(Xn, Xv, x, 0) \
SWIZZLE4_3_2(Xn, Xv, y, 1) \
SWIZZLE4_3_2(Xn, Xv, z, 2) \
SWIZZLE4_3_2(Xn, Xv, w, 3) \
#define SWIZZLE3_3_1(Xn, Xv) \
SWIZZLE3_3_2(Xn, Xv, x, 0) \
SWIZZLE3_3_2(Xn, Xv, y, 1) \
SWIZZLE3_3_2(Xn, Xv, z, 2) \
#define SWIZZLE2_3_1(Xn, Xv) \
SWIZZLE2_3_2(Xn, Xv, x, 0) \
SWIZZLE2_3_2(Xn, Xv, y, 1) \
#define SWIZZLE4_4_3(Xn, Xv, Yn, Yv, Zn, Zv) \
SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, x, 0) \
SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, y, 1) \
SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, z, 2) \
SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, w, 3) \
#define SWIZZLE3_4_3(Xn, Xv, Yn, Yv, Zn, Zv) \
SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, x, 0) \
SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, y, 1) \
SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, z, 2) \
#define SWIZZLE2_4_3(Xn, Xv, Yn, Yv, Zn, Zv) \
SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, x, 0) \
SWIZZLE4(Xn, Xv, Yn, Yv, Zn, Zv, y, 1) \
#define SWIZZLE4_4_2(Xn, Xv, Yn, Yv) \
SWIZZLE4_4_3(Xn, Xv, Yn, Yv, x, 0) \
SWIZZLE4_4_3(Xn, Xv, Yn, Yv, y, 1) \
SWIZZLE4_4_3(Xn, Xv, Yn, Yv, z, 2) \
SWIZZLE4_4_3(Xn, Xv, Yn, Yv, w, 3) \
#define SWIZZLE3_4_2(Xn, Xv, Yn, Yv) \
SWIZZLE3_4_3(Xn, Xv, Yn, Yv, x, 0) \
SWIZZLE3_4_3(Xn, Xv, Yn, Yv, y, 1) \
SWIZZLE3_4_3(Xn, Xv, Yn, Yv, z, 2) \
#define SWIZZLE2_4_2(Xn, Xv, Yn, Yv) \
SWIZZLE2_4_3(Xn, Xv, Yn, Yv, x, 0) \
SWIZZLE2_4_3(Xn, Xv, Yn, Yv, y, 1) \
#define SWIZZLE4_4_1(Xn, Xv) \
SWIZZLE4_4_2(Xn, Xv, x, 0) \
SWIZZLE4_4_2(Xn, Xv, y, 1) \
SWIZZLE4_4_2(Xn, Xv, z, 2) \
SWIZZLE4_4_2(Xn, Xv, w, 3) \
#define SWIZZLE3_4_1(Xn, Xv) \
SWIZZLE3_4_2(Xn, Xv, x, 0) \
SWIZZLE3_4_2(Xn, Xv, y, 1) \
SWIZZLE3_4_2(Xn, Xv, z, 2) \
#define SWIZZLE2_4_1(Xn, Xv) \
SWIZZLE2_4_2(Xn, Xv, x, 0) \
SWIZZLE2_4_2(Xn, Xv, y, 1) \
template<type_class_t Type, int Count>
struct expression_swizzle_t : expression_ctors_t<Type, Count>
{
using expression_ctors_t::expression_ctors_t;
};
template<type_class_t Type>
struct expression_swizzle_t<Type, 2> : expression_ctors_t<Type, 2>
{
using expression_ctors_t::expression_ctors_t;
SWIZZLE1(x, 0)
SWIZZLE1(y, 1)
SWIZZLE2_2_1(x, 0)
SWIZZLE2_2_1(y, 1)
SWIZZLE2_3_1(x, 0)
SWIZZLE2_3_1(y, 1)
SWIZZLE2_4_1(x, 0)
SWIZZLE2_4_1(y, 1)
};
template<type_class_t Type>
struct expression_swizzle_t<Type, 3> : expression_ctors_t<Type, 3>
{
using expression_ctors_t::expression_ctors_t;
SWIZZLE1(x, 0)
SWIZZLE1(y, 1)
SWIZZLE1(z, 2)
SWIZZLE3_2_1(x, 0)
SWIZZLE3_2_1(y, 1)
SWIZZLE3_2_1(z, 2)
SWIZZLE3_3_1(x, 0)
SWIZZLE3_3_1(y, 1)
SWIZZLE3_3_1(z, 2)
SWIZZLE3_4_1(x, 0)
SWIZZLE3_4_1(y, 1)
SWIZZLE3_4_1(z, 2)
};
template<type_class_t Type>
struct expression_swizzle_t<Type, 4> : expression_ctors_t<Type, 4>
{
using expression_ctors_t::expression_ctors_t;
SWIZZLE1(x, 0)
SWIZZLE1(y, 1)
SWIZZLE1(z, 2)
SWIZZLE1(w, 3)
SWIZZLE4_2_1(x, 0)
SWIZZLE4_2_1(y, 1)
SWIZZLE4_2_1(z, 2)
SWIZZLE4_2_1(w, 3)
SWIZZLE4_3_1(x, 0)
SWIZZLE4_3_1(y, 1)
SWIZZLE4_3_1(z, 2)
SWIZZLE4_3_1(w, 3)
SWIZZLE4_4_1(x, 0)
SWIZZLE4_4_1(y, 1)
SWIZZLE4_4_1(z, 2)
SWIZZLE4_4_1(w, 3)
};
template<type_class_t Type, int Count>
struct expression_t : expression_swizzle_t<Type, Count>
{
using expression_swizzle_t::expression_swizzle_t;
const expression_t operator -()
{
if (is_single && text[0] == '-')
return expression_t{ text.substr(1), mask };
return call_operator("-");
}
const expression_t operator-(const expression_t& rhs) const
{
if (rhs.is_single && rhs.text[0] == '-')
return call_operator("+", expression_t{ rhs.text.substr(1), rhs.mask });
return call_operator("-", rhs);
}
const expression_t operator+(const expression_t& rhs) const
{
if (rhs.is_single && rhs.text[0] == '-')
return call_operator("-", expression_t{ rhs.text.substr(1), rhs.mask });
return call_operator("+", rhs);
}
const expression_t operator/(const expression_t& rhs) const { return call_operator("/", rhs); }
const expression_t operator*(const expression_t& rhs) const { return call_operator("*", rhs); }
expression_t operator-=(const expression_t& rhs) { return call_operator("-=", rhs); }
expression_t operator+=(const expression_t& rhs) { return call_operator("+=", rhs); }
expression_t operator/=(const expression_t& rhs) { return call_operator("/=", rhs); }
expression_t operator*=(const expression_t& rhs) { return call_operator("*=", rhs); }
expression_t operator=(const expression_t& rhs) { return call_operator("=", rhs); }
const expression_t operator-(const expression_t<Type, 1>& rhs) const { return call_operator("-", rhs); }
const expression_t operator+(const expression_t<Type, 1>& rhs) const { return call_operator("+", rhs); }
const expression_t operator/(const expression_t<Type, 1>& rhs) const { return call_operator("/", rhs); }
const expression_t operator*(const expression_t<Type, 1>& rhs) const { return call_operator("*", rhs); }
expression_t operator-=(const expression_t<Type, 1>& rhs) { return call_operator("-=", rhs); }
expression_t operator+=(const expression_t<Type, 1>& rhs) { return call_operator("+=", rhs); }
expression_t operator/=(const expression_t<Type, 1>& rhs) { return call_operator("/=", rhs); }
expression_t operator*=(const expression_t<Type, 1>& rhs) { return call_operator("*=", rhs); }
};
template<>
struct expression_t<type_class_t::type_bool, 1> : expression_swizzle_t<type_class_t::type_bool, 1>
{
using expression_swizzle_t::expression_swizzle_t;
expression_t operator=(const expression_t& rhs) { return call_operator("=", rhs); }
const expression_from<boolean_t<1>> operator!() const { return call_operator<boolean_t<1>>("!"); }
const expression_from<boolean_t<1>> operator==(const expression_t& rhs) const { return call_operator<boolean_t<1>>("==", rhs); }
const expression_from<boolean_t<1>> operator!=(const expression_t& rhs) const { return call_operator<boolean_t<1>>("!=", rhs); }
};
template<int Count>
struct expression_t<type_class_t::type_bool, Count> : expression_swizzle_t<type_class_t::type_bool, Count>
{
using expression_swizzle_t::expression_swizzle_t;
expression_t operator=(const expression_t& rhs) { return call_operator("=", rhs); }
};
template<type_class_t Type>
struct expression_t<Type, 1> : expression_swizzle_t<Type, 1>
{
using expression_swizzle_t::expression_swizzle_t;
const expression_t operator -()
{
if (is_single && text[0] == '-')
return expression_t{ text.substr(1), mask };
return call_operator("-");
}
const expression_t operator-(const expression_t& rhs) const
{
if (rhs.is_single && rhs.text[0] == '-')
return call_operator("+", expression_t{ rhs.text.substr(1), rhs.mask });
return call_operator("-", rhs);
}
const expression_t operator+(const expression_t& rhs) const
{
if (rhs.is_single && rhs.text[0] == '-')
return call_operator("-", expression_t{ rhs.text.substr(1), rhs.mask });
return call_operator("+", rhs);
}
template<int Count> const expression_t<Type, Count> operator/(const expression_t<Type, Count>& rhs) const { return call_operator<type_t<Type, Count>>("/", rhs); }
template<int Count> const expression_t<Type, Count> operator*(const expression_t<Type, Count>& rhs) const { return call_operator<type_t<Type, Count>>("*", rhs); }
expression_t operator=(const expression_t& rhs) { return call_operator("=", rhs); }
expression_t operator-=(const expression_t& rhs) { return call_operator("-=", rhs); }
expression_t operator+=(const expression_t& rhs) { return call_operator("+=", rhs); }
expression_t operator/=(const expression_t& rhs) { return call_operator("/=", rhs); }
expression_t operator*=(const expression_t& rhs) { return call_operator("*=", rhs); }
const expression_from<boolean_t<1>> operator >(const expression_t& rhs) const { return call_operator<boolean_t<1>>(">", rhs); }
const expression_from<boolean_t<1>> operator >=(const expression_t& rhs) const { return call_operator<boolean_t<1>>(">=", rhs); }
const expression_from<boolean_t<1>> operator <(const expression_t& rhs) const { return call_operator<boolean_t<1>>("<", rhs); }
const expression_from<boolean_t<1>> operator <=(const expression_t& rhs) const { return call_operator<boolean_t<1>>("<=", rhs); }
const expression_from<boolean_t<1>> operator==(const expression_t& rhs) const { return call_operator<boolean_t<1>>("==", rhs); }
const expression_from<boolean_t<1>> operator!=(const expression_t& rhs) const { return call_operator<boolean_t<1>>("!=", rhs); }
};
template<typename Type>
static expression_t<(type_class_t)Type::type, Type::count> expression(const std::string& text, bool is_single = true)
{
return{ text, is_single };
}
template<typename Type, typename NameType>
struct function_t
{
using return_type = Type;
template<typename... ArgsType>
static expression_t<(type_class_t)return_type::type, return_type::count> invoke(const ArgsType&... args)
{
std::string result;
using sw = std::string[]; sw{ (result += (result.empty() ? "" : ", ") + args.finalize(false))..., "" };
return{ std::string(NameType::name) + "(" + result + ")" };
}
};
template<typename ReturnType, typename... ArgsType, typename NameType>
struct function_t<ReturnType(ArgsType...), NameType>
{
using return_type = ReturnType;
static expression_from<return_type> invoke(const expression_from<ArgsType>&... args)
{
std::string result = std::string(NameType::name) + "(";
using sw = std::string[]; sw{ (result += args.to_string())..., "" };
return{ result + ")" };
}
};
template<type_class_t Type, int Count>
static expression_from<void_t> if_(expression_from<boolean_t<1>> condition, expression_t<Type, Count> then)
{
return expression<void_t>("if (" + condition.finalize(false) + ") " + then.finalize(false));
}
template<type_class_t ThenType, int ThenCount, type_class_t ElseType, int ElseCount>
static expression_from<void_t> if_(expression_from<boolean_t<1>> condition, expression_t<ThenType, ThenCount> then, expression_t<ElseType, ElseCount> else_)
{
return expression<void_t>("if (" + condition.finalize(false) + ") " + then.finalize() + " else " + else_.finalize(false));
}
static expression_from<void_t> begin_block();
static expression_from<void_t> end_block();
};
}

View File

@@ -0,0 +1,24 @@
#pragma once
#include "clike_builder.h"
#include "glsl_language.h"
namespace shader_code
{
struct glsl_builder : clike_builder<glsl_language>
{
using bool_t = boolean_t<1>;
using bvec2_t = boolean_t<2>;
using bvec3_t = boolean_t<3>;
using bvec4_t = boolean_t<4>;
using int_t = integer_t<1>;
using ivec2_t = integer_t<2>;
using ivec3_t = integer_t<3>;
using ivec4_t = integer_t<4>;
using float_t = float_point_t<1>;
using vec2_t = float_point_t<2>;
using vec3_t = float_point_t<3>;
using vec4_t = float_point_t<4>;
};
}

268
shader_code/glsl_language.h Normal file
View File

@@ -0,0 +1,268 @@
#pragma once
#include "clike_language.h"
namespace shader_code
{
struct glsl_language
{
template<clike_language::type_class_t Type, int Count>
struct type_name_t;
template<>
struct type_name_t<clike_language::type_class_t::type_bool, 1>
{
static constexpr char *name = "bool";
};
template<>
struct type_name_t<clike_language::type_class_t::type_bool, 2>
{
static constexpr char *name = "bvec2";
};
template<>
struct type_name_t<clike_language::type_class_t::type_bool, 3>
{
static constexpr char *name = "bvec3";
};
template<>
struct type_name_t<clike_language::type_class_t::type_bool, 4>
{
static constexpr char *name = "bvec4";
};
template<>
struct type_name_t<clike_language::type_class_t::type_int, 1>
{
static constexpr char *name = "int";
};
template<>
struct type_name_t<clike_language::type_class_t::type_int, 2>
{
static constexpr char *name = "ivec2";
};
template<>
struct type_name_t<clike_language::type_class_t::type_int, 3>
{
static constexpr char *name = "ivec3";
};
template<>
struct type_name_t<clike_language::type_class_t::type_int, 4>
{
static constexpr char *name = "ivec4";
};
template<>
struct type_name_t<clike_language::type_class_t::type_float, 1>
{
static constexpr char *name = "float";
};
template<>
struct type_name_t<clike_language::type_class_t::type_float, 2>
{
static constexpr char *name = "vec2";
};
template<>
struct type_name_t<clike_language::type_class_t::type_float, 3>
{
static constexpr char *name = "vec3";
};
template<>
struct type_name_t<clike_language::type_class_t::type_float, 4>
{
static constexpr char *name = "vec4";
};
template<>
struct type_name_t<clike_language::type_class_t::type_sampler1D, 1>
{
static constexpr char *name = "sampler1D";
};
template<>
struct type_name_t<clike_language::type_class_t::type_sampler2D, 1>
{
static constexpr char *name = "sampler2D";
};
template<>
struct type_name_t<clike_language::type_class_t::type_sampler3D, 1>
{
static constexpr char *name = "sampler3D";
};
template<clike_language::function_class_t Function>
struct function_name_t;
template<>
struct function_name_t<clike_language::function_class_t::function_abs>
{
static constexpr char *name = "abs";
};
template<>
struct function_name_t<clike_language::function_class_t::function_normalize>
{
static constexpr char *name = "normalize";
};
template<>
struct function_name_t<clike_language::function_class_t::function_floor>
{
static constexpr char *name = "floor";
};
template<>
struct function_name_t<clike_language::function_class_t::function_fract>
{
static constexpr char *name = "fract";
};
template<>
struct function_name_t<clike_language::function_class_t::function_pow>
{
static constexpr char *name = "pow";
};
template<>
struct function_name_t<clike_language::function_class_t::function_texture>
{
static constexpr char *name = "texture";
};
template<>
struct function_name_t<clike_language::function_class_t::function_normalize>
{
static constexpr char *name = "normalize";
};
template<>
struct function_name_t<clike_language::function_class_t::function_any>
{
static constexpr char *name = "any";
};
template<>
struct function_name_t<clike_language::function_class_t::function_all>
{
static constexpr char *name = "all";
};
template<>
struct function_name_t<clike_language::function_class_t::function_dot>
{
static constexpr char *name = "dot";
};
template<>
struct function_name_t<clike_language::function_class_t::function_greater>
{
static constexpr char *name = "greaterThan";
};
template<>
struct function_name_t<clike_language::function_class_t::function_less>
{
static constexpr char *name = "lessThan";
};
template<>
struct function_name_t<clike_language::function_class_t::function_equal>
{
static constexpr char *name = "equal";
};
template<>
struct function_name_t<clike_language::function_class_t::function_greater_equal>
{
static constexpr char *name = "greaterThanEqual";
};
template<>
struct function_name_t<clike_language::function_class_t::function_less_equal>
{
static constexpr char *name = "lessThanEqual";
};
template<>
struct function_name_t<clike_language::function_class_t::function_not_equal>
{
static constexpr char *name = "notEqual";
};
template<>
struct function_name_t<clike_language::function_class_t::function_sin>
{
static constexpr char *name = "sin";
};
template<>
struct function_name_t<clike_language::function_class_t::function_cos>
{
static constexpr char *name = "cos";
};
template<>
struct function_name_t<clike_language::function_class_t::function_clamp>
{
static constexpr char *name = "clamp";
};
template<>
struct function_name_t<clike_language::function_class_t::function_min>
{
static constexpr char *name = "min";
};
template<>
struct function_name_t<clike_language::function_class_t::function_max>
{
static constexpr char *name = "max";
};
template<>
struct function_name_t<clike_language::function_class_t::function_sqrt>
{
static constexpr char *name = "sqrt";
};
template<>
struct function_name_t<clike_language::function_class_t::function_rsqrt>
{
static constexpr char *name = "inversesqrt";
};
template<>
struct function_name_t<clike_language::function_class_t::function_exp2>
{
static constexpr char *name = "exp2";
};
template<>
struct function_name_t<clike_language::function_class_t::function_log2>
{
static constexpr char *name = "log2";
};
template<>
struct function_name_t<clike_language::function_class_t::function_ddx>
{
static constexpr char *name = "dFdx";
};
template<>
struct function_name_t<clike_language::function_class_t::function_ddy>
{
static constexpr char *name = "dFdy";
};
};
}

1
shader_code/pch.cpp Normal file
View File

@@ -0,0 +1 @@
#include "pch.h"

1
shader_code/pch.h Normal file
View File

@@ -0,0 +1 @@
#pragma once

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{97E17077-A21F-45EF-9C3A-73A0BC092D7E}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>shader_code</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)lib\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)tmp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="builder.cpp" />
<ClCompile Include="clike_language.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="builder.h" />
<ClInclude Include="clike_builder.h" />
<ClInclude Include="clike_language.h" />
<ClInclude Include="glsl_builder.h" />
<ClInclude Include="glsl_language.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="builder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="clike_language.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="builder.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="clike_builder.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="clike_language.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="glsl_builder.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="glsl_language.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
</Project>