Skip to content

Instantly share code, notes, and snippets.

@Triang3l
Last active June 17, 2018 17:59
Show Gist options
  • Save Triang3l/6a3ced63f318344864102bcd48510a15 to your computer and use it in GitHub Desktop.
Save Triang3l/6a3ced63f318344864102bcd48510a15 to your computer and use it in GitHub Desktop.
Updated CreateCubeFunction of Xenia SPIR-V shader translator that crashes RenderDoc's AMDIL disassembler
spv::Function* SpirvShaderTranslator::CreateCubeFunction() {
auto& b = *builder_;
spv::Block* function_block = nullptr;
auto function = b.makeFunctionEntry(spv::NoPrecision, vec4_float_type_,
"cube", {vec4_float_type_},
{{spv::NoPrecision}}, &function_block);
auto src = function->getParamId(0);
// The source parameter is ordered as .yxzz.
const unsigned int src_i_x = 1, src_i_y = 0, src_i_z = 2;
auto t_s_ma = b.createVariable(spv::StorageClass::StorageClassFunction,
vec4_float_type_, "t_s_ma");
// T scale, S scale, 2, face index.
auto scale = b.createVariable(spv::StorageClass::StorageClassFunction,
vec4_float_type_, "scale");
// Pseudocode:
// vec3 src = param.yxz;
// float t, s, ma, face;
// if (abs(src.x) >= abs(src.y) && abs(src.x) >= abs(src.z)) {
// t = -src.y;
// s = (src.x >= 0.0 ? -src.z : src.z);
// ma = src.x;
// face = (src.x >= 0.0 ? 0.0 : 1.0);
// } else if (abs(src.y) >= abs(src.z)) {
// t = (src.y >= 0.0 ? src.z : -src.z);
// s = src.x;
// ma = src.y;
// face = (src.y >= 0.0 ? 2.0 : 3.0);
// } else {
// t = -src.y;
// s = (src.z >= 0.0 ? src.x : -src.x);
// ma = src.z;
// face = (src.z >= 0.0 ? 4.0 : 5.0);
// }
// return vec4(t - 2.0 * abs(ma), s - 2.0 * abs(ma), 2.0 * ma, face);
auto abs_src = CreateGlslStd450InstructionCall(
spv::NoPrecision, vec4_float_type_, spv::GLSLstd450::kFAbs, {src});
auto abs_src_x = b.createCompositeExtract(abs_src, float_type_, src_i_x);
auto abs_src_y = b.createCompositeExtract(abs_src, float_type_, src_i_y);
auto abs_src_z = b.createCompositeExtract(abs_src, float_type_, src_i_z);
auto x_gt_y = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_,
abs_src_x, abs_src_y);
auto x_gt_z = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_,
abs_src_x, abs_src_z);
auto x_gt_yz = b.createBinOp(spv::Op::OpLogicalAnd, bool_type_,
x_gt_y, x_gt_z);
spv::Builder::If if_x_else_yz(x_gt_yz, 0, b);
{
// X is the major axis: +T = -Y, +S = -+Z.
auto t_s_ma_x = b.createOp(spv::Op::OpVectorShuffle, vec4_float_type_,
{src, src, src_i_y, src_i_z, src_i_x, 0});
b.createStore(t_s_ma_x, t_s_ma);
auto scale_pos_x = b.makeCompositeConstant(vec4_float_type_,
{b.makeFloatConstant(-1.0f),
b.makeFloatConstant(-1.0f),
b.makeFloatConstant(2.0f),
b.makeFloatConstant(0.0f)});
auto scale_neg_x = b.makeCompositeConstant(vec4_float_type_,
{b.makeFloatConstant(-1.0f),
b.makeFloatConstant(1.0f),
b.makeFloatConstant(2.0f),
b.makeFloatConstant(1.0f)});
auto ma_x = b.createCompositeExtract(t_s_ma_x, float_type_, 2);
auto ma_pos_x = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_,
ma_x, b.makeFloatConstant(0.0f));
auto scale_x = b.createTriOp(spv::Op::OpSelect, vec4_float_type_, ma_pos_x,
scale_pos_x, scale_neg_x);
b.createStore(scale_x, scale);
}
if_x_else_yz.makeBeginElse();
{
auto y_gt_z = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_,
abs_src_y, abs_src_z);
spv::Builder::If if_y_else_z(y_gt_z, 0, b);
{
// Y is the major axis: +T = +-Z, +S = +X.
auto t_s_ma_y = b.createOp(spv::Op::OpVectorShuffle, vec4_float_type_,
{src, src, src_i_z, src_i_x, src_i_y, 0});
b.createStore(t_s_ma_y, t_s_ma);
auto scale_pos_y = b.makeCompositeConstant(vec4_float_type_,
{b.makeFloatConstant(1.0f),
b.makeFloatConstant(1.0f),
b.makeFloatConstant(2.0f),
b.makeFloatConstant(2.0f)});
auto scale_neg_y = b.makeCompositeConstant(vec4_float_type_,
{b.makeFloatConstant(-1.0f),
b.makeFloatConstant(1.0f),
b.makeFloatConstant(2.0f),
b.makeFloatConstant(3.0f)});
auto ma_y = b.createCompositeExtract(t_s_ma_y, float_type_, 2);
auto ma_pos_y = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_,
ma_y, b.makeFloatConstant(0.0f));
auto scale_y = b.createTriOp(spv::Op::OpSelect, vec4_float_type_,
ma_pos_y, scale_pos_y, scale_neg_y);
b.createStore(scale_y, scale);
}
if_y_else_z.makeBeginElse();
{
// Z is the major axis: +T = -Y, +S = +-X.
auto t_s_ma_z = b.createOp(spv::Op::OpVectorShuffle, vec4_float_type_,
{src, src, src_i_y, src_i_x, src_i_z, 0});
b.createStore(t_s_ma_z, t_s_ma);
auto scale_pos_z = b.makeCompositeConstant(vec4_float_type_,
{b.makeFloatConstant(-1.0f),
b.makeFloatConstant(1.0f),
b.makeFloatConstant(2.0f),
b.makeFloatConstant(4.0f)});
auto scale_neg_z = b.makeCompositeConstant(vec4_float_type_,
{b.makeFloatConstant(-1.0f),
b.makeFloatConstant(-1.0f),
b.makeFloatConstant(2.0f),
b.makeFloatConstant(5.0f)});
auto ma_z = b.createCompositeExtract(t_s_ma_z, float_type_, 2);
auto ma_pos_z = b.createBinOp(spv::Op::OpFOrdGreaterThanEqual, bool_type_,
ma_z, b.makeFloatConstant(0.0f));
auto scale_z = b.createTriOp(spv::Op::OpSelect, vec4_float_type_,
ma_pos_z, scale_pos_z, scale_neg_z);
b.createStore(scale_z, scale);
}
if_y_else_z.makeEndIf();
}
if_x_else_yz.makeEndIf();
auto ret = b.createLoad(t_s_ma);
// Set face index scale to 1 because it's going to be multiplied.
ret = b.createCompositeInsert(b.makeFloatConstant(1.0f), ret,
vec4_float_type_, 3);
// Apply face-specific signs, face index and multiply major axis by 2.
ret = b.createBinOp(spv::Op::OpFMul, vec4_float_type_, ret,
b.createLoad(scale));
// Subtract 2 * MA from T and S so games can move them to 0...1.
auto abs_2ma = b.createCompositeExtract(ret, float_type_, 2);
abs_2ma = CreateGlslStd450InstructionCall(
spv::NoPrecision, float_type_, spv::GLSLstd450::kFAbs, {abs_2ma});
auto temp_t = b.createCompositeExtract(ret, float_type_, 0);
temp_t = b.createBinOp(spv::Op::OpFSub, float_type_, temp_t, abs_2ma);
ret = b.createCompositeInsert(temp_t, ret, vec4_float_type_, 0);
auto temp_s = b.createCompositeExtract(ret, float_type_, 1);
temp_s = b.createBinOp(spv::Op::OpFSub, float_type_, temp_s, abs_2ma);
ret = b.createCompositeInsert(temp_s, ret, vec4_float_type_, 1);
b.makeReturn(false, ret);
return function;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment