Skip to content

Commit

Permalink
Merge branch 'Vita3K:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
backgamon authored Mar 23, 2024
2 parents bb68adc + e671af6 commit 80a5a80
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 95 deletions.
2 changes: 1 addition & 1 deletion vita3k/shader/include/shader/usse_utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ spv::Id make_vector_or_scalar_type(spv::Builder &b, spv::Id component, int size)

spv::Id unwrap_type(spv::Builder &b, spv::Id type);

spv::Id convert_to_float(spv::Builder &b, spv::Id opr, DataType type, bool normal);
spv::Id convert_to_float(spv::Builder &b, const SpirvUtilFunctions &utils, spv::Id opr, DataType type, bool normal);
spv::Id convert_to_int(spv::Builder &b, const SpirvUtilFunctions &utils, spv::Id opr, DataType type, bool normal);

spv::Id add_uvec2_uint(spv::Builder &b, spv::Id vec, spv::Id to_add);
Expand Down
2 changes: 1 addition & 1 deletion vita3k/shader/src/spirv_recompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,7 @@ static spv::Function *make_frag_finalize_function(spv::Builder &b, const SpirvSh
color = utils::load(b, parameters, utils, features, color_val_operand, 0xF, reg_off);

if (!is_float_data_type(color_val_operand.type))
color = utils::convert_to_float(b, color, color_val_operand.type, true);
color = utils::convert_to_float(b, utils, color, color_val_operand.type, true);

if (program.is_frag_color_used() && features.should_use_shader_interlock()) {
spv::Id signed_i32 = b.makeIntType(32);
Expand Down
24 changes: 12 additions & 12 deletions vita3k/shader/src/translator/alu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,10 +999,10 @@ bool USSETranslatorVisitor::sop2(
spv::Id src1_alpha = load(inst.opr.src1, 0b1000, src1_repeat_offset);
spv::Id src2_alpha = load(inst.opr.src2, 0b1000, src2_repeat_offset);

src1_color = utils::convert_to_float(m_b, src1_color, DataType::UINT8, true);
src2_color = utils::convert_to_float(m_b, src2_color, DataType::UINT8, true);
src1_alpha = utils::convert_to_float(m_b, src1_alpha, DataType::UINT8, true);
src2_alpha = utils::convert_to_float(m_b, src2_alpha, DataType::UINT8, true);
src1_color = utils::convert_to_float(m_b, m_util_funcs, src1_color, DataType::UINT8, true);
src2_color = utils::convert_to_float(m_b, m_util_funcs, src2_color, DataType::UINT8, true);
src1_alpha = utils::convert_to_float(m_b, m_util_funcs, src1_alpha, DataType::UINT8, true);
src2_alpha = utils::convert_to_float(m_b, m_util_funcs, src2_alpha, DataType::UINT8, true);

spv::Id src_color_type = m_b.getTypeId(src1_color);
spv::Id src_alpha_type = m_b.getTypeId(src1_alpha);
Expand Down Expand Up @@ -1191,8 +1191,8 @@ bool shader::usse::USSETranslatorVisitor::sop2m(Imm2 pred,
spv::Id src1 = load(inst.opr.src1, 0b1111, 0);
spv::Id src2 = load(inst.opr.src2, 0b1111, 0);

src1 = utils::convert_to_float(m_b, src1, DataType::UINT8, true);
src2 = utils::convert_to_float(m_b, src2, DataType::UINT8, true);
src1 = utils::convert_to_float(m_b, m_util_funcs, src1, DataType::UINT8, true);
src2 = utils::convert_to_float(m_b, m_util_funcs, src2, DataType::UINT8, true);

spv::Id src_type = m_b.getTypeId(src1);

Expand Down Expand Up @@ -1442,12 +1442,12 @@ bool shader::usse::USSETranslatorVisitor::sop3(Imm2 pred,
spv::Id src1_alpha = load(inst.opr.src1, 0b1000);
spv::Id src2_alpha = load(inst.opr.src2, 0b1000);

src0_color = utils::convert_to_float(m_b, src0_color, DataType::UINT8, true);
src1_color = utils::convert_to_float(m_b, src1_color, DataType::UINT8, true);
src2_color = utils::convert_to_float(m_b, src2_color, DataType::UINT8, true);
src0_alpha = utils::convert_to_float(m_b, src0_alpha, DataType::UINT8, true);
src1_alpha = utils::convert_to_float(m_b, src1_alpha, DataType::UINT8, true);
src2_alpha = utils::convert_to_float(m_b, src2_alpha, DataType::UINT8, true);
src0_color = utils::convert_to_float(m_b, m_util_funcs, src0_color, DataType::UINT8, true);
src1_color = utils::convert_to_float(m_b, m_util_funcs, src1_color, DataType::UINT8, true);
src2_color = utils::convert_to_float(m_b, m_util_funcs, src2_color, DataType::UINT8, true);
src0_alpha = utils::convert_to_float(m_b, m_util_funcs, src0_alpha, DataType::UINT8, true);
src1_alpha = utils::convert_to_float(m_b, m_util_funcs, src1_alpha, DataType::UINT8, true);
src2_alpha = utils::convert_to_float(m_b, m_util_funcs, src2_alpha, DataType::UINT8, true);

spv::Id src_color_type = m_b.getTypeId(src0_color);
spv::Id src_alpha_type = m_b.getTypeId(src0_alpha);
Expand Down
2 changes: 1 addition & 1 deletion vita3k/shader/src/translator/data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ bool USSETranslatorVisitor::vpck(

// source is int destination is float
if (is_float_data_type(inst.opr.dest.type) && !is_float_data_type(inst.opr.src1.type)) {
source = utils::convert_to_float(m_b, source, inst.opr.src1.type, scale);
source = utils::convert_to_float(m_b, m_util_funcs, source, inst.opr.src1.type, scale);
}

// source is float destination is int
Expand Down
121 changes: 41 additions & 80 deletions vita3k/shader/src/usse_utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static spv::Function *make_fx10_unpack_func(spv::Builder &b, const SpirvUtilFunc

spv::Id type_i32 = b.makeIntType(32);
spv::Id ivec3 = b.makeVectorType(type_i32, 3);
spv::Id uvec3 = b.makeVectorType(b.makeUintType(32), 3);
spv::Id type_f32 = b.makeFloatType(32);
spv::Id type_f32_v3 = b.makeVectorType(type_f32, 3);

Expand All @@ -181,25 +182,25 @@ static spv::Function *make_fx10_unpack_func(spv::Builder &b, const SpirvUtilFunc

spv::Id extracted = fx10_unpack_func->getParamId(0);

// Cast to uint first
// Cast to int first
extracted = b.createUnaryOp(spv::OpBitcast, type_i32, extracted);
spv::Id vec = b.createCompositeConstruct(ivec3, { extracted, extracted, extracted });

// vec = vec >> ivec3(0,10,20);
// vec = vec >> uvec3(0,10,20);
// note: note entirely sure, I really hope the layout is the same as in a 32-bit little-endian integer
const spv::Id shift_amount = b.createCompositeConstruct(ivec3, { b.makeIntConstant(0), b.makeIntConstant(10), b.makeIntConstant(20) });
const spv::Id shift_amount = b.makeCompositeConstant(uvec3, { b.makeUintConstant(0), b.makeUintConstant(10), b.makeUintConstant(20) });
vec = b.createBinOp(spv::OpShiftRightLogical, ivec3, vec, shift_amount);

// sign-extend the 10-bit integer:
// vec <<= 22 (logical)
// vec >>= 22 (arithmetic)
spv::Id extend_amount = b.makeIntConstant(22);
extend_amount = b.createCompositeConstruct(ivec3, { extend_amount, extend_amount, extend_amount });
spv::Id extend_amount = b.makeUintConstant(22);
extend_amount = b.makeCompositeConstant(uvec3, { extend_amount, extend_amount, extend_amount });
vec = b.createBinOp(spv::OpShiftLeftLogical, ivec3, vec, extend_amount);
vec = b.createBinOp(spv::OpShiftRightArithmetic, ivec3, vec, extend_amount);

// normalize it
vec = convert_to_float(b, vec, DataType::C10, true);
vec = convert_to_float(b, utils, vec, DataType::C10, true);

b.makeReturn(false, vec);
b.setBuildPoint(last_build_point);
Expand Down Expand Up @@ -261,39 +262,22 @@ static spv::Function *make_unpack_func(spv::Builder &b, const FeatureState &feat
decorations, &unpack_func_block);
spv::Id extracted = unpack_func->getParamId(0);

extracted = b.createUnaryOp(spv::OpBitcast, is_signed ? type_i32 : type_ui32, extracted);

std::vector<spv::Id> comps;
const spv::Id result_type = is_signed ? type_i32 : type_ui32;
extracted = b.createUnaryOp(spv::OpBitcast, result_type, extracted);

const auto comp_bits = 32 / comp_count;
spv::Id comp_bits_val = b.makeUintConstant(comp_bits);

std::vector<spv::Id> comps;
for (int i = 0; i < comp_count; ++i) {
spv::Id comp;

if (is_signed) {
comp = b.createTriOp(spv::OpBitFieldSExtract, type_i32, extracted, b.makeIntConstant(comp_bits * i), b.makeIntConstant(comp_bits));
} else {
comp = b.createTriOp(spv::OpBitFieldUExtract, type_ui32, extracted, b.makeIntConstant(comp_bits * i), b.makeIntConstant(comp_bits));
}
const spv::Op op = is_signed ? spv::OpBitFieldSExtract : spv::OpBitFieldUExtract;
spv::Id comp = b.createTriOp(op, result_type, extracted, b.makeUintConstant(comp_bits * i), comp_bits_val);

comps.push_back(comp);
}

auto output = b.createCompositeConstruct(output_type, comps);

if (is_signed) {
// Sign extended them. Thanks kd-11 for method.
spv::Id sign_check_vec_type = b.makeVectorType(b.makeBoolType(), comp_count);
std::vector<std::uint32_t> constants(comp_count, b.makeIntConstant(1 << (comp_bits - 1)));
std::vector<std::uint32_t> constant_bias(comp_count, b.makeIntConstant(1 << comp_bits));

spv::Id sign_check_vec = b.createBinOp(spv::OpSLessThan, sign_check_vec_type, output,
b.makeCompositeConstant(output_type, constants));
spv::Id bias_vec = b.makeCompositeConstant(output_type, constant_bias);

output = b.createTriOp(spv::OpSelect, output_type, sign_check_vec, output, b.createBinOp(spv::OpISub, output_type, output, bias_vec));
}

b.makeReturn(false, output);
b.setBuildPoint(last_build_point);

Expand Down Expand Up @@ -358,15 +342,10 @@ static spv::Function *make_pack_func(spv::Builder &b, const FeatureState &featur

const spv::Id comp_type = b.getContainedTypeId(input_type);

auto output = b.makeUintConstant(0);
auto output = is_signed ? b.makeIntConstant(0) : b.makeUintConstant(0);
for (int i = 0; i < comp_count; ++i) {
auto comp = b.createBinOp(spv::OpVectorExtractDynamic, comp_type, extracted, b.makeIntConstant(i));

if (is_signed) {
comp = b.createUnaryOp(spv::OpBitcast, type_ui32, comp);
}

output = b.createOp(spv::OpBitFieldInsert, type_ui32, { output, comp, b.makeIntConstant(comp_bits * i), b.makeIntConstant(comp_bits) });
spv::Id comp = b.createBinOp(spv::OpVectorExtractDynamic, comp_type, extracted, b.makeIntConstant(i));
output = b.createOp(spv::OpBitFieldInsert, comp_type, { output, comp, b.makeIntConstant(comp_bits * i), b.makeIntConstant(comp_bits) });
}

output = b.createUnaryOp(spv::OpBitcast, type_f32, output);
Expand Down Expand Up @@ -1442,27 +1421,26 @@ spv::Id unwrap_type(spv::Builder &b, spv::Id type) {
return type;
}

// will break in 32-bit host
static std::pair<float, float> get_int_normalize_range_constants(DataType type) {
static float get_int_normalize_range_constants(DataType type) {
switch (type) {
case DataType::UINT8:
return { 0.0f, 255.0f };
return 255.0f;
case DataType::INT8:
return { 128.0f, 127.0f };
return 127.0f;
case DataType::C10:
// signed 10-bit
return { 512.0f, 511.0f };
// signed 10-bit, with a range of [-2, 2]
return 255.0f;
case DataType::UINT16:
return { 0.0f, 65535.0f };
return 65535.0f;
case DataType::INT16:
return { 32768.0f, 32767.0f };
return 32767.0f;
case DataType::UINT32:
return { 0.0f, 4294967295.0f };
return 4294967295.0f;
case DataType::INT32:
return { 2147483648.0f, 2147483647.0f };
return 2147483647.0f;
default:
assert(false);
return { 0.0f, 0.0f };
return 0.0f;
}
}

Expand All @@ -1477,7 +1455,7 @@ static spv::Id create_constant_vector_or_scalar(spv::Builder &b, spv::Id constan
return b.createCompositeConstruct(b.makeVectorType(b.getTypeId(constant), comp_count), oprs);
}

spv::Id convert_to_float(spv::Builder &b, spv::Id opr, DataType type, bool normal) {
spv::Id convert_to_float(spv::Builder &b, const SpirvUtilFunctions &utils, spv::Id opr, DataType type, bool normal) {
const auto spv_type = unwrap_type(b, b.getTypeId(opr));
const auto comp_count = b.isVector(opr) ? b.getNumComponents(opr) : 1;
const auto target_type = b.isVector(opr) ? b.makeVectorType(b.makeFloatType(32), comp_count) : b.makeFloatType(32);
Expand All @@ -1492,22 +1470,15 @@ spv::Id convert_to_float(spv::Builder &b, spv::Id opr, DataType type, bool norma
}

if (normal) {
const auto constant_range = get_int_normalize_range_constants(type);
const auto normalizer = b.makeFloatConstant(constant_range.second);
const auto normalizer_vec = create_constant_vector_or_scalar(b, normalizer, comp_count);
const float normalizer = b.makeFloatConstant(get_int_normalize_range_constants(type));
const spv::Id normalizer_vec = create_constant_vector_or_scalar(b, normalizer, comp_count);

opr = b.createBinOp(spv::OpFDiv, target_type, opr, normalizer_vec);
if (is_sint) {
const auto zero_vec = create_constant_vector_or_scalar(b, b.makeFloatConstant(0.0f), comp_count);
const auto b_vec_type = make_vector_or_scalar_type(b, b.makeBoolType(), comp_count);

const auto normalizer_neg = b.makeFloatConstant(constant_range.first);
const auto normalize_vec_neg = create_constant_vector_or_scalar(b, normalizer_neg, comp_count);

opr = b.createTriOp(spv::OpSelect, target_type, b.createBinOp(spv::OpFOrdLessThan, b_vec_type, opr, zero_vec),
b.createBinOp(spv::OpFDiv, target_type, opr, normalize_vec_neg),
b.createBinOp(spv::OpFDiv, target_type, opr, normalizer_vec));
} else {
opr = b.createBinOp(spv::OpFDiv, target_type, opr, normalizer_vec);
// opr = max(-1.0f, opr) (or -2.0f for fx10)
float lower_bound = type == DataType::C10 ? -2.f : -1.f;
const spv::Id minus1 = create_constant_vector_or_scalar(b, b.makeFloatConstant(lower_bound), comp_count);
opr = b.createBuiltinCall(target_type, utils.std_builtins, GLSLstd450FMax, { opr, minus1 });
}
}
return opr;
Expand All @@ -1523,26 +1494,16 @@ spv::Id convert_to_int(spv::Builder &b, const SpirvUtilFunctions &utils, spv::Id
const auto target_type = b.isVector(opr) ? b.makeVectorType(target_comp_type, comp_count) : target_comp_type;

if (normal) {
const auto constant_range = get_int_normalize_range_constants(type);
const auto normalizer = b.makeFloatConstant(constant_range.second);
const float constant_range = get_int_normalize_range_constants(type);
const spv::Id normalizer = b.makeFloatConstant(constant_range);
const auto normalizer_vec = create_constant_vector_or_scalar(b, normalizer, comp_count);
const auto range_begin_vec = create_constant_vector_or_scalar(b, b.makeFloatConstant(is_uint ? 0.f : -1.f), comp_count);
const auto range_end_vec = create_constant_vector_or_scalar(b, b.makeFloatConstant(1.f), comp_count);
const bool is_fx10 = type == DataType::C10; // fx10 range is [-2,2]
const auto range_begin_vec = create_constant_vector_or_scalar(b, b.makeFloatConstant(is_uint ? 0.f : (is_fx10 ? -2.f : -1.f)), comp_count);
const auto range_end_vec = create_constant_vector_or_scalar(b, b.makeFloatConstant(is_fx10 ? 2.f : 1.f), comp_count);

// opr = round(clamp(opr * norm), -1, 1)
opr = b.createBuiltinCall(opr_type, utils.std_builtins, GLSLstd450FClamp, { opr, range_begin_vec, range_end_vec });
if (is_uint) {
opr = b.createBinOp(spv::OpFMul, opr_type, opr, normalizer_vec);
} else {
const auto zero_vec = create_constant_vector_or_scalar(b, b.makeFloatConstant(0.f), comp_count);
const auto b_vec_type = make_vector_or_scalar_type(b, b.makeBoolType(), comp_count);

const auto normalizer_neg = b.makeFloatConstant(constant_range.first);
const auto normalize_vec_neg = create_constant_vector_or_scalar(b, normalizer_neg, comp_count);

opr = b.createTriOp(spv::OpSelect, opr_type, b.createBinOp(spv::OpFOrdLessThan, b_vec_type, opr, zero_vec),
b.createBinOp(spv::OpFMul, opr_type, opr, normalize_vec_neg),
b.createBinOp(spv::OpFMul, opr_type, opr, normalizer_vec));
}
opr = b.createBinOp(spv::OpFMul, opr_type, opr, normalizer_vec);
opr = b.createBuiltinCall(opr_type, utils.std_builtins, GLSLstd450Round, { opr });
}

Expand Down

0 comments on commit 80a5a80

Please sign in to comment.