Last active
June 17, 2018 17:59
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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