From eede38ff63ea795743dc206e12269ccfaf487096 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Tue, 18 Apr 2023 22:05:02 +0300 Subject: [PATCH 1/5] [SPIR-V] Remove more vec2-4 reserve calls --- src/xenia/gpu/spirv_shader_translator.cc | 9 --------- src/xenia/gpu/spirv_shader_translator_alu.cc | 1 - 2 files changed, 10 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 1a7ef2bac..1c5119906 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -1110,7 +1110,6 @@ spv::Id SpirvShaderTranslator::SpirvSmearScalarResultOrConstant( } int num_components = builder_->getNumTypeComponents(vector_type); id_vector_temp_util_.clear(); - id_vector_temp_util_.reserve(size_t(num_components)); for (int i = 0; i < num_components; ++i) { id_vector_temp_util_.push_back(scalar); } @@ -2386,7 +2385,6 @@ spv::Id SpirvShaderTranslator::LoadOperandStorage( case InstructionStorageSource::kConstantFloat: assert_true(uniform_float_constants_ != spv::NoResult); id_vector_temp_util_.clear(); - id_vector_temp_util_.reserve(2); // The first and the only structure member. id_vector_temp_util_.push_back(const_int_0_); // Array element. @@ -2448,7 +2446,6 @@ spv::Id SpirvShaderTranslator::GetUnmodifiedOperandComponents( static_cast(SwizzleSource::kX)); } uint_vector_temp_util_.clear(); - uint_vector_temp_util_.reserve(component_count); uint32_t components_remaining = components; uint32_t component_index; while (xe::bit_scan_forward(components_remaining, &component_index)) { @@ -2575,7 +2572,6 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result, if (result.is_clamped && non_constant_components) { // Apply the saturation modifier to the result. id_vector_temp_util_.clear(); - id_vector_temp_util_.reserve(3); id_vector_temp_util_.push_back(value); id_vector_temp_util_.push_back( const_float_vectors_0_[value_num_components - 1]); @@ -2660,7 +2656,6 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result, value_to_store = value; } else { uint_vector_temp_util_.clear(); - uint_vector_temp_util_.reserve(target_num_components); uint_vector_temp_util_.insert( uint_vector_temp_util_.cend(), result_swizzled_value_components, result_swizzled_value_components + target_num_components); @@ -2686,7 +2681,6 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result, if (target_num_components > 1) { // Constants only - vector target. id_vector_temp_util_.clear(); - id_vector_temp_util_.reserve(target_num_components); for (uint32_t i = 0; i < target_num_components; ++i) { id_vector_temp_util_.push_back( (constant_values & (1 << i)) ? const_float_1_ : const_float_0_); @@ -2718,7 +2712,6 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result, } else { // Mixed non-constants and constants - scalar source. id_vector_temp_util_.clear(); - id_vector_temp_util_.reserve(target_num_components); for (uint32_t i = 0; i < target_num_components; ++i) { if (constant_components & (1 << i)) { id_vector_temp_util_.push_back( @@ -2805,7 +2798,6 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result, id_vector_temp_util_), spv::NoPrecision)); id_vector_temp_util_.clear(); - id_vector_temp_util_.reserve(2); id_vector_temp_util_.push_back(point_vertex_diameter_min); id_vector_temp_util_.push_back(point_size); point_size = @@ -2822,7 +2814,6 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result, id_vector_temp_util_), spv::NoPrecision)); id_vector_temp_util_.clear(); - id_vector_temp_util_.reserve(2); id_vector_temp_util_.push_back(point_vertex_diameter_max); id_vector_temp_util_.push_back(point_size); point_size = diff --git a/src/xenia/gpu/spirv_shader_translator_alu.cc b/src/xenia/gpu/spirv_shader_translator_alu.cc index c017e351c..b82f0c427 100644 --- a/src/xenia/gpu/spirv_shader_translator_alu.cc +++ b/src/xenia/gpu/spirv_shader_translator_alu.cc @@ -29,7 +29,6 @@ spv::Id SpirvShaderTranslator::ZeroIfAnyOperandIsZero(spv::Id value, assert_true(builder_->getNumComponents(operand_0_abs) == num_components); assert_true(builder_->getNumComponents(operand_1_abs) == num_components); id_vector_temp_util_.clear(); - id_vector_temp_util_.reserve(2); id_vector_temp_util_.push_back(operand_0_abs); id_vector_temp_util_.push_back(operand_1_abs); return builder_->createTriOp( From 64d2a80f79a38b8f0aeb1d3a7ee64b76aca9a1f1 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Wed, 19 Apr 2023 10:35:09 +0300 Subject: [PATCH 2/5] [SPIR-V] Cleanup ALU emulation conditionals --- src/xenia/gpu/spirv_shader_translator.h | 2 + src/xenia/gpu/spirv_shader_translator_alu.cc | 353 +++++++++---------- 2 files changed, 163 insertions(+), 192 deletions(-) diff --git a/src/xenia/gpu/spirv_shader_translator.h b/src/xenia/gpu/spirv_shader_translator.h index d453aa329..c09cc831e 100644 --- a/src/xenia/gpu/spirv_shader_translator.h +++ b/src/xenia/gpu/spirv_shader_translator.h @@ -571,6 +571,8 @@ class SpirvShaderTranslator : public ShaderTranslator { // must be called with absolute values of operands - use GetAbsoluteOperand! spv::Id ZeroIfAnyOperandIsZero(spv::Id value, spv::Id operand_0_abs, spv::Id operand_1_abs); + // Conditionally discard the current fragment. Changes the build point. + void KillPixel(spv::Id condition); // Return type is a xe::bit_count(result.GetUsedResultComponents())-component // float vector or a single float, depending on whether it's a reduction // instruction (check getTypeId of the result), or returns spv::NoResult if diff --git a/src/xenia/gpu/spirv_shader_translator_alu.cc b/src/xenia/gpu/spirv_shader_translator_alu.cc index b82f0c427..db1019952 100644 --- a/src/xenia/gpu/spirv_shader_translator_alu.cc +++ b/src/xenia/gpu/spirv_shader_translator_alu.cc @@ -42,6 +42,33 @@ spv::Id SpirvShaderTranslator::ZeroIfAnyOperandIsZero(spv::Id value, const_float_vectors_0_[num_components - 1], value); } +void SpirvShaderTranslator::KillPixel(spv::Id condition) { + // Same calls as in spv::Builder::If. + spv::Function& function = builder_->getBuildPoint()->getParent(); + spv::Block* kill_block = new spv::Block(builder_->getUniqueId(), function); + spv::Block* merge_block = new spv::Block(builder_->getUniqueId(), function); + spv::Block& header_block = *builder_->getBuildPoint(); + + function.addBlock(kill_block); + builder_->setBuildPoint(kill_block); + // Kill without influencing the control flow in the translated shader. + if (var_main_kill_pixel_ != spv::NoResult) { + builder_->createStore(builder_->makeBoolConstant(true), + var_main_kill_pixel_); + } + if (features_.demote_to_helper_invocation) { + builder_->createNoResultOp(spv::OpDemoteToHelperInvocationEXT); + } + builder_->createBranch(merge_block); + + builder_->setBuildPoint(&header_block); + SpirvCreateSelectionMerge(merge_block->getId()); + builder_->createConditionalBranch(condition, kill_block, merge_block); + + function.addBlock(merge_block); + builder_->setBuildPoint(merge_block); +} + void SpirvShaderTranslator::ProcessAluInstruction( const ParsedAluInstruction& instr) { if (instr.IsNop()) { @@ -560,133 +587,122 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( builder_->addDecoration(operand_neg[2], spv::DecorationNoContraction); } + spv::Id ma_z_result[4] = {}, ma_yx_result[4] = {}; + // Check if the major axis is Z (abs(z) >= abs(x) && abs(z) >= abs(y)). - // Selection merge must be the penultimate instruction in the block, check - // the condition before it. - spv::Id ma_z_condition = builder_->createBinOp( - spv::OpLogicalAnd, type_bool_, - builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, - operand_abs[2], operand_abs[0]), - builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, - operand_abs[2], operand_abs[1])); - spv::Function& function = builder_->getBuildPoint()->getParent(); - spv::Block& ma_z_block = builder_->makeNewBlock(); - spv::Block& ma_yx_block = builder_->makeNewBlock(); - spv::Block* ma_merge_block = - new spv::Block(builder_->getUniqueId(), function); - SpirvCreateSelectionMerge(ma_merge_block->getId()); - builder_->createConditionalBranch(ma_z_condition, &ma_z_block, - &ma_yx_block); - - builder_->setBuildPoint(&ma_z_block); - // The major axis is Z. - spv::Id ma_z_result[4] = {}; - // tc = -y - ma_z_result[0] = operand_neg[1]; - // ma/2 = z - ma_z_result[2] = operand[2]; - if (used_result_components & 0b1010) { - spv::Id z_is_neg = builder_->createBinOp( - spv::OpFOrdLessThan, type_bool_, operand[2], const_float_0_); - if (used_result_components & 0b0010) { - // sc = z < 0.0 ? -x : x - ma_z_result[1] = builder_->createTriOp( - spv::OpSelect, type_float_, z_is_neg, operand_neg[0], operand[0]); - } - if (used_result_components & 0b1000) { - // id = z < 0.0 ? 5.0 : 4.0 - ma_z_result[3] = - builder_->createTriOp(spv::OpSelect, type_float_, z_is_neg, - builder_->makeFloatConstant(5.0f), - builder_->makeFloatConstant(4.0f)); + spv::Builder::If ma_z_if( + builder_->createBinOp( + spv::OpLogicalAnd, type_bool_, + builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, + operand_abs[2], operand_abs[0]), + builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, + operand_abs[2], operand_abs[1])), + spv::SelectionControlMaskNone, *builder_); + { + // The major axis is Z. + // tc = -y + ma_z_result[0] = operand_neg[1]; + // ma/2 = z + ma_z_result[2] = operand[2]; + if (used_result_components & 0b1010) { + spv::Id z_is_neg = builder_->createBinOp( + spv::OpFOrdLessThan, type_bool_, operand[2], const_float_0_); + if (used_result_components & 0b0010) { + // sc = z < 0.0 ? -x : x + ma_z_result[1] = + builder_->createTriOp(spv::OpSelect, type_float_, z_is_neg, + operand_neg[0], operand[0]); + } + if (used_result_components & 0b1000) { + // id = z < 0.0 ? 5.0 : 4.0 + ma_z_result[3] = + builder_->createTriOp(spv::OpSelect, type_float_, z_is_neg, + builder_->makeFloatConstant(5.0f), + builder_->makeFloatConstant(4.0f)); + } } } - builder_->createBranch(ma_merge_block); + spv::Block& ma_z_end_block = *builder_->getBuildPoint(); + ma_z_if.makeBeginElse(); + { + spv::Id ma_y_result[4] = {}, ma_x_result[4] = {}; - builder_->setBuildPoint(&ma_yx_block); - // The major axis is not Z - create an inner conditional to check if the - // major axis is Y (abs(y) >= abs(x)). - // Selection merge must be the penultimate instruction in the block, check - // the condition before it. - spv::Id ma_y_condition = - builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, - operand_abs[1], operand_abs[0]); - spv::Block& ma_y_block = builder_->makeNewBlock(); - spv::Block& ma_x_block = builder_->makeNewBlock(); - spv::Block& ma_yx_merge_block = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(ma_yx_merge_block.getId()); - builder_->createConditionalBranch(ma_y_condition, &ma_y_block, - &ma_x_block); + // The major axis is not Z - create an inner conditional to check if the + // major axis is Y (abs(y) >= abs(x)). + spv::Builder::If ma_y_if( + builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, + operand_abs[1], operand_abs[0]), + spv::SelectionControlMaskNone, *builder_); + { + // The major axis is Y. + // sc = x + ma_y_result[1] = operand[0]; + // ma/2 = y + ma_y_result[2] = operand[1]; + if (used_result_components & 0b1001) { + spv::Id y_is_neg = builder_->createBinOp( + spv::OpFOrdLessThan, type_bool_, operand[1], const_float_0_); + if (used_result_components & 0b0001) { + // tc = y < 0.0 ? -z : z + ma_y_result[0] = + builder_->createTriOp(spv::OpSelect, type_float_, y_is_neg, + operand_neg[2], operand[2]); + // id = y < 0.0 ? 3.0 : 2.0 + ma_y_result[3] = + builder_->createTriOp(spv::OpSelect, type_float_, y_is_neg, + builder_->makeFloatConstant(3.0f), + builder_->makeFloatConstant(2.0f)); + } + } + } + spv::Block& ma_y_end_block = *builder_->getBuildPoint(); + ma_y_if.makeBeginElse(); + { + // The major axis is X. + // tc = -y + ma_x_result[0] = operand_neg[1]; + // ma/2 = x + ma_x_result[2] = operand[0]; + if (used_result_components & 0b1010) { + spv::Id x_is_neg = builder_->createBinOp( + spv::OpFOrdLessThan, type_bool_, operand[0], const_float_0_); + if (used_result_components & 0b0010) { + // sc = x < 0.0 ? z : -z + ma_x_result[1] = + builder_->createTriOp(spv::OpSelect, type_float_, x_is_neg, + operand[2], operand_neg[2]); + } + if (used_result_components & 0b1000) { + // id = x < 0.0 ? 1.0 : 0.0 + ma_x_result[3] = + builder_->createTriOp(spv::OpSelect, type_float_, x_is_neg, + const_float_1_, const_float_0_); + } + } + } + spv::Block& ma_x_end_block = *builder_->getBuildPoint(); + ma_y_if.makeEndIf(); - builder_->setBuildPoint(&ma_y_block); - // The major axis is Y. - spv::Id ma_y_result[4] = {}; - // sc = x - ma_y_result[1] = operand[0]; - // ma/2 = y - ma_y_result[2] = operand[1]; - if (used_result_components & 0b1001) { - spv::Id y_is_neg = builder_->createBinOp( - spv::OpFOrdLessThan, type_bool_, operand[1], const_float_0_); - if (used_result_components & 0b0001) { - // tc = y < 0.0 ? -z : z - ma_y_result[0] = builder_->createTriOp( - spv::OpSelect, type_float_, y_is_neg, operand_neg[2], operand[2]); - // id = y < 0.0 ? 3.0 : 2.0 - ma_y_result[3] = - builder_->createTriOp(spv::OpSelect, type_float_, y_is_neg, - builder_->makeFloatConstant(3.0f), - builder_->makeFloatConstant(2.0f)); + // The major axis is Y or X - choose the options of the result from Y + // and X. + for (uint32_t i = 0; i < 4; ++i) { + if (!(used_result_components & (1 << i))) { + continue; + } + std::unique_ptr phi_op = + std::make_unique(builder_->getUniqueId(), + type_float_, spv::OpPhi); + phi_op->addIdOperand(ma_y_result[i]); + phi_op->addIdOperand(ma_y_end_block.getId()); + phi_op->addIdOperand(ma_x_result[i]); + phi_op->addIdOperand(ma_x_end_block.getId()); + ma_yx_result[i] = phi_op->getResultId(); + builder_->getBuildPoint()->addInstruction(std::move(phi_op)); } } - builder_->createBranch(&ma_yx_merge_block); + spv::Block& ma_yx_end_block = *builder_->getBuildPoint(); + ma_z_if.makeEndIf(); - builder_->setBuildPoint(&ma_x_block); - // The major axis is X. - spv::Id ma_x_result[4] = {}; - // tc = -y - ma_x_result[0] = operand_neg[1]; - // ma/2 = x - ma_x_result[2] = operand[0]; - if (used_result_components & 0b1010) { - spv::Id x_is_neg = builder_->createBinOp( - spv::OpFOrdLessThan, type_bool_, operand[0], const_float_0_); - if (used_result_components & 0b0010) { - // sc = x < 0.0 ? z : -z - ma_x_result[1] = builder_->createTriOp( - spv::OpSelect, type_float_, x_is_neg, operand[2], operand_neg[2]); - } - if (used_result_components & 0b1000) { - // id = x < 0.0 ? 1.0 : 0.0 - ma_x_result[3] = - builder_->createTriOp(spv::OpSelect, type_float_, x_is_neg, - const_float_1_, const_float_0_); - } - } - builder_->createBranch(&ma_yx_merge_block); - - builder_->setBuildPoint(&ma_yx_merge_block); - // The major axis is Y or X - choose the options of the result from Y and - // X. - spv::Id ma_yx_result[4] = {}; - for (uint32_t i = 0; i < 4; ++i) { - if (!(used_result_components & (1 << i))) { - continue; - } - std::unique_ptr phi_op = - std::make_unique(builder_->getUniqueId(), - type_float_, spv::OpPhi); - phi_op->addIdOperand(ma_y_result[i]); - phi_op->addIdOperand(ma_y_block.getId()); - phi_op->addIdOperand(ma_x_result[i]); - phi_op->addIdOperand(ma_x_block.getId()); - ma_yx_result[i] = phi_op->getResultId(); - builder_->getBuildPoint()->addInstruction(std::move(phi_op)); - } - builder_->createBranch(ma_merge_block); - - function.addBlock(ma_merge_block); - builder_->setBuildPoint(ma_merge_block); // Choose the result options from Z and YX cases. id_vector_temp_.clear(); for (uint32_t i = 0; i < 4; ++i) { @@ -697,9 +713,9 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( std::make_unique(builder_->getUniqueId(), type_float_, spv::OpPhi); phi_op->addIdOperand(ma_z_result[i]); - phi_op->addIdOperand(ma_z_block.getId()); + phi_op->addIdOperand(ma_z_end_block.getId()); phi_op->addIdOperand(ma_yx_result[i]); - phi_op->addIdOperand(ma_yx_merge_block.getId()); + phi_op->addIdOperand(ma_yx_end_block.getId()); id_vector_temp_.push_back(phi_op->getResultId()); builder_->getBuildPoint()->addInstruction(std::move(phi_op)); } @@ -815,31 +831,14 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( case ucode::AluVectorOpcode::kKillGt: case ucode::AluVectorOpcode::kKillGe: case ucode::AluVectorOpcode::kKillNe: { - // Selection merge must be the penultimate instruction in the block, check - // the condition before it. - spv::Id condition = builder_->createUnaryOp( + KillPixel(builder_->createUnaryOp( spv::OpAny, type_bool_, builder_->createBinOp( spv::Op(kOps[size_t(instr.vector_opcode)]), type_bool4_, GetOperandComponents(operand_storage[0], instr.vector_operands[0], 0b1111), GetOperandComponents(operand_storage[1], instr.vector_operands[1], - 0b1111))); - spv::Block& kill_block = builder_->makeNewBlock(); - spv::Block& merge_block = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(merge_block.getId()); - builder_->createConditionalBranch(condition, &kill_block, &merge_block); - builder_->setBuildPoint(&kill_block); - // Kill without influencing the control flow in the translated shader. - if (var_main_kill_pixel_ != spv::NoResult) { - builder_->createStore(builder_->makeBoolConstant(true), - var_main_kill_pixel_); - } - if (features_.demote_to_helper_invocation) { - builder_->createNoResultOp(spv::OpDemoteToHelperInvocationEXT); - } - builder_->createBranch(&merge_block); - builder_->setBuildPoint(&merge_block); + 0b1111)))); return const_float_0_; } @@ -1091,47 +1090,34 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( spv::OpLogicalAnd, type_bool_, condition, builder_->createBinOp(spv::OpFOrdGreaterThan, type_bool_, b, const_float_0_)); - spv::Block& multiply_block = builder_->makeNewBlock(); - spv::Block& merge_block = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(merge_block.getId()); + spv::Block& pre_multiply_if_block = *builder_->getBuildPoint(); + spv::Id product; + spv::Builder::If multiply_if(condition, spv::SelectionControlMaskNone, + *builder_); { - std::unique_ptr branch_conditional_op = - std::make_unique(spv::OpBranchConditional); - branch_conditional_op->addIdOperand(condition); - branch_conditional_op->addIdOperand(multiply_block.getId()); - branch_conditional_op->addIdOperand(merge_block.getId()); - // More likely to multiply that to return -FLT_MAX. - branch_conditional_op->addImmediateOperand(2); - branch_conditional_op->addImmediateOperand(1); - builder_->getBuildPoint()->addInstruction( - std::move(branch_conditional_op)); + // Multiplication case. + spv::Id a = instr.scalar_operands[0].GetComponent(0) != + instr.scalar_operands[0].GetComponent(1) + ? GetOperandComponents(operand_storage[0], + instr.scalar_operands[0], 0b0001) + : b; + product = builder_->createBinOp(spv::OpFMul, type_float_, a, ps); + builder_->addDecoration(product, spv::DecorationNoContraction); + // Shader Model 3: +0 or denormal * anything = +-0. + product = ZeroIfAnyOperandIsZero( + product, GetAbsoluteOperand(a, instr.scalar_operands[0]), ps_abs); } - spv::Block& head_block = *builder_->getBuildPoint(); - multiply_block.addPredecessor(&head_block); - merge_block.addPredecessor(&head_block); - // Multiplication case. - builder_->setBuildPoint(&multiply_block); - spv::Id a = instr.scalar_operands[0].GetComponent(0) != - instr.scalar_operands[0].GetComponent(1) - ? GetOperandComponents(operand_storage[0], - instr.scalar_operands[0], 0b0001) - : b; - spv::Id product = builder_->createBinOp(spv::OpFMul, type_float_, a, ps); - builder_->addDecoration(product, spv::DecorationNoContraction); - // Shader Model 3: +0 or denormal * anything = +-0. - product = ZeroIfAnyOperandIsZero( - product, GetAbsoluteOperand(a, instr.scalar_operands[0]), ps_abs); - builder_->createBranch(&merge_block); - // Merge case - choose between the product and -FLT_MAX. - builder_->setBuildPoint(&merge_block); + spv::Block& multiply_end_block = *builder_->getBuildPoint(); + multiply_if.makeEndIf(); + // Merge - choose between the product and -FLT_MAX. { std::unique_ptr phi_op = std::make_unique(builder_->getUniqueId(), type_float_, spv::OpPhi); phi_op->addIdOperand(product); - phi_op->addIdOperand(multiply_block.getId()); + phi_op->addIdOperand(multiply_end_block.getId()); phi_op->addIdOperand(const_float_max_neg); - phi_op->addIdOperand(head_block.getId()); + phi_op->addIdOperand(pre_multiply_if_block.getId()); spv::Id phi_result = phi_op->getResultId(); builder_->getBuildPoint()->addInstruction(std::move(phi_op)); return phi_result; @@ -1375,30 +1361,13 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( case ucode::AluScalarOpcode::kKillsGe: case ucode::AluScalarOpcode::kKillsNe: case ucode::AluScalarOpcode::kKillsOne: { - // Selection merge must be the penultimate instruction in the block, check - // the condition before it. - spv::Id condition = builder_->createBinOp( + KillPixel(builder_->createBinOp( spv::Op(kOps[size_t(instr.scalar_opcode)]), type_bool_, GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), instr.scalar_opcode == ucode::AluScalarOpcode::kKillsOne ? const_float_1_ - : const_float_0_); - spv::Block& kill_block = builder_->makeNewBlock(); - spv::Block& merge_block = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(merge_block.getId()); - builder_->createConditionalBranch(condition, &kill_block, &merge_block); - builder_->setBuildPoint(&kill_block); - // Kill without influencing the control flow in the translated shader. - if (var_main_kill_pixel_ != spv::NoResult) { - builder_->createStore(builder_->makeBoolConstant(true), - var_main_kill_pixel_); - } - if (features_.demote_to_helper_invocation) { - builder_->createNoResultOp(spv::OpDemoteToHelperInvocationEXT); - } - builder_->createBranch(&merge_block); - builder_->setBuildPoint(&merge_block); + : const_float_0_)); return const_float_0_; } From 78f1d55a364580551e6c614a21a7ecde8a9b4f49 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Wed, 19 Apr 2023 11:11:28 +0300 Subject: [PATCH 3/5] [SPIR-V] Use Builder createSelectionMerge directly --- src/xenia/gpu/spirv_builder.h | 33 ++++ src/xenia/gpu/spirv_shader_translator.cc | 38 +++-- src/xenia/gpu/spirv_shader_translator.h | 23 +-- src/xenia/gpu/spirv_shader_translator_alu.cc | 2 +- .../gpu/spirv_shader_translator_fetch.cc | 39 ++--- src/xenia/gpu/spirv_shader_translator_rb.cc | 158 ++++++++++-------- src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc | 35 +--- .../gpu/vulkan/vulkan_render_target_cache.cc | 29 +--- 8 files changed, 182 insertions(+), 175 deletions(-) create mode 100644 src/xenia/gpu/spirv_builder.h diff --git a/src/xenia/gpu/spirv_builder.h b/src/xenia/gpu/spirv_builder.h new file mode 100644 index 000000000..6692ebb09 --- /dev/null +++ b/src/xenia/gpu/spirv_builder.h @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2023 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_GPU_SPIRV_BUILDER_H_ +#define XENIA_GPU_SPIRV_BUILDER_H_ + +#include "third_party/glslang/SPIRV/SpvBuilder.h" + +namespace xe { +namespace gpu { + +// SpvBuilder with extra helpers. + +class SpirvBuilder : public spv::Builder { + public: + SpirvBuilder(unsigned int spv_version, unsigned int user_number, + spv::SpvBuildLogger* logger) + : spv::Builder(spv_version, user_number, logger) {} + + // Make public rather than protected. + using spv::Builder::createSelectionMerge; +}; + +} // namespace gpu +} // namespace xe + +#endif // XENIA_GPU_SPIRV_BUILDER_H_ diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 1c5119906..e670bc32c 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -161,7 +161,7 @@ uint32_t SpirvShaderTranslator::GetModificationRegisterCount() const { void SpirvShaderTranslator::StartTranslation() { // TODO(Triang3l): Logger. - builder_ = std::make_unique( + builder_ = std::make_unique( features_.spirv_version, (kSpirvMagicToolId << 16) | 1, nullptr); builder_->addCapability(IsSpirvTessEvalShader() ? spv::CapabilityTessellation @@ -591,8 +591,8 @@ void SpirvShaderTranslator::StartTranslation() { main_switch_header_ = builder_->getBuildPoint(); main_switch_merge_ = new spv::Block(builder_->getUniqueId(), *function_main_); - SpirvCreateSelectionMerge(main_switch_merge_->getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(main_switch_merge_, + spv::SelectionControlDontFlattenMask); main_switch_op_ = std::make_unique(spv::OpSwitch); main_switch_op_->addIdOperand(main_loop_pc_current); main_switch_op_->addIdOperand(main_switch_merge_->getId()); @@ -914,7 +914,7 @@ void SpirvShaderTranslator::ProcessLoopStartInstruction( spv::OpIEqual, type_bool_, loop_count_new, const_uint_0_); spv::Block& skip_block = builder_->makeNewBlock(); spv::Block& body_block = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(body_block.getId()); + builder_->createSelectionMerge(&body_block, spv::SelectionControlMaskNone); { std::unique_ptr branch_conditional_op = std::make_unique(spv::OpBranchConditional); @@ -976,7 +976,7 @@ void SpirvShaderTranslator::ProcessLoopEndInstruction( spv::Block& body_block = *builder_->getBuildPoint(); spv::Block& continue_block = builder_->makeNewBlock(); spv::Block& break_block = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(break_block.getId()); + builder_->createSelectionMerge(&break_block, spv::SelectionControlMaskNone); { std::unique_ptr branch_conditional_op = std::make_unique(spv::OpBranchConditional); @@ -1293,8 +1293,8 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderInMain() { spv::Block& block_load_vertex_index_pre = *builder_->getBuildPoint(); spv::Block& block_load_vertex_index_start = builder_->makeNewBlock(); spv::Block& block_load_vertex_index_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_load_vertex_index_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_load_vertex_index_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(load_vertex_index, &block_load_vertex_index_start, &block_load_vertex_index_merge); @@ -1389,8 +1389,8 @@ void SpirvShaderTranslator::StartVertexOrTessEvalShaderInMain() { spv::Block& block_load_vertex_index_pre = *builder_->getBuildPoint(); spv::Block& block_load_vertex_index_start = builder_->makeNewBlock(); spv::Block& block_load_vertex_index_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_load_vertex_index_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_load_vertex_index_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(load_vertex_index, &block_load_vertex_index_start, &block_load_vertex_index_merge); @@ -1992,8 +1992,8 @@ void SpirvShaderTranslator::StartFragmentShaderInMain() { builder_->makeNewBlock(); main_fsi_early_depth_stencil_execute_quad_merge_ = &builder_->makeNewBlock(); - SpirvCreateSelectionMerge( - main_fsi_early_depth_stencil_execute_quad_merge_->getId(), + builder_->createSelectionMerge( + main_fsi_early_depth_stencil_execute_quad_merge_, spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch( quad_needs_execution, &main_fsi_early_depth_stencil_execute_quad, @@ -2244,7 +2244,8 @@ void SpirvShaderTranslator::UpdateExecConditionals( cf_exec_condition_ = condition; cf_exec_conditional_merge_ = new spv::Block( builder_->getUniqueId(), builder_->getBuildPoint()->getParent()); - SpirvCreateSelectionMerge(cf_exec_conditional_merge_->getId()); + builder_->createSelectionMerge(cf_exec_conditional_merge_, + spv::SelectionControlDontFlattenMask); spv::Block& inner_block = builder_->makeNewBlock(); builder_->createConditionalBranch( condition_id, condition ? &inner_block : cf_exec_conditional_merge_, @@ -2284,7 +2285,8 @@ void SpirvShaderTranslator::UpdateInstructionPredication(bool predicated, spv::Block& predicated_block = builder_->makeNewBlock(); cf_instruction_predicate_merge_ = new spv::Block( builder_->getUniqueId(), builder_->getBuildPoint()->getParent()); - SpirvCreateSelectionMerge(cf_instruction_predicate_merge_->getId()); + builder_->createSelectionMerge(cf_instruction_predicate_merge_, + spv::SelectionControlMaskNone); builder_->createConditionalBranch( predicate_id, condition ? &predicated_block : cf_instruction_predicate_merge_, @@ -2870,7 +2872,8 @@ spv::Id SpirvShaderTranslator::EndianSwap32Uint(spv::Id value, spv::Id endian) { assert_false(block_pre_8in16.isTerminated()); spv::Block& block_8in16 = builder_->makeNewBlock(); spv::Block& block_8in16_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_8in16_merge.getId()); + builder_->createSelectionMerge(&block_8in16_merge, + spv::SelectionControlMaskNone); builder_->createConditionalBranch(is_8in16_or_8in32, &block_8in16, &block_8in16_merge); builder_->setBuildPoint(&block_8in16); @@ -2910,7 +2913,8 @@ spv::Id SpirvShaderTranslator::EndianSwap32Uint(spv::Id value, spv::Id endian) { spv::Block& block_pre_16in32 = *builder_->getBuildPoint(); spv::Block& block_16in32 = builder_->makeNewBlock(); spv::Block& block_16in32_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_16in32_merge.getId()); + builder_->createSelectionMerge(&block_16in32_merge, + spv::SelectionControlMaskNone); builder_->createConditionalBranch(is_8in32_or_16in32, &block_16in32, &block_16in32_merge); builder_->setBuildPoint(&block_16in32); @@ -2982,8 +2986,8 @@ spv::Id SpirvShaderTranslator::LoadUint32FromSharedMemory( std::unique_ptr value_phi_op = std::make_unique(value_phi_result, type_uint_, spv::OpPhi); - SpirvCreateSelectionMerge(switch_merge_block.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&switch_merge_block, + spv::SelectionControlDontFlattenMask); { std::unique_ptr switch_op = std::make_unique(spv::OpSwitch); diff --git a/src/xenia/gpu/spirv_shader_translator.h b/src/xenia/gpu/spirv_shader_translator.h index c09cc831e..b7da0678d 100644 --- a/src/xenia/gpu/spirv_shader_translator.h +++ b/src/xenia/gpu/spirv_shader_translator.h @@ -17,8 +17,8 @@ #include #include -#include "third_party/glslang/SPIRV/SpvBuilder.h" #include "xenia/gpu/shader_translator.h" +#include "xenia/gpu/spirv_builder.h" #include "xenia/gpu/xenos.h" #include "xenia/ui/vulkan/vulkan_provider.h" @@ -374,30 +374,30 @@ class SpirvShaderTranslator : public ShaderTranslator { // Converts the color value externally clamped to [0, 31.875] to 7e3 floating // point, with zeros in bits 10:31, rounding to the nearest even. - static spv::Id PreClampedFloat32To7e3(spv::Builder& builder, + static spv::Id PreClampedFloat32To7e3(SpirvBuilder& builder, spv::Id f32_scalar, spv::Id ext_inst_glsl_std_450); // Same as PreClampedFloat32To7e3, but clamps the input to [0, 31.875]. - static spv::Id UnclampedFloat32To7e3(spv::Builder& builder, + static spv::Id UnclampedFloat32To7e3(SpirvBuilder& builder, spv::Id f32_scalar, spv::Id ext_inst_glsl_std_450); // Converts the 7e3 number in bits [f10_shift, f10_shift + 10) to a 32-bit // float. - static spv::Id Float7e3To32(spv::Builder& builder, spv::Id f10_uint_scalar, + static spv::Id Float7e3To32(SpirvBuilder& builder, spv::Id f10_uint_scalar, uint32_t f10_shift, bool result_as_uint, spv::Id ext_inst_glsl_std_450); // Converts the depth value externally clamped to the representable [0, 2) // range to 20e4 floating point, with zeros in bits 24:31, rounding to the // nearest even or towards zero. If remap_from_0_to_0_5 is true, it's assumed // that 0...1 is pre-remapped to 0...0.5 in the input. - static spv::Id PreClampedDepthTo20e4(spv::Builder& builder, + static spv::Id PreClampedDepthTo20e4(SpirvBuilder& builder, spv::Id f32_scalar, bool round_to_nearest_even, bool remap_from_0_to_0_5, spv::Id ext_inst_glsl_std_450); // Converts the 20e4 number in bits [f24_shift, f24_shift + 10) to a 32-bit // float. - static spv::Id Depth20e4To32(spv::Builder& builder, spv::Id f24_uint_scalar, + static spv::Id Depth20e4To32(SpirvBuilder& builder, spv::Id f24_uint_scalar, uint32_t f24_shift, bool remap_to_0_to_0_5, bool result_as_uint, spv::Id ext_inst_glsl_std_450); @@ -451,15 +451,6 @@ class SpirvShaderTranslator : public ShaderTranslator { // Builder helpers. spv::Id SpirvSmearScalarResultOrConstant(spv::Id scalar, spv::Id vector_type); - void SpirvCreateSelectionMerge( - spv::Id merge_block_id, spv::SelectionControlMask selection_control_mask = - spv::SelectionControlMaskNone) { - std::unique_ptr selection_merge_op = - std::make_unique(spv::OpSelectionMerge); - selection_merge_op->addIdOperand(merge_block_id); - selection_merge_op->addImmediateOperand(selection_control_mask); - builder_->getBuildPoint()->addInstruction(std::move(selection_merge_op)); - } Modification GetSpirvShaderModification() const { return Modification(current_translation().modification()); @@ -689,7 +680,7 @@ class SpirvShaderTranslator : public ShaderTranslator { // and stencil testing with fragment shader interlock. bool is_depth_only_fragment_shader_ = false; - std::unique_ptr builder_; + std::unique_ptr builder_; std::vector id_vector_temp_; // For helper functions like operand loading, so they don't conflict with diff --git a/src/xenia/gpu/spirv_shader_translator_alu.cc b/src/xenia/gpu/spirv_shader_translator_alu.cc index db1019952..76410aa71 100644 --- a/src/xenia/gpu/spirv_shader_translator_alu.cc +++ b/src/xenia/gpu/spirv_shader_translator_alu.cc @@ -62,7 +62,7 @@ void SpirvShaderTranslator::KillPixel(spv::Id condition) { builder_->createBranch(merge_block); builder_->setBuildPoint(&header_block); - SpirvCreateSelectionMerge(merge_block->getId()); + builder_->createSelectionMerge(merge_block, spv::SelectionControlMaskNone); builder_->createConditionalBranch(condition, kill_block, merge_block); function.addBlock(merge_block); diff --git a/src/xenia/gpu/spirv_shader_translator_fetch.cc b/src/xenia/gpu/spirv_shader_translator_fetch.cc index 70785b795..45f7477ec 100644 --- a/src/xenia/gpu/spirv_shader_translator_fetch.cc +++ b/src/xenia/gpu/spirv_shader_translator_fetch.cc @@ -1178,8 +1178,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::Block& block_dimension_head = *builder_->getBuildPoint(); spv::Block& block_dimension_merge = builder_->makeNewBlock(); spv::Block& block_dimension_3d = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_dimension_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_dimension_merge, + spv::SelectionControlDontFlattenMask); assert_true(data_is_3d != spv::NoResult); builder_->createConditionalBranch(data_is_3d, &block_dimension_3d, &block_dimension_merge); @@ -1209,8 +1209,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::Block* block_dimension_3d = z_offset != spv::NoResult ? &builder_->makeNewBlock() : nullptr; spv::Block& block_dimension_stacked = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_dimension_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_dimension_merge, + spv::SelectionControlDontFlattenMask); assert_true(data_is_3d != spv::NoResult); builder_->createConditionalBranch( data_is_3d, @@ -1318,7 +1318,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::Block& block_ma_y = builder_->makeNewBlock(); spv::Block& block_ma_z = builder_->makeNewBlock(); spv::Block& block_ma_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_ma_merge.getId()); + builder_->createSelectionMerge(&block_ma_merge, + spv::SelectionControlMaskNone); { std::unique_ptr ma_switch_op = std::make_unique(spv::OpSwitch); @@ -1441,8 +1442,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::Block& block_dimension_3d_start = builder_->makeNewBlock(); spv::Block& block_dimension_stacked_start = builder_->makeNewBlock(); spv::Block& block_dimension_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_dimension_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_dimension_merge, + spv::SelectionControlDontFlattenMask); assert_true(data_is_3d != spv::NoResult); builder_->createConditionalBranch(data_is_3d, &block_dimension_3d_start, @@ -1843,8 +1844,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::Block& block_dimension_3d_start = builder_->makeNewBlock(); spv::Block& block_dimension_stacked_start = builder_->makeNewBlock(); spv::Block& block_dimension_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_dimension_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_dimension_merge, + spv::SelectionControlDontFlattenMask); assert_true(data_is_3d != spv::NoResult); builder_->createConditionalBranch(data_is_3d, &block_dimension_3d_start, @@ -2021,8 +2022,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( ? builder_->makeNewBlock() : block_z_head; if (vol_filter_is_linear != spv::NoResult) { - SpirvCreateSelectionMerge(block_z_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_z_merge, spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch( vol_filter_is_linear, &block_z_linear, &block_z_merge); builder_->setBuildPoint(&block_z_linear); @@ -2187,8 +2188,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::Block& block_swizzle_constant = builder_->makeNewBlock(); spv::Block& block_swizzle_component = builder_->makeNewBlock(); spv::Block& block_swizzle_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_swizzle_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_swizzle_merge, spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(swizzle_bit_2, &block_swizzle_constant, &block_swizzle_component); @@ -2279,8 +2280,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::Block& block_sign_unsigned_biased = builder_->makeNewBlock(); spv::Block& block_sign_gamma_start = builder_->makeNewBlock(); spv::Block& block_sign_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_sign_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_sign_merge, spv::SelectionControlDontFlattenMask); { std::unique_ptr sign_switch_op = std::make_unique(spv::OpSwitch); @@ -2543,8 +2544,8 @@ void SpirvShaderTranslator::SampleTexture( spv::Block& block_sign_head = *builder_->getBuildPoint(); spv::Block& block_sign = builder_->makeNewBlock(); spv::Block& block_sign_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_sign_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_sign_merge, + spv::SelectionControlDontFlattenMask); // Unsigned (i == 0) - if there are any non-signed components. // Signed (i == 1) - if there are any signed components. builder_->createConditionalBranch(i ? is_any_signed : is_all_signed, @@ -2601,8 +2602,8 @@ spv::Id SpirvShaderTranslator::QueryTextureLod( spv::Block& block_sign_signed = builder_->makeNewBlock(); spv::Block& block_sign_unsigned = builder_->makeNewBlock(); spv::Block& block_sign_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_sign_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_sign_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(is_all_signed, &block_sign_signed, &block_sign_unsigned); builder_->setBuildPoint(&block_sign_signed); diff --git a/src/xenia/gpu/spirv_shader_translator_rb.cc b/src/xenia/gpu/spirv_shader_translator_rb.cc index b3c3218b3..2c97dae4e 100644 --- a/src/xenia/gpu/spirv_shader_translator_rb.cc +++ b/src/xenia/gpu/spirv_shader_translator_rb.cc @@ -23,7 +23,7 @@ namespace xe { namespace gpu { spv::Id SpirvShaderTranslator::PreClampedFloat32To7e3( - spv::Builder& builder, spv::Id f32_scalar, spv::Id ext_inst_glsl_std_450) { + SpirvBuilder& builder, spv::Id f32_scalar, spv::Id ext_inst_glsl_std_450) { // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp // Assuming the value is already clamped to [0, 31.875]. @@ -107,7 +107,7 @@ spv::Id SpirvShaderTranslator::PreClampedFloat32To7e3( } spv::Id SpirvShaderTranslator::UnclampedFloat32To7e3( - spv::Builder& builder, spv::Id f32_scalar, spv::Id ext_inst_glsl_std_450) { + SpirvBuilder& builder, spv::Id f32_scalar, spv::Id ext_inst_glsl_std_450) { spv::Id type_float = builder.makeFloatType(32); // Need the source as float for clamping. @@ -136,7 +136,7 @@ spv::Id SpirvShaderTranslator::UnclampedFloat32To7e3( return PreClampedFloat32To7e3(builder, f32_scalar, ext_inst_glsl_std_450); } -spv::Id SpirvShaderTranslator::Float7e3To32(spv::Builder& builder, +spv::Id SpirvShaderTranslator::Float7e3To32(SpirvBuilder& builder, spv::Id f10_uint_scalar, uint32_t f10_shift, bool result_as_uint, @@ -234,7 +234,7 @@ spv::Id SpirvShaderTranslator::Float7e3To32(spv::Builder& builder, } spv::Id SpirvShaderTranslator::PreClampedDepthTo20e4( - spv::Builder& builder, spv::Id f32_scalar, bool round_to_nearest_even, + SpirvBuilder& builder, spv::Id f32_scalar, bool round_to_nearest_even, bool remap_from_0_to_0_5, spv::Id ext_inst_glsl_std_450) { // CFloat24 from d3dref9.dll + // https://github.com/Microsoft/DirectXTex/blob/master/DirectXTex/DirectXTexConvert.cpp @@ -325,7 +325,7 @@ spv::Id SpirvShaderTranslator::PreClampedDepthTo20e4( builder.makeUintConstant(24)); } -spv::Id SpirvShaderTranslator::Depth20e4To32(spv::Builder& builder, +spv::Id SpirvShaderTranslator::Depth20e4To32(SpirvBuilder& builder, spv::Id f24_uint_scalar, uint32_t f24_shift, bool remap_to_0_to_0_5, @@ -463,8 +463,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { builder_->createLoad(var_main_kill_pixel_, spv::NoPrecision); spv::Block& block_kill = builder_->makeNewBlock(); spv::Block& block_kill_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_kill_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_kill_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(kill_pixel, &block_kill, &block_kill_merge); builder_->setBuildPoint(&block_kill); @@ -500,8 +500,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { spv::Block& block_fsi_rt_0_alpha_tests_rt_written = builder_->makeNewBlock(); block_fsi_rt_0_alpha_tests_rt_written_merge = &builder_->makeNewBlock(); - SpirvCreateSelectionMerge( - block_fsi_rt_0_alpha_tests_rt_written_merge->getId(), + builder_->createSelectionMerge( + block_fsi_rt_0_alpha_tests_rt_written_merge, spv::SelectionControlDontFlattenMask); { std::unique_ptr rt_0_written_branch_conditional_op = @@ -538,8 +538,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { builder_->makeUintConstant(uint32_t(xenos::CompareFunction::kAlways))); spv::Block& block_alpha_test = builder_->makeNewBlock(); spv::Block& block_alpha_test_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_alpha_test_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_alpha_test_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(alpha_test_function_is_non_always, &block_alpha_test, &block_alpha_test_merge); @@ -571,8 +571,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { spv::Block& block_alpha_test_not_equal = builder_->makeNewBlock(); spv::Block& block_alpha_test_non_not_equal = builder_->makeNewBlock(); spv::Block& block_alpha_test_not_equal_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_alpha_test_not_equal_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_alpha_test_not_equal_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(alpha_test_function_is_not_equal, &block_alpha_test_not_equal, &block_alpha_test_non_not_equal); @@ -631,8 +631,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { // since SPIR-V requires structured control flow in shaders. spv::Block& block_alpha_test_kill = builder_->makeNewBlock(); spv::Block& block_alpha_test_kill_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_alpha_test_kill_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_alpha_test_kill_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(alpha_test_result, &block_alpha_test_kill_merge, &block_alpha_test_kill); @@ -707,8 +707,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { spv::OpINotEqual, type_bool_, main_fsi_sample_mask_, const_uint_0_); block_fsi_if_after_kill = &builder_->makeNewBlock(); block_fsi_if_after_kill_merge = &builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_fsi_if_after_kill_merge->getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(block_fsi_if_after_kill_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(pixel_not_killed, block_fsi_if_after_kill, block_fsi_if_after_kill_merge); @@ -729,8 +729,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { builder_->makeNewBlock(); spv::Block& block_sample_late_depth_stencil_write_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge( - block_sample_late_depth_stencil_write_merge.getId(), + builder_->createSelectionMerge( + &block_sample_late_depth_stencil_write_merge, spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch( sample_late_depth_stencil_write_needed, @@ -790,8 +790,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { // Skip all color operations if the pixel has failed the tests entirely. block_fsi_if_after_depth_stencil = &builder_->makeNewBlock(); block_fsi_if_after_depth_stencil_merge = &builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_fsi_if_after_depth_stencil_merge->getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(block_fsi_if_after_depth_stencil_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(color_write_depth_stencil_condition, block_fsi_if_after_depth_stencil, block_fsi_if_after_depth_stencil_merge); @@ -856,8 +856,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { spv::Block& fsi_color_written_if_head = *builder_->getBuildPoint(); spv::Block& fsi_color_written_if = builder_->makeNewBlock(); spv::Block& fsi_color_written_if_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(fsi_color_written_if_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&fsi_color_written_if_merge, + spv::SelectionControlDontFlattenMask); { std::unique_ptr rt_written_branch_conditional_op = std::make_unique(spv::OpBranchConditional); @@ -917,8 +917,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { const_uint32_max)); spv::Block& rt_write_mask_not_empty_if = builder_->makeNewBlock(); spv::Block& rt_write_mask_not_empty_if_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(rt_write_mask_not_empty_if_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&rt_write_mask_not_empty_if_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(rt_write_mask_not_empty, &rt_write_mask_not_empty_if, &rt_write_mask_not_empty_if_merge); @@ -986,8 +986,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { spv::Block& rt_blend_enabled_if = builder_->makeNewBlock(); spv::Block& rt_blend_enabled_else = builder_->makeNewBlock(); spv::Block& rt_blend_enabled_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(rt_blend_enabled_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&rt_blend_enabled_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch( rt_blend_enabled, &rt_blend_enabled_if, &rt_blend_enabled_else); @@ -1100,8 +1100,9 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { for (uint32_t i = 0; i < 4; ++i) { spv::Block& block_sample_covered = builder_->makeNewBlock(); spv::Block& block_sample_covered_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_sample_covered_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_sample_covered_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(fsi_samples_covered[i], &block_sample_covered, &block_sample_covered_merge); @@ -1134,8 +1135,9 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { spv::Block& block_load_64bpp_head = *builder_->getBuildPoint(); spv::Block& block_load_64bpp = builder_->makeNewBlock(); spv::Block& block_load_64bpp_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_load_64bpp_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_load_64bpp_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(rt_is_64bpp, &block_load_64bpp, &block_load_64bpp_merge); builder_->setBuildPoint(&block_load_64bpp); @@ -1204,8 +1206,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { rt_access_chain_0); spv::Block& block_store_64bpp = builder_->makeNewBlock(); spv::Block& block_store_64bpp_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_store_64bpp_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_store_64bpp_merge, spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(rt_is_64bpp, &block_store_64bpp, &block_store_64bpp_merge); builder_->setBuildPoint(&block_store_64bpp); @@ -1247,8 +1249,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { spv::Block& rt_keep_mask_not_empty_if_else = builder_->makeNewBlock(); spv::Block& rt_keep_mask_not_empty_if_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(rt_keep_mask_not_empty_if_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&rt_keep_mask_not_empty_if_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(rt_keep_mask_not_empty, &rt_keep_mask_not_empty_if, &rt_keep_mask_not_empty_if_else); @@ -1266,8 +1268,9 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { for (uint32_t i = 0; i < 4; ++i) { spv::Block& block_sample_covered = builder_->makeNewBlock(); spv::Block& block_sample_covered_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_sample_covered_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_sample_covered_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(fsi_samples_covered[i], &block_sample_covered, &block_sample_covered_merge); @@ -1295,8 +1298,9 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { rt_access_chain_0); spv::Block& block_store_64bpp = builder_->makeNewBlock(); spv::Block& block_store_64bpp_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_store_64bpp_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_store_64bpp_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(rt_is_64bpp, &block_store_64bpp, &block_store_64bpp_merge); builder_->setBuildPoint(&block_store_64bpp); @@ -1331,8 +1335,9 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { for (uint32_t i = 0; i < 4; ++i) { spv::Block& block_sample_covered = builder_->makeNewBlock(); spv::Block& block_sample_covered_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_sample_covered_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_sample_covered_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(fsi_samples_covered[i], &block_sample_covered, &block_sample_covered_merge); @@ -1351,8 +1356,9 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { buffer_edram_, id_vector_temp_)); spv::Block& block_store_64bpp = builder_->makeNewBlock(); spv::Block& block_store_64bpp_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_store_64bpp_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge( + &block_store_64bpp_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(rt_is_64bpp, &block_store_64bpp, &block_store_64bpp_merge); builder_->setBuildPoint(&block_store_64bpp); @@ -1403,7 +1409,8 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { spv::Block& block_gamma_head = *builder_->getBuildPoint(); spv::Block& block_gamma = builder_->makeNewBlock(); spv::Block& block_gamma_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_gamma_merge.getId()); + builder_->createSelectionMerge(&block_gamma_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(is_gamma, &block_gamma, &block_gamma_merge); builder_->setBuildPoint(&block_gamma); @@ -1491,7 +1498,8 @@ void SpirvShaderTranslator::FSI_LoadSampleMask(spv::Id msaa_samples) { spv::Block& block_msaa_2x = builder_->makeNewBlock(); spv::Block& block_msaa_4x = builder_->makeNewBlock(); spv::Block& block_msaa_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_msaa_merge.getId()); + builder_->createSelectionMerge(&block_msaa_merge, + spv::SelectionControlDontFlattenMask); { std::unique_ptr msaa_switch_op = std::make_unique(spv::OpSwitch); @@ -1754,8 +1762,8 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( spv::Block& block_depth_stencil_enabled_head = *builder_->getBuildPoint(); spv::Block& block_depth_stencil_enabled = builder_->makeNewBlock(); spv::Block& block_depth_stencil_enabled_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_depth_stencil_enabled_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_depth_stencil_enabled_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(depth_stencil_enabled, &block_depth_stencil_enabled, &block_depth_stencil_enabled_merge); @@ -1788,8 +1796,8 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( block_any_sample_covered_head = builder_->getBuildPoint(); block_any_sample_covered = &builder_->makeNewBlock(); block_any_sample_covered_merge = &builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_any_sample_covered_merge->getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(block_any_sample_covered_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(any_sample_covered, block_any_sample_covered, block_any_sample_covered_merge); @@ -1986,8 +1994,8 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( spv::Block& block_sample_covered_head = *builder_->getBuildPoint(); spv::Block& block_sample_covered = builder_->makeNewBlock(); spv::Block& block_sample_covered_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_sample_covered_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_sample_covered_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(sample_covered, &block_sample_covered, &block_sample_covered_merge); builder_->setBuildPoint(&block_sample_covered); @@ -2090,8 +2098,8 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( spv::Block& block_depth_format_float = builder_->makeNewBlock(); spv::Block& block_depth_format_unorm = builder_->makeNewBlock(); spv::Block& block_depth_format_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_depth_format_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_depth_format_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch( depth_is_float24, &block_depth_format_float, &block_depth_format_unorm); // Float24 case. @@ -2151,8 +2159,8 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( spv::Block& block_stencil_enabled_head = *builder_->getBuildPoint(); spv::Block& block_stencil_enabled = builder_->makeNewBlock(); spv::Block& block_stencil_enabled_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_stencil_enabled_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_stencil_enabled_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(stencil_enabled, &block_stencil_enabled, &block_stencil_enabled_merge); builder_->setBuildPoint(&block_stencil_enabled); @@ -2200,8 +2208,8 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( spv::Block& block_stencil_op_increment_wrap = builder_->makeNewBlock(); spv::Block& block_stencil_op_decrement_wrap = builder_->makeNewBlock(); spv::Block& block_stencil_op_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_stencil_op_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_stencil_op_merge, + spv::SelectionControlDontFlattenMask); { std::unique_ptr stencil_op_switch_op = std::make_unique(spv::OpSwitch); @@ -2409,8 +2417,8 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( if (new_depth_stencil_write_condition != spv::NoResult) { spv::Block& block_depth_stencil_write = builder_->makeNewBlock(); spv::Block& block_depth_stencil_write_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_depth_stencil_write_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_depth_stencil_write_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(new_depth_stencil_write_condition, &block_depth_stencil_write, &block_depth_stencil_write_merge); @@ -2499,7 +2507,8 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( spv::Block& block_format_16_float = builder_->makeNewBlock(); spv::Block& block_format_32_float = builder_->makeNewBlock(); spv::Block& block_format_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_format_merge.getId()); + builder_->createSelectionMerge(&block_format_merge, + spv::SelectionControlDontFlattenMask); { std::unique_ptr format_switch_op = std::make_unique(spv::OpSwitch); @@ -2939,7 +2948,8 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( spv::Block& block_format_32_float = builder_->makeNewBlock(); spv::Block& block_format_32_32_float = builder_->makeNewBlock(); spv::Block& block_format_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_format_merge.getId()); + builder_->createSelectionMerge(&block_format_merge, + spv::SelectionControlDontFlattenMask); { std::unique_ptr format_switch_op = std::make_unique(spv::OpSwitch); @@ -3247,8 +3257,8 @@ spv::Id SpirvShaderTranslator::FSI_FlushNaNClampAndInBlending( spv::Block& block_is_fixed_point_head = *builder_->getBuildPoint(); spv::Block& block_is_fixed_point_if = builder_->makeNewBlock(); spv::Block& block_is_fixed_point_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_is_fixed_point_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_is_fixed_point_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(is_fixed_point, &block_is_fixed_point_if, &block_is_fixed_point_merge); builder_->setBuildPoint(&block_is_fixed_point_if); @@ -3290,7 +3300,8 @@ spv::Id SpirvShaderTranslator::FSI_ApplyColorBlendFactor( spv::Block& block_not_zero_head = *builder_->getBuildPoint(); spv::Block& block_not_zero_if = builder_->makeNewBlock(); spv::Block& block_not_zero_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_not_zero_merge.getId()); + builder_->createSelectionMerge(&block_not_zero_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(factor_not_zero, &block_not_zero_if, &block_not_zero_merge); @@ -3318,8 +3329,8 @@ spv::Id SpirvShaderTranslator::FSI_ApplyColorBlendFactor( one_minus_alpha_factor_blocks[2] = &builder_->makeNewBlock(); spv::Block& block_factor_source_alpha_saturate = builder_->makeNewBlock(); spv::Block& block_factor_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_factor_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_factor_merge, + spv::SelectionControlDontFlattenMask); { std::unique_ptr factor_switch_op = std::make_unique(spv::OpSwitch); @@ -3522,7 +3533,8 @@ spv::Id SpirvShaderTranslator::FSI_ApplyAlphaBlendFactor( spv::Block& block_not_zero_head = *builder_->getBuildPoint(); spv::Block& block_not_zero_if = builder_->makeNewBlock(); spv::Block& block_not_zero_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_not_zero_merge.getId()); + builder_->createSelectionMerge(&block_not_zero_merge, + spv::SelectionControlDontFlattenMask); builder_->createConditionalBranch(factor_not_zero, &block_not_zero_if, &block_not_zero_merge); @@ -3542,8 +3554,8 @@ spv::Id SpirvShaderTranslator::FSI_ApplyAlphaBlendFactor( one_minus_alpha_factor_blocks[2] = &builder_->makeNewBlock(); spv::Block& block_factor_source_alpha_saturate = builder_->makeNewBlock(); spv::Block& block_factor_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_factor_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_factor_merge, + spv::SelectionControlDontFlattenMask); { std::unique_ptr factor_switch_op = std::make_unique(spv::OpSwitch); @@ -3710,8 +3722,8 @@ spv::Id SpirvShaderTranslator::FSI_BlendColorOrAlphaWithUnclampedResult( spv::Block& block_min_max_max = builder_->makeNewBlock(); spv::Block& block_min_max_default = builder_->makeNewBlock(); spv::Block& block_min_max_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_min_max_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_min_max_merge, + spv::SelectionControlDontFlattenMask); { std::unique_ptr min_max_switch_op = std::make_unique(spv::OpSwitch); @@ -3779,8 +3791,8 @@ spv::Id SpirvShaderTranslator::FSI_BlendColorOrAlphaWithUnclampedResult( spv::Block& block_signs_subtract = builder_->makeNewBlock(); spv::Block& block_signs_reverse_subtract = builder_->makeNewBlock(); spv::Block& block_signs_merge = builder_->makeNewBlock(); - SpirvCreateSelectionMerge(block_signs_merge.getId(), - spv::SelectionControlDontFlattenMask); + builder_->createSelectionMerge(&block_signs_merge, + spv::SelectionControlDontFlattenMask); { std::unique_ptr signs_switch_op = std::make_unique(spv::OpSwitch); diff --git a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc index 022bca812..1909972b2 100644 --- a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc @@ -18,7 +18,6 @@ #include #include "third_party/fmt/include/fmt/format.h" -#include "third_party/glslang/SPIRV/SpvBuilder.h" #include "xenia/base/assert.h" #include "xenia/base/logging.h" #include "xenia/base/math.h" @@ -28,6 +27,7 @@ #include "xenia/gpu/gpu_flags.h" #include "xenia/gpu/register_file.h" #include "xenia/gpu/registers.h" +#include "xenia/gpu/spirv_builder.h" #include "xenia/gpu/spirv_shader_translator.h" #include "xenia/gpu/vulkan/vulkan_command_processor.h" #include "xenia/gpu/vulkan/vulkan_shader.h" @@ -952,7 +952,7 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { (key.user_clip_plane_cull ? key.user_clip_plane_count : 0) + key.has_vertex_kill_and; - spv::Builder builder(spv::Spv_1_0, + SpirvBuilder builder(spv::Spv_1_0, (SpirvShaderTranslator::kSpirvMagicToolId << 16) | 1, nullptr); spv::Id ext_inst_glsl_std_450 = builder.import("GLSL.std.450"); @@ -1233,14 +1233,8 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { spv::Block& discard_predecessor = *builder.getBuildPoint(); spv::Block& discard_then_block = builder.makeNewBlock(); spv::Block& discard_merge_block = builder.makeNewBlock(); - { - std::unique_ptr selection_merge_op( - std::make_unique(spv::OpSelectionMerge)); - selection_merge_op->addIdOperand(discard_merge_block.getId()); - selection_merge_op->addImmediateOperand( - spv::SelectionControlDontFlattenMask); - discard_predecessor.addInstruction(std::move(selection_merge_op)); - } + builder.createSelectionMerge(&discard_merge_block, + spv::SelectionControlDontFlattenMask); { std::unique_ptr branch_conditional_op( std::make_unique(spv::OpBranchConditional)); @@ -1295,14 +1289,8 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { spv::Block& discard_predecessor = *builder.getBuildPoint(); spv::Block& discard_then_block = builder.makeNewBlock(); spv::Block& discard_merge_block = builder.makeNewBlock(); - { - std::unique_ptr selection_merge_op( - std::make_unique(spv::OpSelectionMerge)); - selection_merge_op->addIdOperand(discard_merge_block.getId()); - selection_merge_op->addImmediateOperand( - spv::SelectionControlDontFlattenMask); - discard_predecessor.addInstruction(std::move(selection_merge_op)); - } + builder.createSelectionMerge(&discard_merge_block, + spv::SelectionControlDontFlattenMask); { std::unique_ptr branch_conditional_op( std::make_unique(spv::OpBranchConditional)); @@ -1378,15 +1366,8 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { spv::Block& point_size_zero_predecessor = *builder.getBuildPoint(); spv::Block& point_size_zero_then_block = builder.makeNewBlock(); spv::Block& point_size_zero_merge_block = builder.makeNewBlock(); - { - std::unique_ptr selection_merge_op( - std::make_unique(spv::OpSelectionMerge)); - selection_merge_op->addIdOperand(point_size_zero_merge_block.getId()); - selection_merge_op->addImmediateOperand( - spv::SelectionControlDontFlattenMask); - point_size_zero_predecessor.addInstruction( - std::move(selection_merge_op)); - } + builder.createSelectionMerge(&point_size_zero_merge_block, + spv::SelectionControlDontFlattenMask); { std::unique_ptr branch_conditional_op( std::make_unique(spv::OpBranchConditional)); diff --git a/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc b/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc index 4203e3c21..f0e0e87d9 100644 --- a/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc @@ -20,13 +20,13 @@ #include #include "third_party/glslang/SPIRV/GLSL.std.450.h" -#include "third_party/glslang/SPIRV/SpvBuilder.h" #include "xenia/base/assert.h" #include "xenia/base/cvar.h" #include "xenia/base/logging.h" #include "xenia/base/math.h" #include "xenia/gpu/draw_util.h" #include "xenia/gpu/registers.h" +#include "xenia/gpu/spirv_builder.h" #include "xenia/gpu/spirv_shader_translator.h" #include "xenia/gpu/texture_cache.h" #include "xenia/gpu/vulkan/deferred_command_buffer.h" @@ -2166,7 +2166,7 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( std::vector id_vector_temp; std::vector uint_vector_temp; - spv::Builder builder(spv::Spv_1_0, + SpirvBuilder builder(spv::Spv_1_0, (SpirvShaderTranslator::kSpirvMagicToolId << 16) | 1, nullptr); spv::Id ext_inst_glsl_std_450 = builder.import("GLSL.std.450"); @@ -4213,16 +4213,8 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( builder.makeNewBlock(); depth24_to_depth32_merge = &depth24_to_depth32_merge_block; } - { - std::unique_ptr depth24_to_depth32_merge_op = - std::make_unique(spv::OpSelectionMerge); - depth24_to_depth32_merge_op->addIdOperand( - depth24_to_depth32_merge->getId()); - depth24_to_depth32_merge_op->addImmediateOperand( - spv::SelectionControlMaskNone); - builder.getBuildPoint()->addInstruction( - std::move(depth24_to_depth32_merge_op)); - } + builder.createSelectionMerge(depth24_to_depth32_merge, + spv::SelectionControlMaskNone); builder.createConditionalBranch(host_depth_outdated, &depth24_to_depth32_convert_entry, depth24_to_depth32_merge); @@ -4304,15 +4296,8 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( builder.makeUintConstant(0)); spv::Block& stencil_bit_kill_block = builder.makeNewBlock(); spv::Block& stencil_bit_merge_block = builder.makeNewBlock(); - { - std::unique_ptr stencil_bit_merge_op = - std::make_unique(spv::OpSelectionMerge); - stencil_bit_merge_op->addIdOperand(stencil_bit_merge_block.getId()); - stencil_bit_merge_op->addImmediateOperand( - spv::SelectionControlMaskNone); - builder.getBuildPoint()->addInstruction( - std::move(stencil_bit_merge_op)); - } + builder.createSelectionMerge(&stencil_bit_merge_block, + spv::SelectionControlMaskNone); builder.createConditionalBranch(stencil_sample_passed, &stencil_bit_merge_block, &stencil_bit_kill_block); @@ -5582,7 +5567,7 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) { std::vector id_vector_temp; - spv::Builder builder(spv::Spv_1_0, + SpirvBuilder builder(spv::Spv_1_0, (SpirvShaderTranslator::kSpirvMagicToolId << 16) | 1, nullptr); spv::Id ext_inst_glsl_std_450 = builder.import("GLSL.std.450"); From 19d56001d29c4b0adf1e11f67d9ffa7db951baf0 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Wed, 19 Apr 2023 11:53:45 +0300 Subject: [PATCH 4/5] [SPIR-V] Wrap NoContraction operations --- src/xenia/gpu/spirv_builder.h | 14 + src/xenia/gpu/spirv_shader_translator.cc | 101 +++---- src/xenia/gpu/spirv_shader_translator_alu.cc | 116 +++----- .../gpu/spirv_shader_translator_fetch.cc | 279 +++++++----------- src/xenia/gpu/spirv_shader_translator_rb.cc | 174 ++++------- src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc | 48 +-- 6 files changed, 276 insertions(+), 456 deletions(-) diff --git a/src/xenia/gpu/spirv_builder.h b/src/xenia/gpu/spirv_builder.h index 6692ebb09..83e9a982f 100644 --- a/src/xenia/gpu/spirv_builder.h +++ b/src/xenia/gpu/spirv_builder.h @@ -25,6 +25,20 @@ class SpirvBuilder : public spv::Builder { // Make public rather than protected. using spv::Builder::createSelectionMerge; + + spv::Id createNoContractionUnaryOp(spv::Op op_code, spv::Id type_id, + spv::Id operand) { + spv::Id result = createUnaryOp(op_code, type_id, operand); + addDecoration(result, spv::DecorationNoContraction); + return result; + } + + spv::Id createNoContractionBinOp(spv::Op op_code, spv::Id type_id, + spv::Id operand1, spv::Id operand2) { + spv::Id result = createBinOp(op_code, type_id, operand1, operand2); + addDecoration(result, spv::DecorationNoContraction); + return result; + } }; } // namespace gpu diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index e670bc32c..878896402 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -1490,9 +1490,8 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() { builder_->makeUintConstant( static_cast(kSysFlag_WNotReciprocal))), const_uint_0_); - spv::Id guest_position_w_inv = builder_->createBinOp( + spv::Id guest_position_w_inv = builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, const_float_1_, position_w); - builder_->addDecoration(guest_position_w_inv, spv::DecorationNoContraction); position_w = builder_->createTriOp(spv::OpSelect, type_float_, is_w_not_reciprocal, position_w, guest_position_w_inv); @@ -1516,10 +1515,8 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() { builder_->makeUintConstant( static_cast(kSysFlag_XYDividedByW))), const_uint_0_); - spv::Id guest_position_xy_mul_w = builder_->createBinOp( + spv::Id guest_position_xy_mul_w = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, type_float2_, position_xy, position_w); - builder_->addDecoration(guest_position_xy_mul_w, - spv::DecorationNoContraction); position_xy = builder_->createTriOp( spv::OpSelect, type_float2_, builder_->smearScalar(spv::NoPrecision, is_xy_divided_by_w, @@ -1537,10 +1534,8 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() { builder_->makeUintConstant( static_cast(kSysFlag_ZDividedByW))), const_uint_0_); - spv::Id guest_position_z_mul_w = - builder_->createBinOp(spv::OpFMul, type_float_, position_z, position_w); - builder_->addDecoration(guest_position_z_mul_w, - spv::DecorationNoContraction); + spv::Id guest_position_z_mul_w = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, position_z, position_w); position_z = builder_->createTriOp(spv::OpSelect, type_float_, is_z_divided_by_w, guest_position_z_mul_w, position_z); @@ -1565,9 +1560,8 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() { builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, id_vector_temp_), spv::NoPrecision); - position_xyz = - builder_->createBinOp(spv::OpFMul, type_float3_, position_xyz, ndc_scale); - builder_->addDecoration(position_xyz, spv::DecorationNoContraction); + position_xyz = builder_->createNoContractionBinOp(spv::OpFMul, type_float3_, + position_xyz, ndc_scale); id_vector_temp_.clear(); id_vector_temp_.push_back( builder_->makeIntConstant(kSystemConstantNdcOffset)); @@ -1575,12 +1569,10 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() { builder_->createAccessChain(spv::StorageClassUniform, uniform_system_constants_, id_vector_temp_), spv::NoPrecision); - spv::Id ndc_offset_mul_w = builder_->createBinOp( + spv::Id ndc_offset_mul_w = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, type_float3_, ndc_offset, position_w); - builder_->addDecoration(ndc_offset_mul_w, spv::DecorationNoContraction); - position_xyz = builder_->createBinOp(spv::OpFAdd, type_float3_, position_xyz, - ndc_offset_mul_w); - builder_->addDecoration(position_xyz, spv::DecorationNoContraction); + position_xyz = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float3_, position_xyz, ndc_offset_mul_w); // Write the point size. if (output_point_size_ != spv::NoResult) { @@ -1666,36 +1658,29 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() { id_vector_temp_.clear(); id_vector_temp_.push_back(builder_->makeIntConstant( kSystemConstantPointScreenDiameterToNdcRadius)); - spv::Id point_radius = builder_->createBinOp( + spv::Id point_radius = builder_->createNoContractionBinOp( spv::OpFMul, type_float2_, point_guest_diameter, builder_->createLoad(builder_->createAccessChain( spv::StorageClassUniform, uniform_system_constants_, id_vector_temp_), spv::NoPrecision)); - builder_->addDecoration(point_radius, spv::DecorationNoContraction); // Transform the radius from the normalized device coordinates to the clip // space. - point_radius = builder_->createBinOp(spv::OpVectorTimesScalar, type_float2_, - point_radius, position_w); - builder_->addDecoration(point_radius, spv::DecorationNoContraction); + point_radius = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float2_, point_radius, position_w); - // Apply the direction of expansion for the current host vertex. - spv::Id point_radius_negative = - builder_->createUnaryOp(spv::OpFNegate, type_float2_, point_radius); - builder_->addDecoration(point_radius_negative, - spv::DecorationNoContraction); - // Expand the point sprite. + // Expand the point sprite in the direction for the current host vertex. uint_vector_temp_.clear(); uint_vector_temp_.push_back(0); uint_vector_temp_.push_back(1); - spv::Id point_position_xy = builder_->createBinOp( + spv::Id point_position_xy = builder_->createNoContractionBinOp( spv::OpFAdd, type_float2_, builder_->createRvalueSwizzle(spv::NoPrecision, type_float2_, position_xyz, uint_vector_temp_), builder_->createTriOp(spv::OpSelect, type_float2_, point_vertex_positive, point_radius, - point_radius_negative)); - builder_->addDecoration(point_position_xy, spv::DecorationNoContraction); + builder_->createNoContractionUnaryOp( + spv::OpFNegate, type_float2_, point_radius))); // Store the position. spv::Id position; { @@ -2419,9 +2404,8 @@ spv::Id SpirvShaderTranslator::ApplyOperandModifiers( } if (original_operand.is_negated != invert_negate) { EnsureBuildPointAvailable(); - operand_value = - builder_->createUnaryOp(spv::OpFNegate, type, operand_value); - builder_->addDecoration(operand_value, spv::DecorationNoContraction); + operand_value = builder_->createNoContractionUnaryOp(spv::OpFNegate, type, + operand_value); } return operand_value; } @@ -3092,29 +3076,28 @@ spv::Id SpirvShaderTranslator::PWLGammaToLinear(spv::Id gamma, spv::Op value_times_scalar_opcode = is_vector ? spv::OpVectorTimesScalar : spv::OpFMul; // linear = gamma * (255.0f * 1024.0f) * scale + offset - spv::Id linear = - builder_->createBinOp(value_times_scalar_opcode, value_type, gamma, - builder_->makeFloatConstant(255.0f * 1024.0f)); - builder_->addDecoration(linear, spv::DecorationNoContraction); - linear = builder_->createBinOp(spv::OpFMul, value_type, linear, scale); - builder_->addDecoration(linear, spv::DecorationNoContraction); - linear = builder_->createBinOp(spv::OpFAdd, value_type, linear, offset); - builder_->addDecoration(linear, spv::DecorationNoContraction); + spv::Id linear = builder_->createNoContractionBinOp( + spv::OpFAdd, value_type, + builder_->createNoContractionBinOp( + spv::OpFMul, value_type, + builder_->createNoContractionBinOp( + value_times_scalar_opcode, value_type, gamma, + builder_->makeFloatConstant(255.0f * 1024.0f)), + scale), + offset); // linear += trunc(linear * scale) - spv::Id linear_integer_term = - builder_->createBinOp(spv::OpFMul, value_type, linear, scale); - builder_->addDecoration(linear_integer_term, spv::DecorationNoContraction); + spv::Id linear_integer_term = builder_->createNoContractionBinOp( + spv::OpFMul, value_type, linear, scale); id_vector_temp_.clear(); id_vector_temp_.push_back(linear_integer_term); linear_integer_term = builder_->createBuiltinCall( value_type, ext_inst_glsl_std_450_, GLSLstd450Trunc, id_vector_temp_); - linear = builder_->createBinOp(spv::OpFAdd, value_type, linear, - linear_integer_term); - builder_->addDecoration(linear, spv::DecorationNoContraction); + linear = builder_->createNoContractionBinOp(spv::OpFAdd, value_type, linear, + linear_integer_term); // linear *= 1.0f / 1023.0f - linear = builder_->createBinOp(value_times_scalar_opcode, value_type, linear, - builder_->makeFloatConstant(1.0f / 1023.0f)); - builder_->addDecoration(linear, spv::DecorationNoContraction); + linear = builder_->createNoContractionBinOp( + value_times_scalar_opcode, value_type, linear, + builder_->makeFloatConstant(1.0f / 1023.0f)); return linear; } @@ -3187,18 +3170,18 @@ spv::Id SpirvShaderTranslator::LinearToPWLGamma(spv::Id linear, offset_3_or_2, offset_1_or_0); // gamma = trunc(linear * scale) * (1.0f / 255.0f) + offset - spv::Id gamma = builder_->createBinOp(spv::OpFMul, value_type, linear, scale); - builder_->addDecoration(gamma, spv::DecorationNoContraction); + spv::Id gamma = builder_->createNoContractionBinOp(spv::OpFMul, value_type, + linear, scale); id_vector_temp_.clear(); id_vector_temp_.push_back(gamma); gamma = builder_->createBuiltinCall(value_type, ext_inst_glsl_std_450_, GLSLstd450Trunc, id_vector_temp_); - gamma = builder_->createBinOp( - is_vector ? spv::OpVectorTimesScalar : spv::OpFMul, value_type, gamma, - builder_->makeFloatConstant(1.0f / 255.0f)); - builder_->addDecoration(gamma, spv::DecorationNoContraction); - gamma = builder_->createBinOp(spv::OpFAdd, value_type, gamma, offset); - builder_->addDecoration(gamma, spv::DecorationNoContraction); + gamma = builder_->createNoContractionBinOp( + spv::OpFAdd, value_type, + builder_->createNoContractionBinOp( + is_vector ? spv::OpVectorTimesScalar : spv::OpFMul, value_type, gamma, + builder_->makeFloatConstant(1.0f / 255.0f)), + offset); return gamma; } diff --git a/src/xenia/gpu/spirv_shader_translator_alu.cc b/src/xenia/gpu/spirv_shader_translator_alu.cc index 76410aa71..0c4c3626e 100644 --- a/src/xenia/gpu/spirv_shader_translator_alu.cc +++ b/src/xenia/gpu/spirv_shader_translator_alu.cc @@ -188,14 +188,12 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( switch (instr.vector_opcode) { case ucode::AluVectorOpcode::kAdd: { - spv::Id result = builder_->createBinOp( + return builder_->createNoContractionBinOp( spv::OpFAdd, result_type, GetOperandComponents(operand_storage[0], instr.vector_operands[0], used_result_components), GetOperandComponents(operand_storage[1], instr.vector_operands[1], used_result_components)); - builder_->addDecoration(result, spv::DecorationNoContraction); - return result; } case ucode::AluVectorOpcode::kMul: case ucode::AluVectorOpcode::kMad: { @@ -205,9 +203,8 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( GetOperandComponents(operand_storage[i], instr.vector_operands[i], used_result_components); } - spv::Id result = builder_->createBinOp( + spv::Id result = builder_->createNoContractionBinOp( spv::OpFMul, result_type, multiplicands[0], multiplicands[1]); - builder_->addDecoration(result, spv::DecorationNoContraction); uint32_t multiplicands_different = used_result_components & ~instr.vector_operands[0].GetIdenticalComponents( @@ -302,11 +299,10 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( if (instr.vector_opcode == ucode::AluVectorOpcode::kMad) { // Not replacing true `0 + term` with conditional selection of the term // because +0 + -0 should result in +0, not -0. - result = builder_->createBinOp( + result = builder_->createNoContractionBinOp( spv::OpFAdd, result_type, result, GetOperandComponents(operand_storage[2], instr.vector_operands[2], used_result_components)); - builder_->addDecoration(result, spv::DecorationNoContraction); } return result; } @@ -329,10 +325,9 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( } else { maxa_operand_0_w = operand_0; } - spv::Id maxa_address = - builder_->createBinOp(spv::OpFAdd, type_float_, maxa_operand_0_w, - builder_->makeFloatConstant(0.5f)); - builder_->addDecoration(maxa_address, spv::DecorationNoContraction); + spv::Id maxa_address = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, maxa_operand_0_w, + builder_->makeFloatConstant(0.5f)); id_vector_temp_.clear(); id_vector_temp_.push_back(maxa_address); maxa_address = @@ -514,10 +509,9 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( operand_components[j] = builder_->createCompositeExtract(operands[j], type_float_, i); } - spv::Id product = - builder_->createBinOp(spv::OpFMul, type_float_, - operand_components[0], operand_components[1]); - builder_->addDecoration(product, spv::DecorationNoContraction); + spv::Id product = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, operand_components[0], + operand_components[1]); if (different & (1 << i)) { // Shader Model 3: +0 or denormal * anything = +-0. product = ZeroIfAnyOperandIsZero( @@ -531,16 +525,14 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( result = product; continue; } - result = - builder_->createBinOp(spv::OpFAdd, type_float_, result, product); - builder_->addDecoration(result, spv::DecorationNoContraction); + result = builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, + result, product); } if (instr.vector_opcode == ucode::AluVectorOpcode::kDp2Add) { - result = builder_->createBinOp( + result = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, result, GetOperandComponents(operand_storage[2], instr.vector_operands[2], 0b0001)); - builder_->addDecoration(result, spv::DecorationNoContraction); } return result; } @@ -574,17 +566,14 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( } spv::Id operand_neg[3] = {}; if (used_result_components & 0b0001) { - operand_neg[1] = - builder_->createUnaryOp(spv::OpFNegate, type_float_, operand[1]); - builder_->addDecoration(operand_neg[1], spv::DecorationNoContraction); + operand_neg[1] = builder_->createNoContractionUnaryOp( + spv::OpFNegate, type_float_, operand[1]); } if (used_result_components & 0b0010) { - operand_neg[0] = - builder_->createUnaryOp(spv::OpFNegate, type_float_, operand[0]); - builder_->addDecoration(operand_neg[0], spv::DecorationNoContraction); - operand_neg[2] = - builder_->createUnaryOp(spv::OpFNegate, type_float_, operand[2]); - builder_->addDecoration(operand_neg[2], spv::DecorationNoContraction); + operand_neg[0] = builder_->createNoContractionUnaryOp( + spv::OpFNegate, type_float_, operand[0]); + operand_neg[2] = builder_->createNoContractionUnaryOp( + spv::OpFNegate, type_float_, operand[2]); } spv::Id ma_z_result[4] = {}, ma_yx_result[4] = {}; @@ -724,9 +713,8 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( // Multiply the major axis by 2. spv::Id& ma2 = id_vector_temp_[xe::bit_count(used_result_components & ((1 << 2) - 1))]; - ma2 = builder_->createBinOp(spv::OpFMul, type_float_, - builder_->makeFloatConstant(2.0f), ma2); - builder_->addDecoration(ma2, spv::DecorationNoContraction); + ma2 = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, builder_->makeFloatConstant(2.0f), ma2); } if (used_result_component_count == 1) { // Only one component - not composite. @@ -817,14 +805,12 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( builder_->createBinOp(spv::OpFOrdEqual, type_bool_, operands_x[0], const_float_0_), builder_->createBinOp(op, type_bool_, operands_x[1], const_float_0_)); - spv::Id result = builder_->createBinOp( + return builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, builder_->createTriOp(spv::OpSelect, type_float_, condition, builder_->makeFloatConstant(-1.0f), operands_x[0]), const_float_1_); - builder_->addDecoration(result, spv::DecorationNoContraction); - return result; } case ucode::AluVectorOpcode::kKillEq: @@ -872,9 +858,8 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( (used_result_components & 0b1000) ? builder_->createCompositeExtract(operands[1], type_float_, 0) : operands[1]; - result_y = builder_->createBinOp(spv::OpFMul, type_float_, - operands_y[0], operands_y[1]); - builder_->addDecoration(result_y, spv::DecorationNoContraction); + result_y = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, operands_y[0], operands_y[1]); if (!(instr.vector_operands[0].GetIdenticalComponents( instr.vector_operands[1]) & 0b0010)) { @@ -997,26 +982,22 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( case ucode::AluScalarOpcode::kSubs: { spv::Id a, b; GetOperandScalarXY(operand_storage[0], instr.scalar_operands[0], a, b); - spv::Id result = builder_->createBinOp( + return builder_->createNoContractionBinOp( spv::Op(kOps[size_t(instr.scalar_opcode)]), type_float_, a, b); - builder_->addDecoration(result, spv::DecorationNoContraction); - return result; } case ucode::AluScalarOpcode::kAddsPrev: case ucode::AluScalarOpcode::kSubsPrev: { - spv::Id result = builder_->createBinOp( + return builder_->createNoContractionBinOp( spv::Op(kOps[size_t(instr.scalar_opcode)]), type_float_, GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision)); - builder_->addDecoration(result, spv::DecorationNoContraction); - return result; } case ucode::AluScalarOpcode::kMuls: { spv::Id a, b; GetOperandScalarXY(operand_storage[0], instr.scalar_operands[0], a, b); - spv::Id result = builder_->createBinOp(spv::OpFMul, type_float_, a, b); - builder_->addDecoration(result, spv::DecorationNoContraction); + spv::Id result = + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, b); if (a != b) { // Shader Model 3: +0 or denormal * anything = +-0. result = ZeroIfAnyOperandIsZero( @@ -1030,8 +1011,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( instr.scalar_operands[0], 0b0001); spv::Id ps = builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision); - spv::Id result = builder_->createBinOp(spv::OpFMul, type_float_, a, ps); - builder_->addDecoration(result, spv::DecorationNoContraction); + spv::Id result = + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, ps); // Shader Model 3: +0 or denormal * anything = +-0. id_vector_temp_.clear(); id_vector_temp_.push_back(ps); @@ -1056,9 +1037,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( id_vector_temp_.push_back(ps); spv::Id ps_abs = builder_->createBuiltinCall( type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, id_vector_temp_); - spv::Id ps_abs_neg = - builder_->createUnaryOp(spv::OpFNegate, type_float_, ps_abs); - builder_->addDecoration(ps_abs_neg, spv::DecorationNoContraction); + spv::Id ps_abs_neg = builder_->createNoContractionUnaryOp( + spv::OpFNegate, type_float_, ps_abs); condition = builder_->createBinOp( spv::OpLogicalAnd, type_bool_, condition, builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, @@ -1076,9 +1056,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( } if (!instr.scalar_operands[0].is_absolute_value || !instr.scalar_operands[0].is_negated) { - b_abs_neg = - builder_->createUnaryOp(spv::OpFNegate, type_float_, b_abs_neg); - builder_->addDecoration(b_abs_neg, spv::DecorationNoContraction); + b_abs_neg = builder_->createNoContractionUnaryOp( + spv::OpFNegate, type_float_, b_abs_neg); } condition = builder_->createBinOp( spv::OpLogicalAnd, type_bool_, condition, @@ -1101,8 +1080,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( ? GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001) : b; - product = builder_->createBinOp(spv::OpFMul, type_float_, a, ps); - builder_->addDecoration(product, spv::DecorationNoContraction); + product = + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, ps); // Shader Model 3: +0 or denormal * anything = +-0. product = ZeroIfAnyOperandIsZero( product, GetAbsoluteOperand(a, instr.scalar_operands[0]), ps_abs); @@ -1136,9 +1115,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( // maxasf: a0 = (int)clamp(floor(src0.a), -256.0, 255.0) spv::Id maxa_address; if (instr.scalar_opcode == ucode::AluScalarOpcode::kMaxAs) { - maxa_address = builder_->createBinOp( + maxa_address = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, a, builder_->makeFloatConstant(0.5f)); - builder_->addDecoration(maxa_address, spv::DecorationNoContraction); } else { maxa_address = a; } @@ -1212,11 +1190,10 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( builder_->makeFloatConstant(-FLT_MAX), result); } case ucode::AluScalarOpcode::kRcpc: { - spv::Id result = builder_->createBinOp( + spv::Id result = builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, const_float_1_, GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); - builder_->addDecoration(result, spv::DecorationNoContraction); result = builder_->createTriOp( spv::OpSelect, type_float_, builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, @@ -1229,11 +1206,10 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( builder_->makeFloatConstant(FLT_MAX), result); } case ucode::AluScalarOpcode::kRcpf: { - spv::Id result = builder_->createBinOp( + spv::Id result = builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, const_float_1_, GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); - builder_->addDecoration(result, spv::DecorationNoContraction); result = builder_->createTriOp( spv::OpSelect, type_float_, builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, @@ -1250,12 +1226,10 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( return builder_->createUnaryOp(spv::OpBitcast, type_float_, result); } case ucode::AluScalarOpcode::kRcp: { - spv::Id result = builder_->createBinOp( + return builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, const_float_1_, GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001)); - builder_->addDecoration(result, spv::DecorationNoContraction); - return result; } case ucode::AluScalarOpcode::kRsqc: { id_vector_temp_.clear(); @@ -1328,12 +1302,11 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( const_float_1_, a)); } case ucode::AluScalarOpcode::kSetpPop: { - spv::Id a_minus_1 = builder_->createBinOp( + spv::Id a_minus_1 = builder_->createNoContractionBinOp( spv::OpFSub, type_float_, GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), const_float_1_); - builder_->addDecoration(a_minus_1, spv::DecorationNoContraction); spv::Id predicate = builder_->createBinOp( spv::OpFOrdLessThanEqual, type_bool_, a_minus_1, const_float_0_); builder_->createStore(predicate, var_main_predicate_); @@ -1377,9 +1350,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( operand_storage[0], instr.scalar_operands[0], 0b0001); spv::Id operand_1 = GetOperandComponents( operand_storage[1], instr.scalar_operands[1], 0b0001); - spv::Id result = - builder_->createBinOp(spv::OpFMul, type_float_, operand_0, operand_1); - builder_->addDecoration(result, spv::DecorationNoContraction); + spv::Id result = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, operand_0, operand_1); if (!(instr.scalar_operands[0].GetIdenticalComponents( instr.scalar_operands[1]) & 0b0001)) { @@ -1394,14 +1366,12 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( case ucode::AluScalarOpcode::kAddsc1: case ucode::AluScalarOpcode::kSubsc0: case ucode::AluScalarOpcode::kSubsc1: { - spv::Id result = builder_->createBinOp( + return builder_->createNoContractionBinOp( spv::Op(kOps[size_t(instr.scalar_opcode)]), type_float_, GetOperandComponents(operand_storage[0], instr.scalar_operands[0], 0b0001), GetOperandComponents(operand_storage[1], instr.scalar_operands[1], 0b0001)); - builder_->addDecoration(result, spv::DecorationNoContraction); - return result; } case ucode::AluScalarOpcode::kRetainPrev: diff --git a/src/xenia/gpu/spirv_shader_translator_fetch.cc b/src/xenia/gpu/spirv_shader_translator_fetch.cc index 45f7477ec..9599dffe8 100644 --- a/src/xenia/gpu/spirv_shader_translator_fetch.cc +++ b/src/xenia/gpu/spirv_shader_translator_fetch.cc @@ -80,9 +80,8 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( spv::Id index = GetOperandComponents( LoadOperandStorage(instr.operands[0]), instr.operands[0], 0b0001); if (instr.attributes.is_index_rounded) { - index = builder_->createBinOp(spv::OpFAdd, type_float_, index, - builder_->makeFloatConstant(0.5f)); - builder_->addDecoration(index, spv::DecorationNoContraction); + index = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, index, builder_->makeFloatConstant(0.5f)); } id_vector_temp_.clear(); id_vector_temp_.push_back(index); @@ -297,18 +296,16 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( if (instr.attributes.is_signed) { switch (instr.attributes.signed_rf_mode) { case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne: - result = builder_->createBinOp( + result = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, result_type, result, builder_->makeFloatConstant(1.0f / 2147483647.0f)); - builder_->addDecoration(result, spv::DecorationNoContraction); // No need to clamp to -1 if signed - 1/(2^31-1) is rounded to // 1/(2^31) as float32. break; case xenos::SignedRepeatingFractionMode::kNoZero: { - result = builder_->createBinOp( + result = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, result_type, result, builder_->makeFloatConstant(1.0f / 2147483647.5f)); - builder_->addDecoration(result, spv::DecorationNoContraction); spv::Id const_no_zero = builder_->makeFloatConstant(0.5f / 2147483647.5f); if (used_format_component_count > 1) { @@ -319,18 +316,16 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( const_no_zero = builder_->makeCompositeConstant( result_type, id_vector_temp_); } - result = builder_->createBinOp(spv::OpFAdd, result_type, result, - const_no_zero); - builder_->addDecoration(result, spv::DecorationNoContraction); + result = builder_->createNoContractionBinOp( + spv::OpFAdd, result_type, result, const_no_zero); } break; default: assert_unhandled_case(instr.attributes.signed_rf_mode); } } else { - result = builder_->createBinOp( + result = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, result_type, result, builder_->makeFloatConstant(1.0f / 4294967295.0f)); - builder_->addDecoration(result, spv::DecorationNoContraction); } } break; @@ -449,9 +444,8 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( } else { packed_scale_mul_op = spv::OpFMul; } - result = builder_->createBinOp(packed_scale_mul_op, result_type, result, - const_packed_scale); - builder_->addDecoration(result, spv::DecorationNoContraction); + result = builder_->createNoContractionBinOp( + packed_scale_mul_op, result_type, result, const_packed_scale); if (instr.attributes.is_signed) { switch (instr.attributes.signed_rf_mode) { case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne: { @@ -479,13 +473,12 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( id_vector_temp_.push_back( builder_->makeFloatConstant(0.5f * packed_scales[i])); } - result = - builder_->createBinOp(spv::OpFAdd, result_type, result, - used_format_component_count > 1 - ? builder_->makeCompositeConstant( - result_type, id_vector_temp_) - : id_vector_temp_[0]); - builder_->addDecoration(result, spv::DecorationNoContraction); + result = builder_->createNoContractionBinOp( + spv::OpFAdd, result_type, result, + used_format_component_count > 1 + ? builder_->makeCompositeConstant(result_type, + id_vector_temp_) + : id_vector_temp_[0]); break; default: assert_unhandled_case(instr.attributes.signed_rf_mode); @@ -497,11 +490,10 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( if (result != spv::NoResult) { // Apply the exponent bias. if (instr.attributes.exp_adjust) { - result = builder_->createBinOp(spv::OpVectorTimesScalar, - builder_->getTypeId(result), result, - builder_->makeFloatConstant(std::ldexp( - 1.0f, instr.attributes.exp_adjust))); - builder_->addDecoration(result, spv::DecorationNoContraction); + result = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, builder_->getTypeId(result), result, + builder_->makeFloatConstant( + std::ldexp(1.0f, instr.attributes.exp_adjust))); } // If any components not present in the format were requested, pad the @@ -1102,18 +1094,14 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( if (!instr.attributes.unnormalized_coordinates) { spv::Id size_component = size[coordinate_component_index]; assert_true(size_component != spv::NoResult); - result_component = builder_->createBinOp( + result_component = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, result_component, size_component); - builder_->addDecoration(result_component, - spv::DecorationNoContraction); } float component_offset = offset_values[coordinate_component_index]; if (component_offset) { - result_component = builder_->createBinOp( + result_component = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, result_component, builder_->makeFloatConstant(component_offset)); - builder_->addDecoration(result_component, - spv::DecorationNoContraction); } // 0.5 has already been subtracted via offsets previously. id_vector_temp_.clear(); @@ -1137,27 +1125,21 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::Id size_component = size[i]; if (instr.attributes.unnormalized_coordinates) { if (component_offset != spv::NoResult) { - coordinate_ref = builder_->createBinOp( + coordinate_ref = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, coordinate_ref, component_offset); - builder_->addDecoration(coordinate_ref, - spv::DecorationNoContraction); } assert_true(size_component != spv::NoResult); - coordinate_ref = builder_->createBinOp( + coordinate_ref = builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, coordinate_ref, size_component); - builder_->addDecoration(coordinate_ref, spv::DecorationNoContraction); } else { if (component_offset != spv::NoResult) { assert_true(size_component != spv::NoResult); - spv::Id component_offset_normalized = builder_->createBinOp( - spv::OpFDiv, type_float_, component_offset, size_component); - builder_->addDecoration(component_offset_normalized, - spv::DecorationNoContraction); - coordinate_ref = - builder_->createBinOp(spv::OpFAdd, type_float_, coordinate_ref, - component_offset_normalized); - builder_->addDecoration(coordinate_ref, - spv::DecorationNoContraction); + spv::Id component_offset_normalized = + builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, component_offset, size_component); + coordinate_ref = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, coordinate_ref, + component_offset_normalized); } } } @@ -1170,10 +1152,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( if (instr.attributes.unnormalized_coordinates) { // Apply the offset, and normalize the Z coordinate for a 3D texture. if (z_offset != spv::NoResult) { - z_coordinate_ref = builder_->createBinOp( + z_coordinate_ref = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, z_coordinate_ref, z_offset); - builder_->addDecoration(z_coordinate_ref, - spv::DecorationNoContraction); } spv::Block& block_dimension_head = *builder_->getBuildPoint(); spv::Block& block_dimension_merge = builder_->makeNewBlock(); @@ -1185,9 +1165,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( &block_dimension_merge); builder_->setBuildPoint(&block_dimension_3d); assert_true(z_size != spv::NoResult); - spv::Id z_3d = builder_->createBinOp(spv::OpFDiv, type_float_, - z_coordinate_ref, z_size); - builder_->addDecoration(z_3d, spv::DecorationNoContraction); + spv::Id z_3d = builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, z_coordinate_ref, z_size); builder_->createBranch(&block_dimension_merge); builder_->setBuildPoint(&block_dimension_merge); { @@ -1222,13 +1201,10 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( builder_->setBuildPoint(block_dimension_3d); if (z_offset != spv::NoResult) { assert_true(z_size != spv::NoResult); - spv::Id z_offset_normalized = builder_->createBinOp( + spv::Id z_offset_normalized = builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, z_offset, z_size); - builder_->addDecoration(z_offset_normalized, - spv::DecorationNoContraction); - z_3d = builder_->createBinOp(spv::OpFAdd, type_float_, z_3d, - z_offset_normalized); - builder_->addDecoration(z_3d, spv::DecorationNoContraction); + z_3d = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, z_3d, z_offset_normalized); } builder_->createBranch(&block_dimension_merge); } @@ -1236,13 +1212,11 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( builder_->setBuildPoint(&block_dimension_stacked); spv::Id z_stacked = z_coordinate_ref; assert_true(z_size != spv::NoResult); - z_stacked = builder_->createBinOp(spv::OpFMul, type_float_, z_stacked, - z_size); - builder_->addDecoration(z_stacked, spv::DecorationNoContraction); + z_stacked = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, z_stacked, z_size); if (z_offset != spv::NoResult) { - z_stacked = builder_->createBinOp(spv::OpFAdd, type_float_, - z_stacked, z_offset); - builder_->addDecoration(z_stacked, spv::DecorationNoContraction); + z_stacked = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, z_stacked, z_offset); } builder_->createBranch(&block_dimension_merge); // Select one of the two. @@ -1267,23 +1241,20 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::Id const_float_2 = builder_->makeFloatConstant(2.0f); spv::Id const_float_minus_3 = builder_->makeFloatConstant(-3.0f); for (uint32_t i = 0; i < 2; ++i) { - spv::Id& coordinate_ref = coordinates[i]; - coordinate_ref = builder_->createBinOp(spv::OpFMul, type_float_, - coordinate_ref, const_float_2); - builder_->addDecoration(coordinate_ref, spv::DecorationNoContraction); - coordinate_ref = builder_->createBinOp( - spv::OpFAdd, type_float_, coordinate_ref, const_float_minus_3); - builder_->addDecoration(coordinate_ref, spv::DecorationNoContraction); + coordinates[i] = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, + builder_->createNoContractionBinOp(spv::OpFMul, type_float_, + coordinates[i], const_float_2), + const_float_minus_3); } // Get the face index (floored, within 0...5 - OpConvertFToU is // undefined for out-of-range values, so clamping from both sides // manually). spv::Id face = coordinates[2]; if (offset_values[2]) { - face = builder_->createBinOp( + face = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, face, builder_->makeFloatConstant(offset_values[2])); - builder_->addDecoration(face, spv::DecorationNoContraction); } id_vector_temp_.clear(); id_vector_temp_.push_back(face); @@ -1307,12 +1278,10 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( builder_->makeFloatConstant(-1.0f), builder_->makeFloatConstant(1.0f)); // Remap the axes in a way opposite to the ALU cube instruction. - spv::Id sc_negated = builder_->createUnaryOp( + spv::Id sc_negated = builder_->createNoContractionUnaryOp( spv::OpFNegate, type_float_, coordinates[0]); - builder_->addDecoration(sc_negated, spv::DecorationNoContraction); - spv::Id tc_negated = builder_->createUnaryOp( + spv::Id tc_negated = builder_->createNoContractionUnaryOp( spv::OpFNegate, type_float_, coordinates[1]); - builder_->addDecoration(tc_negated, spv::DecorationNoContraction); spv::Block& block_ma_head = *builder_->getBuildPoint(); spv::Block& block_ma_x = builder_->makeNewBlock(); spv::Block& block_ma_y = builder_->makeNewBlock(); @@ -1578,7 +1547,7 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( // specification order: specified LOD + sampler LOD bias + instruction // LOD bias). // Fetch constant LOD (bits 12:21 of the word 4). - spv::Id lod = builder_->createBinOp( + spv::Id lod = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, builder_->createUnaryOp( spv::OpConvertSToF, type_float_, @@ -1587,21 +1556,18 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( builder_->makeUintConstant(12), builder_->makeUintConstant(10))), builder_->makeFloatConstant(1.0f / 32.0f)); - builder_->addDecoration(lod, spv::DecorationNoContraction); // Register LOD. if (instr.attributes.use_register_lod) { - lod = builder_->createBinOp( + lod = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, builder_->createLoad(var_main_tfetch_lod_, spv::NoPrecision), lod); - builder_->addDecoration(lod, spv::DecorationNoContraction); } // Instruction LOD bias. if (instr.attributes.lod_bias) { - lod = builder_->createBinOp( + lod = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, lod, builder_->makeFloatConstant(instr.attributes.lod_bias)); - builder_->addDecoration(lod, spv::DecorationNoContraction); } // Calculate the gradients for sampling the texture if needed. @@ -1639,14 +1605,10 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( if (instr.attributes.unnormalized_coordinates) { // Normalize the gradients. assert_true(size[0] != spv::NoResult); - gradient_h_1d = builder_->createBinOp( + gradient_h_1d = builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, gradient_h_1d, size[0]); - builder_->addDecoration(gradient_h_1d, - spv::DecorationNoContraction); - gradient_v_1d = builder_->createBinOp( + gradient_v_1d = builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, gradient_v_1d, size[0]); - builder_->addDecoration(gradient_v_1d, - spv::DecorationNoContraction); } } else { builder_->addCapability(spv::CapabilityDerivativeControl); @@ -1655,14 +1617,10 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( gradient_v_1d = builder_->createUnaryOp( spv::OpDPdyCoarse, type_float_, coordinates[0]); } - gradient_h_1d = builder_->createBinOp( + gradient_h_1d = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, gradient_h_1d, lod_gradient_scale); - builder_->addDecoration(gradient_h_1d, - spv::DecorationNoContraction); - gradient_v_1d = builder_->createBinOp( + gradient_v_1d = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, gradient_v_1d, lod_gradient_scale); - builder_->addDecoration(gradient_v_1d, - spv::DecorationNoContraction); // 1D textures are sampled as 2D arrays - need 2-component // gradients. id_vector_temp_.clear(); @@ -1690,15 +1648,11 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( if (instr.attributes.unnormalized_coordinates) { // Normalize the gradients. assert_true(size[0] != spv::NoResult); - register_gradient_x = builder_->createBinOp( + register_gradient_x = builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, register_gradient_x, size[0]); - builder_->addDecoration(register_gradient_x, - spv::DecorationNoContraction); assert_true(size[1] != spv::NoResult); - register_gradient_y = builder_->createBinOp( + register_gradient_y = builder_->createNoContractionBinOp( spv::OpFDiv, type_float_, register_gradient_y, size[1]); - builder_->addDecoration(register_gradient_y, - spv::DecorationNoContraction); } id_vector_temp_.clear(); id_vector_temp_.push_back(register_gradient_x); @@ -1723,16 +1677,12 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( builder_->createUnaryOp(spv::OpDPdyCoarse, type_float2_, gradient_coordinate_vector); } - gradients_h = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float2_, - gradients_h, lod_gradient_scale); - builder_->addDecoration(gradients_h, - spv::DecorationNoContraction); - gradients_v = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float2_, - gradients_v, lod_gradient_scale); - builder_->addDecoration(gradients_v, - spv::DecorationNoContraction); + gradients_h = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float2_, gradients_h, + lod_gradient_scale); + gradients_v = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float2_, gradients_v, + lod_gradient_scale); } break; case xenos::FetchOpDimension::k3DOrStacked: { if (instr.attributes.use_register_gradients) { @@ -1747,13 +1697,12 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( id_vector_temp_.clear(); for (uint32_t j = 0; j < 3; ++j) { assert_true(size[j] != spv::NoResult); - id_vector_temp_.push_back(builder_->createBinOp( - spv::OpFDiv, type_float_, - builder_->createCompositeExtract(gradient_ref, - type_float_, j), - size[j])); - builder_->addDecoration(id_vector_temp_.back(), - spv::DecorationNoContraction); + id_vector_temp_.push_back( + builder_->createNoContractionBinOp( + spv::OpFDiv, type_float_, + builder_->createCompositeExtract(gradient_ref, + type_float_, j), + size[j])); } gradient_ref = builder_->createCompositeConstruct( type_float3_, id_vector_temp_); @@ -1775,16 +1724,12 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( builder_->createUnaryOp(spv::OpDPdyCoarse, type_float3_, gradient_coordinate_vector); } - gradients_h = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_, - gradients_h, lod_gradient_scale); - builder_->addDecoration(gradients_h, - spv::DecorationNoContraction); - gradients_v = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_, - gradients_v, lod_gradient_scale); - builder_->addDecoration(gradients_v, - spv::DecorationNoContraction); + gradients_h = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, gradients_h, + lod_gradient_scale); + gradients_v = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, gradients_v, + lod_gradient_scale); } break; case xenos::FetchOpDimension::kCube: { if (instr.attributes.use_register_gradients) { @@ -1812,16 +1757,12 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( builder_->createUnaryOp(spv::OpDPdyCoarse, type_float3_, gradient_coordinate_vector); } - gradients_h = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_, - gradients_h, lod_gradient_scale); - builder_->addDecoration(gradients_h, - spv::DecorationNoContraction); - gradients_v = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_, - gradients_v, lod_gradient_scale); - builder_->addDecoration(gradients_v, - spv::DecorationNoContraction); + gradients_h = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, gradients_h, + lod_gradient_scale); + gradients_v = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, gradients_v, + lod_gradient_scale); } break; } } @@ -1911,10 +1852,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( if (!instr.attributes.unnormalized_coordinates) { // Denormalize the gradient if provided as normalized. assert_true(size[2] != spv::NoResult); - layer_max_gradient = builder_->createBinOp( + layer_max_gradient = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, layer_max_gradient, size[2]); - builder_->addDecoration(layer_max_gradient, - spv::DecorationNoContraction); } // For NaN, considering that magnification is being done. spv::Id is_minifying_z = builder_->createBinOp( @@ -1971,20 +1910,16 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( // If the filter is linear, subtract 0.5 from the Z coordinate of the // first layer in filtering because 0.5 is in the middle of it. if (vol_filter_is_linear != spv::NoResult) { - spv::Id layer_coordinate_linear = builder_->createBinOp( - spv::OpFSub, type_float_, layer_coordinate, - builder_->makeFloatConstant(0.5f)); - builder_->addDecoration(layer_coordinate_linear, - spv::DecorationNoContraction); layer_coordinate = builder_->createTriOp( spv::OpSelect, type_float_, vol_filter_is_linear, - layer_coordinate_linear, layer_coordinate); + builder_->createNoContractionBinOp( + spv::OpFSub, type_float_, layer_coordinate, + builder_->makeFloatConstant(0.5f)), + layer_coordinate); } else if (vol_mag_filter_is_linear) { - layer_coordinate = builder_->createBinOp( + layer_coordinate = builder_->createNoContractionBinOp( spv::OpFSub, type_float_, layer_coordinate, builder_->makeFloatConstant(0.5f)); - builder_->addDecoration(layer_coordinate, - spv::DecorationNoContraction); } // Sample the first layer, needed regardless of whether filtering is // needed. @@ -2324,16 +2259,14 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( // Unsigned biased. builder_->setBuildPoint(&block_sign_unsigned_biased); spv::Id sample_result_component_unsigned_biased = - builder_->createBinOp(spv::OpFMul, type_float_, - sample_result_component_unsigned, - const_float_2); - builder_->addDecoration(sample_result_component_unsigned_biased, - spv::DecorationNoContraction); - sample_result_component_unsigned_biased = builder_->createBinOp( - spv::OpFAdd, type_float_, - sample_result_component_unsigned_biased, const_float_minus_1); - builder_->addDecoration(sample_result_component_unsigned_biased, - spv::DecorationNoContraction); + builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, sample_result_component_unsigned, + const_float_2); + sample_result_component_unsigned_biased = + builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, + sample_result_component_unsigned_biased, + const_float_minus_1); builder_->createBranch(&block_sign_merge); // Gamma. builder_->setBuildPoint(&block_sign_gamma_start); @@ -2384,12 +2317,9 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( &result_component_index)) { result_remaining_components &= ~(UINT32_C(1) << result_component_index); - spv::Id& result_component_ref = result[result_component_index]; - result_component_ref = builder_->createBinOp( - spv::OpFMul, type_float_, result_component_ref, + result[result_component_index] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, result[result_component_index], result_exponent_bias); - builder_->addDecoration(result_component_ref, - spv::DecorationNoContraction); } } } @@ -2564,16 +2494,13 @@ void SpirvShaderTranslator::SampleTexture( if (lerp_factor != spv::NoResult) { spv::Id lerp_first = i ? lerp_first_signed : lerp_first_unsigned; if (lerp_first != spv::NoResult) { - spv::Id lerp_difference = builder_->createBinOp( - spv::OpFSub, type_float4_, result, lerp_first); - builder_->addDecoration(lerp_difference, spv::DecorationNoContraction); - lerp_difference = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float4_, - lerp_difference, lerp_factor); - builder_->addDecoration(lerp_difference, spv::DecorationNoContraction); - result = builder_->createBinOp(spv::OpFAdd, type_float4_, result, - lerp_difference); - builder_->addDecoration(result, spv::DecorationNoContraction); + spv::Id lerp_difference = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float4_, + builder_->createNoContractionBinOp(spv::OpFSub, type_float4_, + result, lerp_first), + lerp_factor); + result = builder_->createNoContractionBinOp(spv::OpFAdd, type_float4_, + result, lerp_difference); } } builder_->createBranch(&block_sign_merge); diff --git a/src/xenia/gpu/spirv_shader_translator_rb.cc b/src/xenia/gpu/spirv_shader_translator_rb.cc index 2c97dae4e..456478f62 100644 --- a/src/xenia/gpu/spirv_shader_translator_rb.cc +++ b/src/xenia/gpu/spirv_shader_translator_rb.cc @@ -835,13 +835,12 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() { builder_->makeIntConstant(kSystemConstantColorExpBias)); id_vector_temp_.push_back( builder_->makeIntConstant(int32_t(color_target_index))); - color = builder_->createBinOp( + color = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, type_float4_, color, builder_->createLoad(builder_->createAccessChain( spv::StorageClassUniform, uniform_system_constants_, id_vector_temp_), spv::NoPrecision)); - builder_->addDecoration(color, spv::DecorationNoContraction); if (edram_fragment_shader_interlock_) { // Write the color to the target in the EDRAM only it was written on the @@ -1967,20 +1966,16 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( spv::Id depth_max_slope = builder_->createBuiltinCall( type_float_, ext_inst_glsl_std_450_, GLSLstd450FMax, id_vector_temp_); // Calculate the polygon offset. - spv::Id slope_scaled_poly_offset = builder_->createBinOp( + spv::Id slope_scaled_poly_offset = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, poly_offset_scale, depth_max_slope); - builder_->addDecoration(slope_scaled_poly_offset, - spv::DecorationNoContraction); - spv::Id poly_offset = builder_->createBinOp( + spv::Id poly_offset = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, slope_scaled_poly_offset, poly_offset_offset); - builder_->addDecoration(poly_offset, spv::DecorationNoContraction); // Apply the post-clip and post-viewport polygon offset to the fragment's // depth. Not clamping yet as this is at the center, which is not necessarily // covered and not necessarily inside the bounds - derivatives scaled by // sample locations will be added to this value, and it must be linear. - spv::Id center_depth32_biased = builder_->createBinOp( + spv::Id center_depth32_biased = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, center_depth32_unbiased, poly_offset); - builder_->addDecoration(center_depth32_biased, spv::DecorationNoContraction); // Perform depth and stencil testing for each covered sample. spv::Id new_sample_mask = main_fsi_sample_mask_; @@ -2076,17 +2071,14 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( } std::array sample_depth_dxy; for (uint32_t j = 0; j < 2; ++j) { - sample_depth_dxy[j] = builder_->createBinOp( + sample_depth_dxy[j] = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, sample_location[j], depth_dxy[j]); - builder_->addDecoration(sample_depth_dxy[j], - spv::DecorationNoContraction); } - spv::Id sample_depth32 = builder_->createBinOp( - spv::OpFAdd, type_float_, sample_depth_dxy[0], sample_depth_dxy[1]); - builder_->addDecoration(sample_depth32, spv::DecorationNoContraction); - sample_depth32 = builder_->createBinOp( - spv::OpFAdd, type_float_, center_depth32_biased, sample_depth32); - builder_->addDecoration(sample_depth32, spv::DecorationNoContraction); + spv::Id sample_depth32 = builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, center_depth32_biased, + builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, + sample_depth_dxy[0], + sample_depth_dxy[1])); id_vector_temp_.clear(); id_vector_temp_.push_back(sample_depth32); id_vector_temp_.push_back(const_float_0_); @@ -2114,11 +2106,9 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( // conversion, adding +0.5 and rounding towards zero results in red instead // of black in the 4D5307E6 clear shader. id_vector_temp_.clear(); - id_vector_temp_.push_back( - builder_->createBinOp(spv::OpFMul, type_float_, sample_depth32, - builder_->makeFloatConstant(float(0xFFFFFF)))); - builder_->addDecoration(id_vector_temp_.back(), - spv::DecorationNoContraction); + id_vector_temp_.push_back(builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, sample_depth32, + builder_->makeFloatConstant(float(0xFFFFFF)))); spv::Id sample_depth_unorm24 = builder_->createUnaryOp( spv::OpConvertFToU, type_uint_, builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, @@ -2582,15 +2572,13 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( id_vector_temp_.push_back(color_float4); id_vector_temp_.push_back(const_float4_0_); id_vector_temp_.push_back(const_float4_1_); - spv::Id color_scaled = builder_->createBinOp( + spv::Id color_scaled = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, type_float4_, builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_, GLSLstd450NClamp, id_vector_temp_), builder_->makeFloatConstant(255.0f)); - builder_->addDecoration(color_scaled, spv::DecorationNoContraction); - spv::Id color_offset = builder_->createBinOp( + spv::Id color_offset = builder_->createNoContractionBinOp( spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); - builder_->addDecoration(color_offset, spv::DecorationNoContraction); spv::Id color_uint4 = builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset); packed_8_8_8_8 = @@ -2647,13 +2635,11 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( builder_->getBuildPoint()->addInstruction( std::move(color_gamma_composite_construct_op)); } - spv::Id color_scaled = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float4_, - color_gamma, builder_->makeFloatConstant(255.0f)); - builder_->addDecoration(color_scaled, spv::DecorationNoContraction); - spv::Id color_offset = builder_->createBinOp( + spv::Id color_scaled = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float4_, color_gamma, + builder_->makeFloatConstant(255.0f)); + spv::Id color_offset = builder_->createNoContractionBinOp( spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); - builder_->addDecoration(color_offset, spv::DecorationNoContraction); spv::Id color_uint4 = builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset); packed_8_8_8_8_gamma = @@ -2690,13 +2676,11 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( id_vector_temp_.clear(); id_vector_temp_.resize(3, builder_->makeFloatConstant(1023.0f)); id_vector_temp_.push_back(builder_->makeFloatConstant(3.0f)); - spv::Id color_scaled = builder_->createBinOp( + spv::Id color_scaled = builder_->createNoContractionBinOp( spv::OpFMul, type_float4_, color_clamped, builder_->makeCompositeConstant(type_float4_, id_vector_temp_)); - builder_->addDecoration(color_scaled, spv::DecorationNoContraction); - spv::Id color_offset = builder_->createBinOp( + spv::Id color_offset = builder_->createNoContractionBinOp( spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); - builder_->addDecoration(color_offset, spv::DecorationNoContraction); spv::Id color_uint4 = builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset); packed_2_10_10_10 = @@ -2738,15 +2722,13 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( builder_->createCompositeExtract(color_float4, type_float_, 3)); id_vector_temp_.push_back(const_float_0_); id_vector_temp_.push_back(const_float_1_); - spv::Id alpha_scaled = builder_->createBinOp( + spv::Id alpha_scaled = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, id_vector_temp_), builder_->makeFloatConstant(3.0f)); - builder_->addDecoration(alpha_scaled, spv::DecorationNoContraction); - spv::Id alpha_offset = builder_->createBinOp( + spv::Id alpha_offset = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, alpha_scaled, unorm_round_offset_float); - builder_->addDecoration(alpha_offset, spv::DecorationNoContraction); color_components[3] = builder_->createUnaryOp(spv::OpConvertFToU, type_uint_, alpha_offset); // Pack. @@ -2795,24 +2777,22 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( const_float4_0_, color_float4)); id_vector_temp_.push_back(const_float4_minus_32); id_vector_temp_.push_back(const_float4_32); - spv::Id color_scaled = builder_->createBinOp( + spv::Id color_scaled = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, type_float4_, builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_, GLSLstd450FClamp, id_vector_temp_), builder_->makeFloatConstant(32767.0f / 32.0f)); - builder_->addDecoration(color_scaled, spv::DecorationNoContraction); id_vector_temp_.clear(); id_vector_temp_.resize(4, builder_->makeFloatConstant(-0.5f)); spv::Id unorm_round_offset_negative_float4 = builder_->makeCompositeConstant(type_float4_, id_vector_temp_); - spv::Id color_offset = builder_->createBinOp( + spv::Id color_offset = builder_->createNoContractionBinOp( spv::OpFAdd, type_float4_, color_scaled, builder_->createTriOp( spv::OpSelect, type_float4_, builder_->createBinOp(spv::OpFOrdLessThan, type_bool4_, color_scaled, const_float4_0_), unorm_round_offset_negative_float4, unorm_round_offset_float4)); - builder_->addDecoration(color_offset, spv::DecorationNoContraction); spv::Id color_uint4 = builder_->createUnaryOp( spv::OpBitcast, type_uint4_, builder_->createUnaryOp(spv::OpConvertFToS, type_int4_, color_offset)); @@ -3028,7 +3008,7 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( builder_->setBuildPoint(i ? &block_format_8_8_8_8_gamma : &block_format_8_8_8_8); for (uint32_t j = 0; j < 4; ++j) { - spv::Id component = builder_->createBinOp( + spv::Id component = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, builder_->createUnaryOp( spv::OpConvertUToF, type_float_, @@ -3036,7 +3016,6 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( spv::OpBitFieldUExtract, type_uint_, color_packed[0], builder_->makeUintConstant(8 * j), component_width)), component_scale); - builder_->addDecoration(component, spv::DecorationNoContraction); if (i && j <= 2) { component = PWLGammaToLinear(component, true); } @@ -3060,7 +3039,7 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( spv::Id rgb_scale = builder_->makeFloatConstant(1.0f / 1023.0f); spv::Id alpha_scale = builder_->makeFloatConstant(1.0f / 3.0f); for (uint32_t i = 0; i < 4; ++i) { - spv::Id component = builder_->createBinOp( + unpacked_2_10_10_10[i] = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, builder_->createUnaryOp( spv::OpConvertUToF, type_float_, @@ -3069,8 +3048,6 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( builder_->makeUintConstant(10 * i), i == 3 ? alpha_width : rgb_width)), i == 3 ? alpha_scale : rgb_scale); - builder_->addDecoration(component, spv::DecorationNoContraction); - unpacked_2_10_10_10[i] = component; } builder_->createBranch(&block_format_merge); } @@ -3093,7 +3070,7 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( builder_->makeUintConstant(10 * i), rgb_width), 0, false, ext_inst_glsl_std_450_); } - spv::Id alpha = builder_->createBinOp( + unpacked_2_10_10_10_float[3] = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, builder_->createUnaryOp( spv::OpConvertUToF, type_float_, @@ -3101,8 +3078,6 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( spv::OpBitFieldUExtract, type_uint_, color_packed[0], builder_->makeUintConstant(30), builder_->makeUintConstant(2))), builder_->makeFloatConstant(1.0f / 3.0f)); - builder_->addDecoration(alpha, spv::DecorationNoContraction); - unpacked_2_10_10_10_float[3] = alpha; builder_->createBranch(&block_format_merge); } spv::Block& block_format_2_10_10_10_float_end = *builder_->getBuildPoint(); @@ -3129,7 +3104,7 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( builder_->createUnaryOp(spv::OpBitcast, type_int_, color_packed[j]); } for (uint32_t j = 0; j < uint32_t(i ? 4 : 2); ++j) { - spv::Id component = builder_->createBinOp( + spv::Id component = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, builder_->createUnaryOp( spv::OpConvertSToF, type_float_, @@ -3138,7 +3113,6 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( builder_->makeUintConstant(16 * (j & 1)), component_width)), component_scale); - builder_->addDecoration(component, spv::DecorationNoContraction); id_vector_temp_.clear(); id_vector_temp_.push_back(component_min); id_vector_temp_.push_back(component); @@ -3414,51 +3388,36 @@ spv::Id SpirvShaderTranslator::FSI_ApplyColorBlendFactor( // kSrc/Dst/ConstantColor { builder_->setBuildPoint(color_factor_blocks[i]); - spv::Id result_color = - builder_->createBinOp(spv::OpFMul, type_float3_, value, color_factor); - builder_->addDecoration(result_color, spv::DecorationNoContraction); - color_factor_results[i] = result_color; + color_factor_results[i] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float3_, value, color_factor); builder_->createBranch(&block_factor_merge); } // kOneMinusSrc/Dst/ConstantColor { builder_->setBuildPoint(one_minus_color_factor_blocks[i]); - spv::Id one_minus_color_factor = builder_->createBinOp( - spv::OpFSub, type_float3_, const_float3_1_, color_factor); - builder_->addDecoration(one_minus_color_factor, - spv::DecorationNoContraction); - spv::Id result_one_minus_color = builder_->createBinOp( - spv::OpFMul, type_float3_, value, one_minus_color_factor); - builder_->addDecoration(result_one_minus_color, - spv::DecorationNoContraction); - one_minus_color_factor_results[i] = result_one_minus_color; + one_minus_color_factor_results[i] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float3_, value, + builder_->createNoContractionBinOp(spv::OpFSub, type_float3_, + const_float3_1_, color_factor)); builder_->createBranch(&block_factor_merge); } // kSrc/Dst/ConstantAlpha { builder_->setBuildPoint(alpha_factor_blocks[i]); - spv::Id result_alpha = builder_->createBinOp( + alpha_factor_results[i] = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, type_float3_, value, alpha_factor); - builder_->addDecoration(result_alpha, spv::DecorationNoContraction); - alpha_factor_results[i] = result_alpha; builder_->createBranch(&block_factor_merge); } // kOneMinusSrc/Dst/ConstantAlpha { builder_->setBuildPoint(one_minus_alpha_factor_blocks[i]); - spv::Id one_minus_alpha_factor = builder_->createBinOp( - spv::OpFSub, type_float_, const_float_1_, alpha_factor); - builder_->addDecoration(one_minus_alpha_factor, - spv::DecorationNoContraction); - spv::Id result_one_minus_alpha = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_, value, - one_minus_alpha_factor); - builder_->addDecoration(result_one_minus_alpha, - spv::DecorationNoContraction); - one_minus_alpha_factor_results[i] = result_one_minus_alpha; + one_minus_alpha_factor_results[i] = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, value, + builder_->createNoContractionBinOp(spv::OpFSub, type_float_, + const_float_1_, alpha_factor)); builder_->createBranch(&block_factor_merge); } } @@ -3467,19 +3426,16 @@ spv::Id SpirvShaderTranslator::FSI_ApplyColorBlendFactor( spv::Id result_source_alpha_saturate; { builder_->setBuildPoint(&block_factor_source_alpha_saturate); - spv::Id one_minus_dest_alpha = builder_->createBinOp( + spv::Id one_minus_dest_alpha = builder_->createNoContractionBinOp( spv::OpFSub, type_float_, const_float_1_, dest_alpha); - builder_->addDecoration(one_minus_dest_alpha, spv::DecorationNoContraction); id_vector_temp_.clear(); id_vector_temp_.push_back(source_alpha); id_vector_temp_.push_back(one_minus_dest_alpha); spv::Id factor_source_alpha_saturate = builder_->createBuiltinCall( type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, id_vector_temp_); - result_source_alpha_saturate = - builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_, value, - factor_source_alpha_saturate); - builder_->addDecoration(result_source_alpha_saturate, - spv::DecorationNoContraction); + result_source_alpha_saturate = builder_->createNoContractionBinOp( + spv::OpVectorTimesScalar, type_float3_, value, + factor_source_alpha_saturate); builder_->createBranch(&block_factor_merge); } @@ -3629,25 +3585,18 @@ spv::Id SpirvShaderTranslator::FSI_ApplyAlphaBlendFactor( // kSrc/Dst/ConstantColor/Alpha { builder_->setBuildPoint(alpha_factor_blocks[i]); - spv::Id result_alpha = - builder_->createBinOp(spv::OpFMul, type_float_, value, alpha_factor); - builder_->addDecoration(result_alpha, spv::DecorationNoContraction); - alpha_factor_results[i] = result_alpha; + alpha_factor_results[i] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, value, alpha_factor); builder_->createBranch(&block_factor_merge); } // kOneMinusSrc/Dst/ConstantColor/Alpha { builder_->setBuildPoint(one_minus_alpha_factor_blocks[i]); - spv::Id one_minus_alpha_factor = builder_->createBinOp( - spv::OpFSub, type_float_, const_float_1_, alpha_factor); - builder_->addDecoration(one_minus_alpha_factor, - spv::DecorationNoContraction); - spv::Id result_one_minus_alpha = builder_->createBinOp( - spv::OpFMul, type_float_, value, one_minus_alpha_factor); - builder_->addDecoration(result_one_minus_alpha, - spv::DecorationNoContraction); - one_minus_alpha_factor_results[i] = result_one_minus_alpha; + one_minus_alpha_factor_results[i] = builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, value, + builder_->createNoContractionBinOp(spv::OpFSub, type_float_, + const_float_1_, alpha_factor)); builder_->createBranch(&block_factor_merge); } } @@ -3656,18 +3605,15 @@ spv::Id SpirvShaderTranslator::FSI_ApplyAlphaBlendFactor( spv::Id result_source_alpha_saturate; { builder_->setBuildPoint(&block_factor_source_alpha_saturate); - spv::Id one_minus_dest_alpha = builder_->createBinOp( + spv::Id one_minus_dest_alpha = builder_->createNoContractionBinOp( spv::OpFSub, type_float_, const_float_1_, dest_alpha); - builder_->addDecoration(one_minus_dest_alpha, spv::DecorationNoContraction); id_vector_temp_.clear(); id_vector_temp_.push_back(source_alpha); id_vector_temp_.push_back(one_minus_dest_alpha); spv::Id factor_source_alpha_saturate = builder_->createBuiltinCall( type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, id_vector_temp_); - result_source_alpha_saturate = builder_->createBinOp( + result_source_alpha_saturate = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, value, factor_source_alpha_saturate); - builder_->addDecoration(result_source_alpha_saturate, - spv::DecorationNoContraction); builder_->createBranch(&block_factor_merge); } @@ -3812,24 +3758,20 @@ spv::Id SpirvShaderTranslator::FSI_BlendColorOrAlphaWithUnclampedResult( // Addition case. builder_->setBuildPoint(&block_signs_add); - spv::Id result_add = - builder_->createBinOp(spv::OpFAdd, value_type, term_source, term_dest); - builder_->addDecoration(result_add, spv::DecorationNoContraction); + spv::Id result_add = builder_->createNoContractionBinOp( + spv::OpFAdd, value_type, term_source, term_dest); builder_->createBranch(&block_signs_merge); // Subtraction case. builder_->setBuildPoint(&block_signs_subtract); - spv::Id result_subtract = - builder_->createBinOp(spv::OpFSub, value_type, term_source, term_dest); - builder_->addDecoration(result_subtract, spv::DecorationNoContraction); + spv::Id result_subtract = builder_->createNoContractionBinOp( + spv::OpFSub, value_type, term_source, term_dest); builder_->createBranch(&block_signs_merge); // Reverse subtraction case. builder_->setBuildPoint(&block_signs_reverse_subtract); - spv::Id result_reverse_subtract = - builder_->createBinOp(spv::OpFSub, value_type, term_dest, term_source); - builder_->addDecoration(result_reverse_subtract, - spv::DecorationNoContraction); + spv::Id result_reverse_subtract = builder_->createNoContractionBinOp( + spv::OpFSub, value_type, term_dest, term_source); builder_->createBranch(&block_signs_merge); // Selection between the signs involved in the addition. diff --git a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc index 1909972b2..67aae26ed 100644 --- a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc @@ -1393,21 +1393,19 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { id_vector_temp.push_back(builder.makeIntConstant( int32_t(kPointConstantScreenDiameterToNdcRadius))); id_vector_temp.push_back(const_int_0); - spv::Id point_radius_x = builder.createBinOp( + spv::Id point_radius_x = builder.createNoContractionBinOp( spv::OpFMul, type_float, point_guest_diameter_x, builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, uniform_system_constants, id_vector_temp), spv::NoPrecision)); - builder.addDecoration(point_radius_x, spv::DecorationNoContraction); id_vector_temp.back() = const_int_1; - spv::Id point_radius_y = builder.createBinOp( + spv::Id point_radius_y = builder.createNoContractionBinOp( spv::OpFMul, type_float, point_guest_diameter_y, builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, uniform_system_constants, id_vector_temp), spv::NoPrecision)); - builder.addDecoration(point_radius_y, spv::DecorationNoContraction); id_vector_temp.clear(); // 0 is the input primitive vertex index. id_vector_temp.push_back(const_int_0); @@ -1418,12 +1416,10 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { spv::NoPrecision); spv::Id point_w = builder.createCompositeExtract(point_position, type_float, 3); - point_radius_x = - builder.createBinOp(spv::OpFMul, type_float, point_radius_x, point_w); - builder.addDecoration(point_radius_x, spv::DecorationNoContraction); - point_radius_y = - builder.createBinOp(spv::OpFMul, type_float, point_radius_y, point_w); - builder.addDecoration(point_radius_y, spv::DecorationNoContraction); + point_radius_x = builder.createNoContractionBinOp( + spv::OpFMul, type_float, point_radius_x, point_w); + point_radius_y = builder.createNoContractionBinOp( + spv::OpFMul, type_float, point_radius_y, point_w); // Load the inputs for the guest point. // Interpolators. @@ -1445,12 +1441,10 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { std::array point_edge_x, point_edge_y; for (uint32_t i = 0; i < 2; ++i) { spv::Op point_radius_add_op = i ? spv::OpFAdd : spv::OpFSub; - point_edge_x[i] = builder.createBinOp(point_radius_add_op, type_float, - point_x, point_radius_x); - builder.addDecoration(point_edge_x[i], spv::DecorationNoContraction); - point_edge_y[i] = builder.createBinOp(point_radius_add_op, type_float, - point_y, point_radius_y); - builder.addDecoration(point_edge_y[i], spv::DecorationNoContraction); + point_edge_x[i] = builder.createNoContractionBinOp( + point_radius_add_op, type_float, point_x, point_radius_x); + point_edge_y[i] = builder.createNoContractionBinOp( + point_radius_add_op, type_float, point_y, point_radius_y); }; spv::Id point_z = builder.createCompositeExtract(point_position, type_float, 2); @@ -1699,24 +1693,20 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { id_vector_temp), spv::NoPrecision); id_vector_temp[0] = vertex_indices[1]; - spv::Id vertex_interpolator_v01 = builder.createBinOp( + spv::Id vertex_interpolator_v01 = builder.createNoContractionBinOp( spv::OpFSub, type_float4, builder.createLoad( builder.createAccessChain(spv::StorageClassInput, in_interpolator, id_vector_temp), spv::NoPrecision), vertex_interpolator_v0); - builder.addDecoration(vertex_interpolator_v01, - spv::DecorationNoContraction); id_vector_temp[0] = vertex_indices[2]; - spv::Id vertex_interpolator_v3 = builder.createBinOp( + spv::Id vertex_interpolator_v3 = builder.createNoContractionBinOp( spv::OpFAdd, type_float4, vertex_interpolator_v01, builder.createLoad( builder.createAccessChain(spv::StorageClassInput, in_interpolator, id_vector_temp), spv::NoPrecision)); - builder.addDecoration(vertex_interpolator_v3, - spv::DecorationNoContraction); builder.createStore(vertex_interpolator_v3, out_interpolators[i]); } // Point coordinates. @@ -1733,22 +1723,20 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { id_vector_temp), spv::NoPrecision); id_vector_temp[0] = vertex_indices[1]; - spv::Id vertex_position_v01 = builder.createBinOp( + spv::Id vertex_position_v01 = builder.createNoContractionBinOp( spv::OpFSub, type_float4, builder.createLoad( builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), spv::NoPrecision), vertex_position_v0); - builder.addDecoration(vertex_position_v01, spv::DecorationNoContraction); id_vector_temp[0] = vertex_indices[2]; - spv::Id vertex_position_v3 = builder.createBinOp( + spv::Id vertex_position_v3 = builder.createNoContractionBinOp( spv::OpFAdd, type_float4, vertex_position_v01, builder.createLoad( builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), spv::NoPrecision)); - builder.addDecoration(vertex_position_v3, spv::DecorationNoContraction); id_vector_temp.clear(); id_vector_temp.push_back(const_member_out_gl_per_vertex_position); builder.createStore( @@ -1767,24 +1755,20 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) { id_vector_temp), spv::NoPrecision); id_vector_temp[0] = vertex_indices[1]; - spv::Id vertex_clip_distance_v01 = builder.createBinOp( + spv::Id vertex_clip_distance_v01 = builder.createNoContractionBinOp( spv::OpFSub, type_float, builder.createLoad( builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), spv::NoPrecision), vertex_clip_distance_v0); - builder.addDecoration(vertex_clip_distance_v01, - spv::DecorationNoContraction); id_vector_temp[0] = vertex_indices[2]; - spv::Id vertex_clip_distance_v3 = builder.createBinOp( + spv::Id vertex_clip_distance_v3 = builder.createNoContractionBinOp( spv::OpFAdd, type_float, vertex_clip_distance_v01, builder.createLoad( builder.createAccessChain(spv::StorageClassInput, in_gl_per_vertex, id_vector_temp), spv::NoPrecision)); - builder.addDecoration(vertex_clip_distance_v3, - spv::DecorationNoContraction); id_vector_temp.clear(); id_vector_temp.push_back(const_member_in_gl_per_vertex_clip_distance); id_vector_temp.push_back(const_int_i); From 8aaa6f1f7deab5ad949e03bd76b16b2530fa7aec Mon Sep 17 00:00:00 2001 From: Triang3l Date: Wed, 19 Apr 2023 21:44:24 +0300 Subject: [PATCH 5/5] [SPIR-V] Wrap 4-operand ops and 1-3-operand GLSL std calls --- src/xenia/gpu/spirv_builder.cc | 105 +++ src/xenia/gpu/spirv_builder.h | 25 +- src/xenia/gpu/spirv_shader_translator.cc | 160 ++-- src/xenia/gpu/spirv_shader_translator_alu.cc | 146 ++-- .../gpu/spirv_shader_translator_fetch.cc | 93 +- src/xenia/gpu/spirv_shader_translator_rb.cc | 348 +++----- .../gpu/vulkan/vulkan_render_target_cache.cc | 791 +++++++----------- 7 files changed, 721 insertions(+), 947 deletions(-) create mode 100644 src/xenia/gpu/spirv_builder.cc diff --git a/src/xenia/gpu/spirv_builder.cc b/src/xenia/gpu/spirv_builder.cc new file mode 100644 index 000000000..2ba9446bc --- /dev/null +++ b/src/xenia/gpu/spirv_builder.cc @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2023 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "xenia/gpu/spirv_builder.h" + +#include +#include +#include + +namespace xe { +namespace gpu { + +spv::Id SpirvBuilder::createQuadOp(spv::Op op_code, spv::Id type_id, + spv::Id operand1, spv::Id operand2, + spv::Id operand3, spv::Id operand4) { + if (generatingOpCodeForSpecConst) { + std::vector operands(4); + operands[0] = operand1; + operands[1] = operand2; + operands[2] = operand3; + operands[3] = operand4; + return createSpecConstantOp(op_code, type_id, operands, + std::vector()); + } + std::unique_ptr op = + std::make_unique(getUniqueId(), type_id, op_code); + op->addIdOperand(operand1); + op->addIdOperand(operand2); + op->addIdOperand(operand3); + op->addIdOperand(operand4); + spv::Id result = op->getResultId(); + buildPoint->addInstruction(std::move(op)); + return result; +} + +spv::Id SpirvBuilder::createNoContractionUnaryOp(spv::Op op_code, + spv::Id type_id, + spv::Id operand) { + spv::Id result = createUnaryOp(op_code, type_id, operand); + addDecoration(result, spv::DecorationNoContraction); + return result; +} + +spv::Id SpirvBuilder::createNoContractionBinOp(spv::Op op_code, spv::Id type_id, + spv::Id operand1, + spv::Id operand2) { + spv::Id result = createBinOp(op_code, type_id, operand1, operand2); + addDecoration(result, spv::DecorationNoContraction); + return result; +} + +spv::Id SpirvBuilder::createUnaryBuiltinCall(spv::Id result_type, + spv::Id builtins, int entry_point, + spv::Id operand) { + std::unique_ptr instruction = + std::make_unique(getUniqueId(), result_type, + spv::OpExtInst); + instruction->addIdOperand(builtins); + instruction->addImmediateOperand(entry_point); + instruction->addIdOperand(operand); + spv::Id result = instruction->getResultId(); + getBuildPoint()->addInstruction(std::move(instruction)); + return result; +} + +spv::Id SpirvBuilder::createBinBuiltinCall(spv::Id result_type, + spv::Id builtins, int entry_point, + spv::Id operand1, spv::Id operand2) { + std::unique_ptr instruction = + std::make_unique(getUniqueId(), result_type, + spv::OpExtInst); + instruction->addIdOperand(builtins); + instruction->addImmediateOperand(entry_point); + instruction->addIdOperand(operand1); + instruction->addIdOperand(operand2); + spv::Id result = instruction->getResultId(); + getBuildPoint()->addInstruction(std::move(instruction)); + return result; +} + +spv::Id SpirvBuilder::createTriBuiltinCall(spv::Id result_type, + spv::Id builtins, int entry_point, + spv::Id operand1, spv::Id operand2, + spv::Id operand3) { + std::unique_ptr instruction = + std::make_unique(getUniqueId(), result_type, + spv::OpExtInst); + instruction->addIdOperand(builtins); + instruction->addImmediateOperand(entry_point); + instruction->addIdOperand(operand1); + instruction->addIdOperand(operand2); + instruction->addIdOperand(operand3); + spv::Id result = instruction->getResultId(); + getBuildPoint()->addInstruction(std::move(instruction)); + return result; +} + +} // namespace gpu +} // namespace xe diff --git a/src/xenia/gpu/spirv_builder.h b/src/xenia/gpu/spirv_builder.h index 83e9a982f..0496aa7c4 100644 --- a/src/xenia/gpu/spirv_builder.h +++ b/src/xenia/gpu/spirv_builder.h @@ -26,19 +26,22 @@ class SpirvBuilder : public spv::Builder { // Make public rather than protected. using spv::Builder::createSelectionMerge; - spv::Id createNoContractionUnaryOp(spv::Op op_code, spv::Id type_id, - spv::Id operand) { - spv::Id result = createUnaryOp(op_code, type_id, operand); - addDecoration(result, spv::DecorationNoContraction); - return result; - } + spv::Id createQuadOp(spv::Op op_code, spv::Id type_id, spv::Id operand1, + spv::Id operand2, spv::Id operand3, spv::Id operand4); + spv::Id createNoContractionUnaryOp(spv::Op op_code, spv::Id type_id, + spv::Id operand); spv::Id createNoContractionBinOp(spv::Op op_code, spv::Id type_id, - spv::Id operand1, spv::Id operand2) { - spv::Id result = createBinOp(op_code, type_id, operand1, operand2); - addDecoration(result, spv::DecorationNoContraction); - return result; - } + spv::Id operand1, spv::Id operand2); + + spv::Id createUnaryBuiltinCall(spv::Id result_type, spv::Id builtins, + int entry_point, spv::Id operand); + spv::Id createBinBuiltinCall(spv::Id result_type, spv::Id builtins, + int entry_point, spv::Id operand1, + spv::Id operand2); + spv::Id createTriBuiltinCall(spv::Id result_type, spv::Id builtins, + int entry_point, spv::Id operand1, + spv::Id operand2, spv::Id operand3); }; } // namespace gpu diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc index 878896402..1f496082c 100644 --- a/src/xenia/gpu/spirv_shader_translator.cc +++ b/src/xenia/gpu/spirv_shader_translator.cc @@ -2037,19 +2037,15 @@ void SpirvShaderTranslator::StartFragmentShaderInMain() { assert_true(input_fragment_coordinates_ != spv::NoResult); id_vector_temp_.clear(); id_vector_temp_.push_back(const_int_0_); - spv::Id param_gen_x = - builder_->createLoad(builder_->createAccessChain( - spv::StorageClassInput, - input_fragment_coordinates_, id_vector_temp_), - spv::NoPrecision); - id_vector_temp_.clear(); - id_vector_temp_.push_back(param_gen_x); - param_gen_x = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, id_vector_temp_); - id_vector_temp_.clear(); - id_vector_temp_.push_back(param_gen_x); - param_gen_x = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, id_vector_temp_); + spv::Id param_gen_x = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, + builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, + input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision))); if (!modification.pixel.param_gen_point) { assert_true(input_front_facing_ != spv::NoResult); param_gen_x = builder_->createTriOp( @@ -2076,19 +2072,15 @@ void SpirvShaderTranslator::StartFragmentShaderInMain() { // Y - pixel Y .0 in the magnitude, is point in the sign bit. id_vector_temp_.clear(); id_vector_temp_.push_back(builder_->makeIntConstant(1)); - spv::Id param_gen_y = - builder_->createLoad(builder_->createAccessChain( - spv::StorageClassInput, - input_fragment_coordinates_, id_vector_temp_), - spv::NoPrecision); - id_vector_temp_.clear(); - id_vector_temp_.push_back(param_gen_y); - param_gen_y = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, id_vector_temp_); - id_vector_temp_.clear(); - id_vector_temp_.push_back(param_gen_y); - param_gen_y = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, id_vector_temp_); + spv::Id param_gen_y = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, + builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, + builder_->createLoad( + builder_->createAccessChain(spv::StorageClassInput, + input_fragment_coordinates_, + id_vector_temp_), + spv::NoPrecision))); if (modification.pixel.param_gen_point) { param_gen_y = builder_->createUnaryOp( spv::OpBitcast, type_float_, @@ -2104,14 +2096,10 @@ void SpirvShaderTranslator::StartFragmentShaderInMain() { assert_true(input_point_coordinates_ != spv::NoResult); // Saturate to avoid negative point coordinates if the center of the pixel // is not covered, and extrapolation is done. - id_vector_temp_.clear(); - id_vector_temp_.push_back( - builder_->createLoad(input_point_coordinates_, spv::NoPrecision)); - id_vector_temp_.push_back(const_float2_0_); - id_vector_temp_.push_back(const_float2_1_); - spv::Id param_gen_point_coordinates = - builder_->createBuiltinCall(type_float2_, ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_); + spv::Id param_gen_point_coordinates = builder_->createTriBuiltinCall( + type_float2_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createLoad(input_point_coordinates_, spv::NoPrecision), + const_float2_0_, const_float2_1_); param_gen_z = builder_->createCompositeExtract( param_gen_point_coordinates, type_float_, 0); param_gen_w = builder_->createCompositeExtract( @@ -2397,10 +2385,8 @@ spv::Id SpirvShaderTranslator::ApplyOperandModifiers( } if (original_operand.is_absolute_value || force_absolute) { EnsureBuildPointAvailable(); - id_vector_temp_util_.clear(); - id_vector_temp_util_.push_back(operand_value); - operand_value = builder_->createBuiltinCall( - type, ext_inst_glsl_std_450_, GLSLstd450FAbs, id_vector_temp_util_); + operand_value = builder_->createUnaryBuiltinCall( + type, ext_inst_glsl_std_450_, GLSLstd450FAbs, operand_value); } if (original_operand.is_negated != invert_negate) { EnsureBuildPointAvailable(); @@ -2464,11 +2450,9 @@ spv::Id SpirvShaderTranslator::GetAbsoluteOperand( return operand_storage; } EnsureBuildPointAvailable(); - id_vector_temp_util_.clear(); - id_vector_temp_util_.push_back(operand_storage); - return builder_->createBuiltinCall(builder_->getTypeId(operand_storage), - ext_inst_glsl_std_450_, GLSLstd450FAbs, - id_vector_temp_util_); + return builder_->createUnaryBuiltinCall(builder_->getTypeId(operand_storage), + ext_inst_glsl_std_450_, + GLSLstd450FAbs, operand_storage); } void SpirvShaderTranslator::StoreResult(const InstructionResult& result, @@ -2557,15 +2541,11 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result, if (result.is_clamped && non_constant_components) { // Apply the saturation modifier to the result. - id_vector_temp_util_.clear(); - id_vector_temp_util_.push_back(value); - id_vector_temp_util_.push_back( - const_float_vectors_0_[value_num_components - 1]); - id_vector_temp_util_.push_back( - const_float_vectors_1_[value_num_components - 1]); - value = builder_->createBuiltinCall( + value = builder_->createTriBuiltinCall( type_float_vectors_[value_num_components - 1], ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_util_); + GLSLstd450NClamp, value, + const_float_vectors_0_[value_num_components - 1], + const_float_vectors_1_[value_num_components - 1]); } // The value contains either result.GetUsedResultComponents() in a condensed @@ -2783,12 +2763,9 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result, uniform_system_constants_, id_vector_temp_util_), spv::NoPrecision)); - id_vector_temp_util_.clear(); - id_vector_temp_util_.push_back(point_vertex_diameter_min); - id_vector_temp_util_.push_back(point_size); - point_size = - builder_->createBuiltinCall(type_int_, ext_inst_glsl_std_450_, - GLSLstd450SMax, id_vector_temp_util_); + point_size = builder_->createBinBuiltinCall( + type_int_, ext_inst_glsl_std_450_, GLSLstd450SMax, + point_vertex_diameter_min, point_size); id_vector_temp_util_.clear(); id_vector_temp_util_.push_back( builder_->makeIntConstant(kSystemConstantPointVertexDiameterMax)); @@ -2799,12 +2776,9 @@ void SpirvShaderTranslator::StoreResult(const InstructionResult& result, uniform_system_constants_, id_vector_temp_util_), spv::NoPrecision)); - id_vector_temp_util_.clear(); - id_vector_temp_util_.push_back(point_vertex_diameter_max); - id_vector_temp_util_.push_back(point_size); - point_size = - builder_->createBuiltinCall(type_int_, ext_inst_glsl_std_450_, - GLSLstd450SMin, id_vector_temp_util_); + point_size = builder_->createBinBuiltinCall( + type_int_, ext_inst_glsl_std_450_, GLSLstd450SMin, + point_vertex_diameter_max, point_size); value_to_store = builder_->createCompositeInsert( builder_->createUnaryOp(spv::OpBitcast, type_float_, point_size), value_to_store, type_float3_, 0); @@ -2902,14 +2876,11 @@ spv::Id SpirvShaderTranslator::EndianSwap32Uint(spv::Id value, spv::Id endian) { builder_->createConditionalBranch(is_8in32_or_16in32, &block_16in32, &block_16in32_merge); builder_->setBuildPoint(&block_16in32); - id_vector_temp_.clear(); - id_vector_temp_.push_back(builder_->createBinOp( - spv::OpShiftRightLogical, type, value, const_uint_16_typed)); - id_vector_temp_.push_back(value); - id_vector_temp_.insert(id_vector_temp_.cend(), 2, - builder_->makeIntConstant(16)); - spv::Id swapped_16in32 = - builder_->createOp(spv::OpBitFieldInsert, type, id_vector_temp_); + spv::Id swapped_16in32 = builder_->createQuadOp( + spv::OpBitFieldInsert, type, + builder_->createBinOp(spv::OpShiftRightLogical, type, value, + const_uint_16_typed), + value, builder_->makeIntConstant(16), builder_->makeIntConstant(16)); builder_->createBranch(&block_16in32_merge); builder_->setBuildPoint(&block_16in32_merge); { @@ -3021,12 +2992,9 @@ spv::Id SpirvShaderTranslator::PWLGammaToLinear(spv::Id gamma, if (!gamma_pre_saturated) { // Saturate, flushing NaN to 0. - id_vector_temp_.clear(); - id_vector_temp_.push_back(gamma); - id_vector_temp_.push_back(const_vector_0); - id_vector_temp_.push_back(const_vector_1); - gamma = builder_->createBuiltinCall(value_type, ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_); + gamma = builder_->createTriBuiltinCall(value_type, ext_inst_glsl_std_450_, + GLSLstd450NClamp, gamma, + const_vector_0, const_vector_1); } spv::Id is_piece_at_least_3 = builder_->createBinOp( @@ -3086,14 +3054,12 @@ spv::Id SpirvShaderTranslator::PWLGammaToLinear(spv::Id gamma, scale), offset); // linear += trunc(linear * scale) - spv::Id linear_integer_term = builder_->createNoContractionBinOp( - spv::OpFMul, value_type, linear, scale); - id_vector_temp_.clear(); - id_vector_temp_.push_back(linear_integer_term); - linear_integer_term = builder_->createBuiltinCall( - value_type, ext_inst_glsl_std_450_, GLSLstd450Trunc, id_vector_temp_); - linear = builder_->createNoContractionBinOp(spv::OpFAdd, value_type, linear, - linear_integer_term); + linear = builder_->createNoContractionBinOp( + spv::OpFAdd, value_type, linear, + builder_->createUnaryBuiltinCall( + value_type, ext_inst_glsl_std_450_, GLSLstd450Trunc, + builder_->createNoContractionBinOp(spv::OpFMul, value_type, linear, + scale))); // linear *= 1.0f / 1023.0f linear = builder_->createNoContractionBinOp( value_times_scalar_opcode, value_type, linear, @@ -3117,12 +3083,9 @@ spv::Id SpirvShaderTranslator::LinearToPWLGamma(spv::Id linear, if (!linear_pre_saturated) { // Saturate, flushing NaN to 0. - id_vector_temp_.clear(); - id_vector_temp_.push_back(linear); - id_vector_temp_.push_back(const_vector_0); - id_vector_temp_.push_back(const_vector_1); - linear = builder_->createBuiltinCall(value_type, ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_); + linear = builder_->createTriBuiltinCall(value_type, ext_inst_glsl_std_450_, + GLSLstd450NClamp, linear, + const_vector_0, const_vector_1); } spv::Id is_piece_at_least_3 = builder_->createBinOp( @@ -3170,19 +3133,16 @@ spv::Id SpirvShaderTranslator::LinearToPWLGamma(spv::Id linear, offset_3_or_2, offset_1_or_0); // gamma = trunc(linear * scale) * (1.0f / 255.0f) + offset - spv::Id gamma = builder_->createNoContractionBinOp(spv::OpFMul, value_type, - linear, scale); - id_vector_temp_.clear(); - id_vector_temp_.push_back(gamma); - gamma = builder_->createBuiltinCall(value_type, ext_inst_glsl_std_450_, - GLSLstd450Trunc, id_vector_temp_); - gamma = builder_->createNoContractionBinOp( + return builder_->createNoContractionBinOp( spv::OpFAdd, value_type, builder_->createNoContractionBinOp( - is_vector ? spv::OpVectorTimesScalar : spv::OpFMul, value_type, gamma, + is_vector ? spv::OpVectorTimesScalar : spv::OpFMul, value_type, + builder_->createUnaryBuiltinCall( + value_type, ext_inst_glsl_std_450_, GLSLstd450Trunc, + builder_->createNoContractionBinOp(spv::OpFMul, value_type, + linear, scale)), builder_->makeFloatConstant(1.0f / 255.0f)), offset); - return gamma; } } // namespace gpu diff --git a/src/xenia/gpu/spirv_shader_translator_alu.cc b/src/xenia/gpu/spirv_shader_translator_alu.cc index 0c4c3626e..47978dd00 100644 --- a/src/xenia/gpu/spirv_shader_translator_alu.cc +++ b/src/xenia/gpu/spirv_shader_translator_alu.cc @@ -28,16 +28,13 @@ spv::Id SpirvShaderTranslator::ZeroIfAnyOperandIsZero(spv::Id value, int num_components = builder_->getNumComponents(value); assert_true(builder_->getNumComponents(operand_0_abs) == num_components); assert_true(builder_->getNumComponents(operand_1_abs) == num_components); - id_vector_temp_util_.clear(); - id_vector_temp_util_.push_back(operand_0_abs); - id_vector_temp_util_.push_back(operand_1_abs); return builder_->createTriOp( spv::OpSelect, type_float_, builder_->createBinOp( spv::OpFOrdEqual, type_bool_vectors_[num_components - 1], - builder_->createBuiltinCall(type_float_vectors_[num_components - 1], - ext_inst_glsl_std_450_, GLSLstd450NMin, - id_vector_temp_util_), + builder_->createBinBuiltinCall( + type_float_vectors_[num_components - 1], ext_inst_glsl_std_450_, + GLSLstd450NMin, operand_0_abs, operand_1_abs), const_float_vectors_0_[num_components - 1]), const_float_vectors_0_[num_components - 1], value); } @@ -252,15 +249,12 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( different_operands[i] = GetAbsoluteOperand(different_operands[i], instr.vector_operands[i]); } - id_vector_temp_.clear(); - id_vector_temp_.push_back(different_operands[0]); - id_vector_temp_.push_back(different_operands[1]); - spv::Id different_abs_min = - builder_->createBuiltinCall(different_type, ext_inst_glsl_std_450_, - GLSLstd450NMin, id_vector_temp_); spv::Id different_zero = builder_->createBinOp( spv::OpFOrdEqual, type_bool_vectors_[different_count - 1], - different_abs_min, const_float_vectors_0_[different_count - 1]); + builder_->createBinBuiltinCall( + different_type, ext_inst_glsl_std_450_, GLSLstd450NMin, + different_operands[0], different_operands[1]), + const_float_vectors_0_[different_count - 1]); // Replace with +0. different_result = builder_->createTriOp( spv::OpSelect, different_type, different_zero, @@ -325,23 +319,18 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( } else { maxa_operand_0_w = operand_0; } - spv::Id maxa_address = builder_->createNoContractionBinOp( - spv::OpFAdd, type_float_, maxa_operand_0_w, - builder_->makeFloatConstant(0.5f)); - id_vector_temp_.clear(); - id_vector_temp_.push_back(maxa_address); - maxa_address = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450Floor, id_vector_temp_); - id_vector_temp_.clear(); - id_vector_temp_.push_back(maxa_address); - id_vector_temp_.push_back(builder_->makeFloatConstant(-256.0f)); - id_vector_temp_.push_back(builder_->makeFloatConstant(255.0f)); builder_->createStore( builder_->createUnaryOp( spv::OpConvertFToS, type_int_, - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_)), + builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, + builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, maxa_operand_0_w, + builder_->makeFloatConstant(0.5f))), + builder_->makeFloatConstant(-256.0f), + builder_->makeFloatConstant(255.0f))), var_main_address_register_); } if (!used_result_components) { @@ -455,13 +444,11 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( case ucode::AluVectorOpcode::kFrc: case ucode::AluVectorOpcode::kTrunc: case ucode::AluVectorOpcode::kFloor: - id_vector_temp_.clear(); - id_vector_temp_.push_back(GetOperandComponents(operand_storage[0], - instr.vector_operands[0], - used_result_components)); - return builder_->createBuiltinCall( + return builder_->createUnaryBuiltinCall( result_type, ext_inst_glsl_std_450_, - GLSLstd450(kOps[size_t(instr.vector_opcode)]), id_vector_temp_); + GLSLstd450(kOps[size_t(instr.vector_opcode)]), + GetOperandComponents(operand_storage[0], instr.vector_operands[0], + used_result_components)); case ucode::AluVectorOpcode::kCndEq: case ucode::AluVectorOpcode::kCndGe: @@ -553,11 +540,8 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( if (!instr.vector_operands[0].is_absolute_value || instr.vector_operands[0].is_negated) { for (unsigned int i = 0; i < 3; ++i) { - id_vector_temp_.clear(); - id_vector_temp_.push_back(operand[i]); - operand_abs[i] = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450FAbs, id_vector_temp_); + operand_abs[i] = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, operand[i]); } } else { for (unsigned int i = 0; i < 3; ++i) { @@ -749,13 +733,10 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation( operand, type_float_, static_cast(component)); while (xe::bit_scan_forward(components_remaining, &component)) { components_remaining &= ~(uint32_t(1) << component); - id_vector_temp_.clear(); - id_vector_temp_.push_back(result); - id_vector_temp_.push_back(builder_->createCompositeExtract( - operand, type_float_, static_cast(component))); - result = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450NMax, id_vector_temp_); + result = builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NMax, result, + builder_->createCompositeExtract( + operand, type_float_, static_cast(component))); } return result; } @@ -1014,12 +995,10 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( spv::Id result = builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, ps); // Shader Model 3: +0 or denormal * anything = +-0. - id_vector_temp_.clear(); - id_vector_temp_.push_back(ps); return ZeroIfAnyOperandIsZero( result, GetAbsoluteOperand(a, instr.scalar_operands[0]), - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450FAbs, id_vector_temp_)); + builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450FAbs, ps)); } case ucode::AluScalarOpcode::kMulsPrev2: { // Check if need to select the src0.a * ps case. @@ -1033,10 +1012,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( spv::OpFUnordNotEqual, type_bool_, ps, const_float_max_neg); // isfinite(ps), or |ps| <= FLT_MAX, or -|ps| >= -FLT_MAX, since -FLT_MAX // is already loaded to an SGPR, this is also false if it's NaN. - id_vector_temp_.clear(); - id_vector_temp_.push_back(ps); - spv::Id ps_abs = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, id_vector_temp_); + spv::Id ps_abs = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, ps); spv::Id ps_abs_neg = builder_->createNoContractionUnaryOp( spv::OpFNegate, type_float_, ps_abs); condition = builder_->createBinOp( @@ -1048,11 +1025,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( instr.scalar_operands[0], 0b0010); spv::Id b_abs_neg = b; if (!instr.scalar_operands[0].is_absolute_value) { - id_vector_temp_.clear(); - id_vector_temp_.push_back(b_abs_neg); - b_abs_neg = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450FAbs, id_vector_temp_); + b_abs_neg = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, b_abs_neg); } if (!instr.scalar_operands[0].is_absolute_value || !instr.scalar_operands[0].is_negated) { @@ -1120,20 +1094,16 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( } else { maxa_address = a; } - id_vector_temp_.clear(); - id_vector_temp_.push_back(maxa_address); - maxa_address = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450Floor, id_vector_temp_); - id_vector_temp_.clear(); - id_vector_temp_.push_back(maxa_address); - id_vector_temp_.push_back(builder_->makeFloatConstant(-256.0f)); - id_vector_temp_.push_back(builder_->makeFloatConstant(255.0f)); builder_->createStore( builder_->createUnaryOp( spv::OpConvertFToS, type_int_, - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_)), + builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, + maxa_address), + builder_->makeFloatConstant(-256.0f), + builder_->makeFloatConstant(255.0f))), var_main_address_register_); } if (a == b) { @@ -1171,18 +1141,16 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( case ucode::AluScalarOpcode::kSqrt: case ucode::AluScalarOpcode::kSin: case ucode::AluScalarOpcode::kCos: - id_vector_temp_.clear(); - id_vector_temp_.push_back(GetOperandComponents( - operand_storage[0], instr.scalar_operands[0], 0b0001)); - return builder_->createBuiltinCall( + return builder_->createUnaryBuiltinCall( type_float_, ext_inst_glsl_std_450_, - GLSLstd450(kOps[size_t(instr.scalar_opcode)]), id_vector_temp_); + GLSLstd450(kOps[size_t(instr.scalar_opcode)]), + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], + 0b0001)); case ucode::AluScalarOpcode::kLogc: { - id_vector_temp_.clear(); - id_vector_temp_.push_back(GetOperandComponents( - operand_storage[0], instr.scalar_operands[0], 0b0001)); - spv::Id result = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450Log2, id_vector_temp_); + spv::Id result = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Log2, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], + 0b0001)); return builder_->createTriOp( spv::OpSelect, type_float_, builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, @@ -1232,12 +1200,10 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( 0b0001)); } case ucode::AluScalarOpcode::kRsqc: { - id_vector_temp_.clear(); - id_vector_temp_.push_back(GetOperandComponents( - operand_storage[0], instr.scalar_operands[0], 0b0001)); - spv::Id result = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450InverseSqrt, id_vector_temp_); + spv::Id result = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450InverseSqrt, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], + 0b0001)); result = builder_->createTriOp( spv::OpSelect, type_float_, builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, @@ -1250,12 +1216,10 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation( builder_->makeFloatConstant(FLT_MAX), result); } case ucode::AluScalarOpcode::kRsqf: { - id_vector_temp_.clear(); - id_vector_temp_.push_back(GetOperandComponents( - operand_storage[0], instr.scalar_operands[0], 0b0001)); - spv::Id result = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450InverseSqrt, id_vector_temp_); + spv::Id result = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450InverseSqrt, + GetOperandComponents(operand_storage[0], instr.scalar_operands[0], + 0b0001)); result = builder_->createTriOp( spv::OpSelect, type_float_, builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, diff --git a/src/xenia/gpu/spirv_shader_translator_fetch.cc b/src/xenia/gpu/spirv_shader_translator_fetch.cc index 9599dffe8..265082ba1 100644 --- a/src/xenia/gpu/spirv_shader_translator_fetch.cc +++ b/src/xenia/gpu/spirv_shader_translator_fetch.cc @@ -83,12 +83,10 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( index = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, index, builder_->makeFloatConstant(0.5f)); } - id_vector_temp_.clear(); - id_vector_temp_.push_back(index); index = builder_->createUnaryOp( spv::OpConvertFToS, type_int_, - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450Floor, id_vector_temp_)); + builder_->createUnaryBuiltinCall(type_float_, ext_inst_glsl_std_450_, + GLSLstd450Floor, index)); if (instr.attributes.stride > 1) { index = builder_->createBinOp( spv::OpIMul, type_int_, index, @@ -246,11 +244,9 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( } else { word = words; } - id_vector_temp_.clear(); - id_vector_temp_.push_back(word); - word = builder_->createBuiltinCall(type_float2_, ext_inst_glsl_std_450_, - GLSLstd450UnpackHalf2x16, - id_vector_temp_); + word = builder_->createUnaryBuiltinCall(type_float2_, + ext_inst_glsl_std_450_, + GLSLstd450UnpackHalf2x16, word); if (word_needed_components != 0b11) { // If only one of two components is needed, extract it. word = builder_->createCompositeExtract( @@ -454,18 +450,14 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction( spv::Id const_minus_1 = builder_->makeFloatConstant(-1.0f); if (used_format_component_count > 1) { id_vector_temp_.clear(); - id_vector_temp_.insert(id_vector_temp_.cend(), - used_format_component_count, + id_vector_temp_.resize(used_format_component_count, const_minus_1); const_minus_1 = builder_->makeCompositeConstant(result_type, id_vector_temp_); } - id_vector_temp_.clear(); - id_vector_temp_.push_back(result); - id_vector_temp_.push_back(const_minus_1); - result = - builder_->createBuiltinCall(result_type, ext_inst_glsl_std_450_, - GLSLstd450FMax, id_vector_temp_); + result = builder_->createBinBuiltinCall( + result_type, ext_inst_glsl_std_450_, GLSLstd450FMax, result, + const_minus_1); } break; case xenos::SignedRepeatingFractionMode::kNoZero: id_vector_temp_.clear(); @@ -1104,11 +1096,9 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( builder_->makeFloatConstant(component_offset)); } // 0.5 has already been subtracted via offsets previously. - id_vector_temp_.clear(); - id_vector_temp_.push_back(result_component); - result_component = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450Fract, id_vector_temp_); + result_component = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Fract, + result_component); result[coordinate_component_index] = result_component; } } else { @@ -1256,14 +1246,11 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( spv::OpFAdd, type_float_, face, builder_->makeFloatConstant(offset_values[2])); } - id_vector_temp_.clear(); - id_vector_temp_.push_back(face); - id_vector_temp_.push_back(const_float_0_); - id_vector_temp_.push_back(builder_->makeFloatConstant(5.0f)); face = builder_->createUnaryOp( spv::OpConvertFToU, type_uint_, - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_)); + builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, face, + const_float_0_, builder_->makeFloatConstant(5.0f))); // Split the face index into the axis and the sign. spv::Id const_uint_1 = builder_->makeUintConstant(1); spv::Id face_axis = builder_->createBinOp( @@ -1580,11 +1567,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( // in getCompTexLOD, so not doing it here too for now. Apply the // gradient exponent biases from the word 4 of the fetch constant in // the future when it's handled in getCompTexLOD somehow. - id_vector_temp_.clear(); - id_vector_temp_.push_back(lod); - spv::Id lod_gradient_scale = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450Exp2, id_vector_temp_); + spv::Id lod_gradient_scale = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Exp2, lod); switch (instr.dimension) { case xenos::FetchOpDimension::k1D: { spv::Id gradient_h_1d, gradient_v_1d; @@ -1841,14 +1825,10 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( (vol_mag_filter_is_fetch_const || vol_min_filter_is_fetch_const || vol_mag_filter_is_linear != vol_min_filter_is_linear)) { // Check if minifying along layers (derivative > 1 along any axis). - id_vector_temp_.clear(); - for (uint32_t i = 0; i < 2; ++i) { - id_vector_temp_.push_back(builder_->createCompositeExtract( - i ? gradients_v : gradients_h, type_float_, 2)); - } - spv::Id layer_max_gradient = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450NMax, id_vector_temp_); + spv::Id layer_max_gradient = builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NMax, + builder_->createCompositeExtract(gradients_h, type_float_, 2), + builder_->createCompositeExtract(gradients_v, type_float_, 2)); if (!instr.attributes.unnormalized_coordinates) { // Denormalize the gradient if provided as normalized. assert_true(size[2] != spv::NoResult); @@ -1927,11 +1907,9 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( // floor even for the layer index, but on the Xenos, addressing is // similar to that of 3D textures). This is needed for both point and // linear filtering (with linear, 0.5 was subtracted previously). - id_vector_temp_.clear(); - id_vector_temp_.push_back(layer_coordinate); - spv::Id layer_0_coordinate = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450Floor, id_vector_temp_); + spv::Id layer_0_coordinate = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Floor, + layer_coordinate); id_vector_temp_.clear(); id_vector_temp_.push_back(coordinates[0]); id_vector_temp_.push_back(coordinates[1]); @@ -1972,11 +1950,9 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( id_vector_temp_.push_back(layer_1_coordinate); texture_parameters.coords = builder_->createCompositeConstruct( type_float3_, id_vector_temp_); - id_vector_temp_.clear(); - id_vector_temp_.push_back(layer_coordinate); - spv::Id layer_lerp_factor = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450Fract, id_vector_temp_); + spv::Id layer_lerp_factor = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Fract, + layer_coordinate); spv::Id sample_result_unsigned_stacked_filtered; spv::Id sample_result_signed_stacked_filtered; SampleTexture( @@ -2302,14 +2278,13 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction( // Apply the exponent bias from the bits 13:18 of the fetch constant // word 4. - id_vector_temp_.clear(); - id_vector_temp_.push_back(builder_->makeFloatConstant(1.0f)); - id_vector_temp_.push_back(builder_->createTriOp( - spv::OpBitFieldSExtract, type_int_, fetch_constant_word_4_signed, - builder_->makeUintConstant(13), builder_->makeUintConstant(6))); - spv::Id result_exponent_bias = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450Ldexp, id_vector_temp_); + spv::Id result_exponent_bias = builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450Ldexp, + const_float_1_, + builder_->createTriOp(spv::OpBitFieldSExtract, type_int_, + fetch_constant_word_4_signed, + builder_->makeUintConstant(13), + builder_->makeUintConstant(6))); { uint32_t result_remaining_components = used_result_nonzero_components; uint32_t result_component_index; diff --git a/src/xenia/gpu/spirv_shader_translator_rb.cc b/src/xenia/gpu/spirv_shader_translator_rb.cc index 456478f62..65a01209d 100644 --- a/src/xenia/gpu/spirv_shader_translator_rb.cc +++ b/src/xenia/gpu/spirv_shader_translator_rb.cc @@ -1531,15 +1531,12 @@ void SpirvShaderTranslator::FSI_LoadSampleMask(spv::Id msaa_samples) { builder_->makeUintConstant(32 - 2)); } else { // 0 and 3 to 0 and 1. - id_vector_temp_.clear(); - id_vector_temp_.push_back(input_sample_mask_value); - id_vector_temp_.push_back(builder_->createTriOp( - spv::OpBitFieldUExtract, type_uint_, input_sample_mask_value, - const_uint_2, const_uint_1)); - id_vector_temp_.push_back(const_uint_1); - id_vector_temp_.push_back(builder_->makeUintConstant(32 - 1)); - sample_mask_2x = - builder_->createOp(spv::OpBitFieldInsert, type_uint_, id_vector_temp_); + sample_mask_2x = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, input_sample_mask_value, + builder_->createTriOp(spv::OpBitFieldUExtract, type_uint_, + input_sample_mask_value, const_uint_2, + const_uint_1), + const_uint_1, builder_->makeUintConstant(32 - 1)); } builder_->createBranch(&block_msaa_merge); @@ -1547,17 +1544,14 @@ void SpirvShaderTranslator::FSI_LoadSampleMask(spv::Id msaa_samples) { builder_->setBuildPoint(&block_msaa_4x); // Flip samples in bits 0:1 by reversing the whole coverage mask and inserting // the reversing bits. - id_vector_temp_.clear(); - id_vector_temp_.push_back(input_sample_mask_value); - id_vector_temp_.push_back(builder_->createBinOp( - spv::OpShiftRightLogical, type_uint_, - builder_->createUnaryOp(spv::OpBitReverse, type_uint_, - input_sample_mask_value), - builder_->makeUintConstant(32 - 1 - 2))); - id_vector_temp_.push_back(const_uint_1); - id_vector_temp_.push_back(const_uint_2); - spv::Id sample_mask_4x = - builder_->createOp(spv::OpBitFieldInsert, type_uint_, id_vector_temp_); + spv::Id sample_mask_4x = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, input_sample_mask_value, + builder_->createBinOp( + spv::OpShiftRightLogical, type_uint_, + builder_->createUnaryOp(spv::OpBitReverse, type_uint_, + input_sample_mask_value), + builder_->makeUintConstant(32 - 1 - 2)), + const_uint_1, const_uint_2); builder_->createBranch(&block_msaa_merge); // Select the result depending on the MSAA sample count. @@ -1955,16 +1949,12 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( // https://docs.microsoft.com/en-us/windows/desktop/direct3d9/depth-bias std::array depth_dxy_abs; for (uint32_t i = 0; i < 2; ++i) { - id_vector_temp_.clear(); - id_vector_temp_.push_back(depth_dxy[i]); - depth_dxy_abs[i] = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, id_vector_temp_); + depth_dxy_abs[i] = builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, depth_dxy[i]); } - id_vector_temp_.clear(); - id_vector_temp_.push_back(depth_dxy_abs[0]); - id_vector_temp_.push_back(depth_dxy_abs[1]); - spv::Id depth_max_slope = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450FMax, id_vector_temp_); + spv::Id depth_max_slope = builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FMax, depth_dxy_abs[0], + depth_dxy_abs[1]); // Calculate the polygon offset. spv::Id slope_scaled_poly_offset = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, poly_offset_scale, depth_max_slope); @@ -2074,17 +2064,14 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( sample_depth_dxy[j] = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, sample_location[j], depth_dxy[j]); } - spv::Id sample_depth32 = builder_->createNoContractionBinOp( - spv::OpFAdd, type_float_, center_depth32_biased, - builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, - sample_depth_dxy[0], - sample_depth_dxy[1])); - id_vector_temp_.clear(); - id_vector_temp_.push_back(sample_depth32); - id_vector_temp_.push_back(const_float_0_); - id_vector_temp_.push_back(const_float_1_); - sample_depth32 = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, id_vector_temp_); + spv::Id sample_depth32 = builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createNoContractionBinOp( + spv::OpFAdd, type_float_, center_depth32_biased, + builder_->createNoContractionBinOp(spv::OpFAdd, type_float_, + sample_depth_dxy[0], + sample_depth_dxy[1])), + const_float_0_, const_float_1_); // Convert the new depth to 24-bit. spv::Block& block_depth_format_float = builder_->makeNewBlock(); @@ -2105,14 +2092,13 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( // Round to the nearest even integer. This seems to be the correct // conversion, adding +0.5 and rounding towards zero results in red instead // of black in the 4D5307E6 clear shader. - id_vector_temp_.clear(); - id_vector_temp_.push_back(builder_->createNoContractionBinOp( - spv::OpFMul, type_float_, sample_depth32, - builder_->makeFloatConstant(float(0xFFFFFF)))); spv::Id sample_depth_unorm24 = builder_->createUnaryOp( spv::OpConvertFToU, type_uint_, - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450RoundEven, id_vector_temp_)); + builder_->createUnaryBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450RoundEven, + builder_->createNoContractionBinOp( + spv::OpFMul, type_float_, sample_depth32, + builder_->makeFloatConstant(float(0xFFFFFF))))); builder_->createBranch(&block_depth_format_merge); spv::Block& block_depth_format_unorm_end = *builder_->getBuildPoint(); // Merge between the two formats. @@ -2253,28 +2239,25 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( builder_->createBranch(&block_stencil_op_merge); // Increment and clamp. builder_->setBuildPoint(&block_stencil_op_increment_clamp); - id_vector_temp_.clear(); - id_vector_temp_.push_back(builder_->makeUintConstant(UINT8_MAX - 1)); - id_vector_temp_.push_back( - builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, old_depth_stencil, - builder_->makeUintConstant(UINT8_MAX))); spv::Id new_stencil_in_low_bits_increment_clamp = builder_->createBinOp( spv::OpIAdd, type_uint_, - builder_->createBuiltinCall(type_uint_, ext_inst_glsl_std_450_, - GLSLstd450UMin, id_vector_temp_), + builder_->createBinBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450UMin, + builder_->makeUintConstant(UINT8_MAX - 1), + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + old_depth_stencil, + builder_->makeUintConstant(UINT8_MAX))), const_uint_1); builder_->createBranch(&block_stencil_op_merge); // Decrement and clamp. builder_->setBuildPoint(&block_stencil_op_decrement_clamp); - id_vector_temp_.clear(); - id_vector_temp_.push_back(const_uint_1); - id_vector_temp_.push_back( - builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, old_depth_stencil, - builder_->makeUintConstant(UINT8_MAX))); spv::Id new_stencil_in_low_bits_decrement_clamp = builder_->createBinOp( spv::OpISub, type_uint_, - builder_->createBuiltinCall(type_uint_, ext_inst_glsl_std_450_, - GLSLstd450UMax, id_vector_temp_), + builder_->createBinBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450UMax, const_uint_1, + builder_->createBinOp(spv::OpBitwiseAnd, type_uint_, + old_depth_stencil, + builder_->makeUintConstant(UINT8_MAX))), const_uint_1); builder_->createBranch(&block_stencil_op_merge); // Invert. @@ -2360,13 +2343,9 @@ void SpirvShaderTranslator::FSI_DepthStencilTest( // Combine the new depth and the new stencil taking into account whether the // new depth should be written. - id_vector_temp_.clear(); - id_vector_temp_.push_back(new_stencil_and_old_depth); - id_vector_temp_.push_back(sample_depth24); - id_vector_temp_.push_back(const_uint_8); - id_vector_temp_.push_back(builder_->makeUintConstant(24)); - spv::Id new_stencil_and_unconditional_new_depth = - builder_->createOp(spv::OpBitFieldInsert, type_uint_, id_vector_temp_); + spv::Id new_stencil_and_unconditional_new_depth = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, new_stencil_and_old_depth, + sample_depth24, const_uint_8, builder_->makeUintConstant(24)); spv::Id new_depth_stencil = builder_->createTriOp( spv::OpSelect, type_uint_, builder_->createBinOp(spv::OpLogicalAnd, type_bool_, @@ -2568,14 +2547,11 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( spv::Id packed_8_8_8_8; { builder_->setBuildPoint(&block_format_8_8_8_8); - id_vector_temp_.clear(); - id_vector_temp_.push_back(color_float4); - id_vector_temp_.push_back(const_float4_0_); - id_vector_temp_.push_back(const_float4_1_); spv::Id color_scaled = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, type_float4_, - builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_), + builder_->createTriBuiltinCall(type_float4_, ext_inst_glsl_std_450_, + GLSLstd450NClamp, color_float4, + const_float4_0_, const_float4_1_), builder_->makeFloatConstant(255.0f)); spv::Id color_offset = builder_->createNoContractionBinOp( spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); @@ -2585,14 +2561,10 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( builder_->createCompositeExtract(color_uint4, type_uint_, 0); spv::Id component_width = builder_->makeUintConstant(8); for (uint32_t i = 1; i < 4; ++i) { - id_vector_temp_.clear(); - id_vector_temp_.push_back(packed_8_8_8_8); - id_vector_temp_.push_back( - builder_->createCompositeExtract(color_uint4, type_uint_, i)); - id_vector_temp_.push_back(builder_->makeUintConstant(8 * i)); - id_vector_temp_.push_back(component_width); - packed_8_8_8_8 = builder_->createOp(spv::OpBitFieldInsert, type_uint_, - id_vector_temp_); + packed_8_8_8_8 = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, packed_8_8_8_8, + builder_->createCompositeExtract(color_uint4, type_uint_, i), + builder_->makeUintConstant(8 * i), component_width); } builder_->createBranch(&block_format_merge); } @@ -2614,13 +2586,10 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( builder_->createRvalueSwizzle(spv::NoPrecision, type_float3_, color_float4, uint_vector_temp_), false); - id_vector_temp_.clear(); - id_vector_temp_.push_back( - builder_->createCompositeExtract(color_float4, type_float_, 3)); - id_vector_temp_.push_back(const_float_0_); - id_vector_temp_.push_back(const_float_1_); - spv::Id alpha_clamped = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, id_vector_temp_); + spv::Id alpha_clamped = builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createCompositeExtract(color_float4, type_float_, 3), + const_float_0_, const_float_1_); // Bypass the `getNumTypeConstituents(typeId) == (int)constituents.size()` // assertion in createCompositeConstruct, OpCompositeConstruct can // construct vectors not only from scalars, but also from other vectors. @@ -2646,14 +2615,10 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( builder_->createCompositeExtract(color_uint4, type_uint_, 0); spv::Id component_width = builder_->makeUintConstant(8); for (uint32_t i = 1; i < 4; ++i) { - id_vector_temp_.clear(); - id_vector_temp_.push_back(packed_8_8_8_8_gamma); - id_vector_temp_.push_back( - builder_->createCompositeExtract(color_uint4, type_uint_, i)); - id_vector_temp_.push_back(builder_->makeUintConstant(8 * i)); - id_vector_temp_.push_back(component_width); - packed_8_8_8_8_gamma = builder_->createOp(spv::OpBitFieldInsert, - type_uint_, id_vector_temp_); + packed_8_8_8_8_gamma = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, packed_8_8_8_8_gamma, + builder_->createCompositeExtract(color_uint4, type_uint_, i), + builder_->makeUintConstant(8 * i), component_width); } builder_->createBranch(&block_format_merge); } @@ -2666,13 +2631,9 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( spv::Id packed_2_10_10_10; { builder_->setBuildPoint(&block_format_2_10_10_10); - id_vector_temp_.clear(); - id_vector_temp_.push_back(color_float4); - id_vector_temp_.push_back(const_float4_0_); - id_vector_temp_.push_back(const_float4_1_); - spv::Id color_clamped = - builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_); + spv::Id color_clamped = builder_->createTriBuiltinCall( + type_float4_, ext_inst_glsl_std_450_, GLSLstd450NClamp, color_float4, + const_float4_0_, const_float4_1_); id_vector_temp_.clear(); id_vector_temp_.resize(3, builder_->makeFloatConstant(1023.0f)); id_vector_temp_.push_back(builder_->makeFloatConstant(3.0f)); @@ -2688,14 +2649,10 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( spv::Id rgb_width = builder_->makeUintConstant(10); spv::Id alpha_width = builder_->makeUintConstant(2); for (uint32_t i = 1; i < 4; ++i) { - id_vector_temp_.clear(); - id_vector_temp_.push_back(packed_2_10_10_10); - id_vector_temp_.push_back( - builder_->createCompositeExtract(color_uint4, type_uint_, i)); - id_vector_temp_.push_back(builder_->makeUintConstant(10 * i)); - id_vector_temp_.push_back(i == 3 ? alpha_width : rgb_width); - packed_2_10_10_10 = builder_->createOp(spv::OpBitFieldInsert, type_uint_, - id_vector_temp_); + packed_2_10_10_10 = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, packed_2_10_10_10, + builder_->createCompositeExtract(color_uint4, type_uint_, i), + builder_->makeUintConstant(10 * i), i == 3 ? alpha_width : rgb_width); } builder_->createBranch(&block_format_merge); } @@ -2717,15 +2674,12 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( ext_inst_glsl_std_450_); } // Alpha. - id_vector_temp_.clear(); - id_vector_temp_.push_back( - builder_->createCompositeExtract(color_float4, type_float_, 3)); - id_vector_temp_.push_back(const_float_0_); - id_vector_temp_.push_back(const_float_1_); spv::Id alpha_scaled = builder_->createNoContractionBinOp( spv::OpFMul, type_float_, - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450NClamp, id_vector_temp_), + builder_->createTriBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NClamp, + builder_->createCompositeExtract(color_float4, type_float_, 3), + const_float_0_, const_float_1_), builder_->makeFloatConstant(3.0f)); spv::Id alpha_offset = builder_->createNoContractionBinOp( spv::OpFAdd, type_float_, alpha_scaled, unorm_round_offset_float); @@ -2735,21 +2689,14 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( packed_2_10_10_10_float = color_components[0]; spv::Id rgb_width = builder_->makeUintConstant(10); for (uint32_t i = 1; i < 3; ++i) { - id_vector_temp_.clear(); - id_vector_temp_.push_back(packed_2_10_10_10_float); - id_vector_temp_.push_back(color_components[i]); - id_vector_temp_.push_back(builder_->makeUintConstant(10 * i)); - id_vector_temp_.push_back(rgb_width); - packed_2_10_10_10_float = builder_->createOp(spv::OpBitFieldInsert, - type_uint_, id_vector_temp_); + packed_2_10_10_10_float = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, packed_2_10_10_10_float, + color_components[i], builder_->makeUintConstant(10 * i), rgb_width); } - id_vector_temp_.clear(); - id_vector_temp_.push_back(packed_2_10_10_10_float); - id_vector_temp_.push_back(color_components[3]); - id_vector_temp_.push_back(builder_->makeUintConstant(30)); - id_vector_temp_.push_back(builder_->makeUintConstant(2)); - packed_2_10_10_10_float = - builder_->createOp(spv::OpBitFieldInsert, type_uint_, id_vector_temp_); + packed_2_10_10_10_float = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, packed_2_10_10_10_float, + color_components[3], builder_->makeUintConstant(30), + builder_->makeUintConstant(2)); builder_->createBranch(&block_format_merge); } spv::Block& block_format_2_10_10_10_float_end = *builder_->getBuildPoint(); @@ -2771,16 +2718,15 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( builder_->makeCompositeConstant(type_float4_, id_vector_temp_); id_vector_temp_.clear(); // NaN to 0, not to -32. - id_vector_temp_.push_back(builder_->createTriOp( - spv::OpSelect, type_float4_, - builder_->createUnaryOp(spv::OpIsNan, type_bool4_, color_float4), - const_float4_0_, color_float4)); - id_vector_temp_.push_back(const_float4_minus_32); - id_vector_temp_.push_back(const_float4_32); spv::Id color_scaled = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, type_float4_, - builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_, - GLSLstd450FClamp, id_vector_temp_), + builder_->createTriBuiltinCall( + type_float4_, ext_inst_glsl_std_450_, GLSLstd450FClamp, + builder_->createTriOp(spv::OpSelect, type_float4_, + builder_->createUnaryOp( + spv::OpIsNan, type_bool4_, color_float4), + const_float4_0_, color_float4), + const_float4_minus_32, const_float4_32), builder_->makeFloatConstant(32767.0f / 32.0f)); id_vector_temp_.clear(); id_vector_temp_.resize(4, builder_->makeFloatConstant(-0.5f)); @@ -2798,15 +2744,11 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( builder_->createUnaryOp(spv::OpConvertFToS, type_int4_, color_offset)); spv::Id component_offset_width = builder_->makeUintConstant(16); for (uint32_t i = 0; i < 2; ++i) { - id_vector_temp_.clear(); - id_vector_temp_.push_back( - builder_->createCompositeExtract(color_uint4, type_uint_, 2 * i)); - id_vector_temp_.push_back( - builder_->createCompositeExtract(color_uint4, type_uint_, 2 * i + 1)); - id_vector_temp_.push_back(component_offset_width); - id_vector_temp_.push_back(component_offset_width); - packed_16[i] = builder_->createOp(spv::OpBitFieldInsert, type_uint_, - id_vector_temp_); + packed_16[i] = builder_->createQuadOp( + spv::OpBitFieldInsert, type_uint_, + builder_->createCompositeExtract(color_uint4, type_uint_, 2 * i), + builder_->createCompositeExtract(color_uint4, type_uint_, 2 * i + 1), + component_offset_width, component_offset_width); } builder_->createBranch(&block_format_merge); } @@ -2828,27 +2770,22 @@ std::array SpirvShaderTranslator::FSI_ClampAndPackColor( id_vector_temp_.resize(4, builder_->makeFloatConstant(65504.0f)); spv::Id const_float4_float16_max = builder_->makeCompositeConstant(type_float4_, id_vector_temp_); - id_vector_temp_.clear(); // NaN to 0, not to -max. - id_vector_temp_.push_back(builder_->createTriOp( - spv::OpSelect, type_float4_, - builder_->createUnaryOp(spv::OpIsNan, type_bool4_, color_float4), - const_float4_0_, color_float4)); - id_vector_temp_.push_back(const_float4_minus_float16_max); - id_vector_temp_.push_back(const_float4_float16_max); - spv::Id color_clamped = - builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_, - GLSLstd450FClamp, id_vector_temp_); + spv::Id color_clamped = builder_->createTriBuiltinCall( + type_float4_, ext_inst_glsl_std_450_, GLSLstd450FClamp, + builder_->createTriOp( + spv::OpSelect, type_float4_, + builder_->createUnaryOp(spv::OpIsNan, type_bool4_, color_float4), + const_float4_0_, color_float4), + const_float4_minus_float16_max, const_float4_float16_max); for (uint32_t i = 0; i < 2; ++i) { uint_vector_temp_.clear(); uint_vector_temp_.push_back(2 * i); uint_vector_temp_.push_back(2 * i + 1); - id_vector_temp_.clear(); - id_vector_temp_.push_back(builder_->createRvalueSwizzle( - spv::NoPrecision, type_float2_, color_clamped, uint_vector_temp_)); - packed_16_float[i] = - builder_->createBuiltinCall(type_uint_, ext_inst_glsl_std_450_, - GLSLstd450PackHalf2x16, id_vector_temp_); + packed_16_float[i] = builder_->createUnaryBuiltinCall( + type_uint_, ext_inst_glsl_std_450_, GLSLstd450PackHalf2x16, + builder_->createRvalueSwizzle(spv::NoPrecision, type_float2_, + color_clamped, uint_vector_temp_)); } builder_->createBranch(&block_format_merge); } @@ -3113,12 +3050,9 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( builder_->makeUintConstant(16 * (j & 1)), component_width)), component_scale); - id_vector_temp_.clear(); - id_vector_temp_.push_back(component_min); - id_vector_temp_.push_back(component); - component = - builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, - GLSLstd450FMax, id_vector_temp_); + component = builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450FMax, component_min, + component); unpacked_16[i][j] = component; } builder_->createBranch(&block_format_merge); @@ -3141,11 +3075,9 @@ std::array SpirvShaderTranslator::FSI_UnpackColor( : &block_format_16_16_float); // TODO(Triang3l): Xenos extended-range float16. for (uint32_t j = 0; j <= i; ++j) { - id_vector_temp_.clear(); - id_vector_temp_.push_back(color_packed[j]); - spv::Id components_float2 = builder_->createBuiltinCall( + spv::Id components_float2 = builder_->createUnaryBuiltinCall( type_float2_, ext_inst_glsl_std_450_, GLSLstd450UnpackHalf2x16, - id_vector_temp_); + color_packed[j]); for (uint32_t k = 0; k < 2; ++k) { unpacked_16_float[i][2 * j + k] = builder_->createCompositeExtract( components_float2, type_float_, k); @@ -3236,19 +3168,16 @@ spv::Id SpirvShaderTranslator::FSI_FlushNaNClampAndInBlending( builder_->createConditionalBranch(is_fixed_point, &block_is_fixed_point_if, &block_is_fixed_point_merge); builder_->setBuildPoint(&block_is_fixed_point_if); - id_vector_temp_.clear(); // Flush NaN to 0 even for signed (NMax would flush it to the minimum value). - id_vector_temp_.push_back(builder_->createTriOp( - spv::OpSelect, color_or_alpha_type, - builder_->createUnaryOp(spv::OpIsNan, - type_bool_vectors_[component_count - 1], - color_or_alpha), - const_float_vectors_0_[component_count - 1], color_or_alpha)); - id_vector_temp_.push_back(min_value); - id_vector_temp_.push_back(max_value); - spv::Id color_or_alpha_clamped = - builder_->createBuiltinCall(color_or_alpha_type, ext_inst_glsl_std_450_, - GLSLstd450FClamp, id_vector_temp_); + spv::Id color_or_alpha_clamped = builder_->createTriBuiltinCall( + color_or_alpha_type, ext_inst_glsl_std_450_, GLSLstd450FClamp, + builder_->createTriOp( + spv::OpSelect, color_or_alpha_type, + builder_->createUnaryOp(spv::OpIsNan, + type_bool_vectors_[component_count - 1], + color_or_alpha), + const_float_vectors_0_[component_count - 1], color_or_alpha), + min_value, max_value); builder_->createBranch(&block_is_fixed_point_merge); builder_->setBuildPoint(&block_is_fixed_point_merge); id_vector_temp_.clear(); @@ -3426,16 +3355,12 @@ spv::Id SpirvShaderTranslator::FSI_ApplyColorBlendFactor( spv::Id result_source_alpha_saturate; { builder_->setBuildPoint(&block_factor_source_alpha_saturate); - spv::Id one_minus_dest_alpha = builder_->createNoContractionBinOp( - spv::OpFSub, type_float_, const_float_1_, dest_alpha); - id_vector_temp_.clear(); - id_vector_temp_.push_back(source_alpha); - id_vector_temp_.push_back(one_minus_dest_alpha); - spv::Id factor_source_alpha_saturate = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, id_vector_temp_); result_source_alpha_saturate = builder_->createNoContractionBinOp( spv::OpVectorTimesScalar, type_float3_, value, - factor_source_alpha_saturate); + builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, source_alpha, + builder_->createNoContractionBinOp(spv::OpFSub, type_float_, + const_float_1_, dest_alpha))); builder_->createBranch(&block_factor_merge); } @@ -3605,15 +3530,12 @@ spv::Id SpirvShaderTranslator::FSI_ApplyAlphaBlendFactor( spv::Id result_source_alpha_saturate; { builder_->setBuildPoint(&block_factor_source_alpha_saturate); - spv::Id one_minus_dest_alpha = builder_->createNoContractionBinOp( - spv::OpFSub, type_float_, const_float_1_, dest_alpha); - id_vector_temp_.clear(); - id_vector_temp_.push_back(source_alpha); - id_vector_temp_.push_back(one_minus_dest_alpha); - spv::Id factor_source_alpha_saturate = builder_->createBuiltinCall( - type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, id_vector_temp_); result_source_alpha_saturate = builder_->createNoContractionBinOp( - spv::OpFMul, type_float_, value, factor_source_alpha_saturate); + spv::OpFMul, type_float_, value, + builder_->createBinBuiltinCall( + type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, source_alpha, + builder_->createNoContractionBinOp(spv::OpFSub, type_float_, + const_float_1_, dest_alpha))); builder_->createBranch(&block_factor_merge); } @@ -3687,22 +3609,18 @@ spv::Id SpirvShaderTranslator::FSI_BlendColorOrAlphaWithUnclampedResult( // Min case. builder_->setBuildPoint(&block_min_max_min); - id_vector_temp_.clear(); - id_vector_temp_.push_back(is_alpha ? source_alpha_clamped - : source_color_clamped); - id_vector_temp_.push_back(is_alpha ? dest_alpha : dest_color); - spv::Id result_min = builder_->createBuiltinCall( - value_type, ext_inst_glsl_std_450_, GLSLstd450FMin, id_vector_temp_); + spv::Id result_min = builder_->createBinBuiltinCall( + value_type, ext_inst_glsl_std_450_, GLSLstd450FMin, + is_alpha ? source_alpha_clamped : source_color_clamped, + is_alpha ? dest_alpha : dest_color); builder_->createBranch(&block_min_max_merge); // Max case. builder_->setBuildPoint(&block_min_max_max); - id_vector_temp_.clear(); - id_vector_temp_.push_back(is_alpha ? source_alpha_clamped - : source_color_clamped); - id_vector_temp_.push_back(is_alpha ? dest_alpha : dest_color); - spv::Id result_max = builder_->createBuiltinCall( - value_type, ext_inst_glsl_std_450_, GLSLstd450FMax, id_vector_temp_); + spv::Id result_max = builder_->createBinBuiltinCall( + value_type, ext_inst_glsl_std_450_, GLSLstd450FMax, + is_alpha ? source_alpha_clamped : source_color_clamped, + is_alpha ? dest_alpha : dest_color); builder_->createBranch(&block_min_max_merge); // Blending with factors. diff --git a/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc b/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc index f0e0e87d9..e5b17ef5f 100644 --- a/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_render_target_cache.cc @@ -2621,13 +2621,9 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( source_sample_id = builder.createBinOp(spv::OpBitwiseAnd, type_uint, dest_sample_id, builder.makeUintConstant(1 << 1)); - id_vector_temp.clear(); - id_vector_temp.push_back(dest_sample_id); - id_vector_temp.push_back(dest_tile_pixel_x); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - source_tile_pixel_x = - builder.createOp(spv::OpBitFieldInsert, type_uint, id_vector_temp); + source_tile_pixel_x = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, dest_tile_pixel_x, + builder.makeUintConstant(1), builder.makeUintConstant(31)); } else if (key.dest_msaa_samples == xenos::MsaaSamples::k2X) { // 32bpp -> 64bpp, 4x -> 2x. // 1 destination horizontal pixel = 2 source horizontal samples. @@ -2655,13 +2651,10 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // D p0,1 = S p0,0 s0,1 | S p0,0 s1,1 // Horizontal pixel index can be reused. Vertical pixel 1 should // become sample 2. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.makeUintConstant(0)); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_sample_id = - builder.createOp(spv::OpBitFieldInsert, type_uint, id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, builder.makeUintConstant(0), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(1)); source_tile_pixel_y = builder.createBinOp(spv::OpShiftRightLogical, type_uint, dest_tile_pixel_y, builder.makeUintConstant(1)); @@ -2673,15 +2666,12 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // 32bpp -> 64bpp, 1x/2x -> 4x. // The X part. // 1 destination horizontal sample = 2 source horizontal pixels. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpShiftLeftLogical, type_uint, dest_tile_pixel_x, - builder.makeUintConstant(2))); - id_vector_temp.push_back(dest_sample_id); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_tile_pixel_x = - builder.createOp(spv::OpBitFieldInsert, type_uint, id_vector_temp); + source_tile_pixel_x = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpShiftLeftLogical, type_uint, + dest_tile_pixel_x, builder.makeUintConstant(2)), + dest_sample_id, builder.makeUintConstant(1), + builder.makeUintConstant(1)); // Y is handled by common code. } else { // 32bpp -> 64bpp, 1x/2x -> 1x/2x. @@ -2706,13 +2696,9 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // D p1,0 s1,0 = S s1,0 high // Vertical pixel and sample (second bit) addressing is the same. // However, 1 horizontal destination pixel = 1 horizontal source sample. - id_vector_temp.clear(); - id_vector_temp.push_back(dest_sample_id); - id_vector_temp.push_back(dest_tile_pixel_x); - id_vector_temp.push_back(builder.makeUintConstant(0)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_sample_id = - builder.createOp(spv::OpBitFieldInsert, type_uint, id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, dest_tile_pixel_x, + builder.makeUintConstant(0), builder.makeUintConstant(1)); // 2 destination horizontal samples = 1 source horizontal sample, thus // 2 destination horizontal pixels = 1 source horizontal pixel. source_tile_pixel_x = @@ -2745,34 +2731,25 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // 0/1 in the second bit for 2x as 4x) = source vertical samples // (second bit). if (msaa_2x_attachments_supported_) { - id_vector_temp.clear(); - id_vector_temp.push_back(source_sample_id); - id_vector_temp.push_back(builder.createBinOp( - spv::OpBitwiseXor, type_uint, dest_sample_id, - builder.makeUintConstant(1))); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_sample_id = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_sample_id, + builder.createBinOp(spv::OpBitwiseXor, type_uint, + dest_sample_id, + builder.makeUintConstant(1)), + builder.makeUintConstant(1), builder.makeUintConstant(1)); } else { - id_vector_temp.clear(); - id_vector_temp.push_back(dest_sample_id); - id_vector_temp.push_back(source_sample_id); - id_vector_temp.push_back(builder.makeUintConstant(0)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_sample_id = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, + source_sample_id, builder.makeUintConstant(0), + builder.makeUintConstant(1)); } } else { // 64bpp -> 32bpp, 4x -> 1x. // 1 destination vertical pixel = 1 source vertical sample. - id_vector_temp.clear(); - id_vector_temp.push_back(source_sample_id); - id_vector_temp.push_back(source_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_sample_id = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_sample_id, + source_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(1)); source_tile_pixel_y = builder.createBinOp( spv::OpShiftRightLogical, type_uint, dest_tile_pixel_y, builder.makeUintConstant(1)); @@ -2808,23 +2785,17 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // for native 2x or 0/1 in the second bit for 2x as 4x) to second // sample bit. if (msaa_2x_attachments_supported_) { - id_vector_temp.clear(); - id_vector_temp.push_back(dest_tile_pixel_x); - id_vector_temp.push_back(builder.createBinOp( - spv::OpBitwiseXor, type_uint, dest_sample_id, - builder.makeUintConstant(1))); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - source_sample_id = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_tile_pixel_x, + builder.createBinOp(spv::OpBitwiseXor, type_uint, + dest_sample_id, + builder.makeUintConstant(1)), + builder.makeUintConstant(1), builder.makeUintConstant(31)); } else { - id_vector_temp.clear(); - id_vector_temp.push_back(dest_sample_id); - id_vector_temp.push_back(dest_tile_pixel_x); - id_vector_temp.push_back(builder.makeUintConstant(0)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_sample_id = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, + dest_tile_pixel_x, builder.makeUintConstant(0), + builder.makeUintConstant(1)); } source_tile_pixel_x = builder.createBinOp( spv::OpShiftRightLogical, type_uint, dest_tile_pixel_x, @@ -2832,15 +2803,13 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( } else { // Same BPP, 4x -> 1x. // Pixels to samples. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpBitwiseAnd, type_uint, dest_tile_pixel_x, - builder.makeUintConstant(1))); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_sample_id = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpBitwiseAnd, type_uint, + dest_tile_pixel_x, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(1)); source_tile_pixel_x = builder.createBinOp( spv::OpShiftRightLogical, type_uint, dest_tile_pixel_x, builder.makeUintConstant(1)); @@ -2853,13 +2822,10 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // Only the X part - Y is handled by common code. if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { // Horizontal samples to pixels. - id_vector_temp.clear(); - id_vector_temp.push_back(dest_sample_id); - id_vector_temp.push_back(dest_tile_pixel_x); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - source_tile_pixel_x = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + source_tile_pixel_x = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, + dest_tile_pixel_x, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } } } @@ -2882,26 +2848,20 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( source_sample_id, builder.makeUintConstant(1)); } else { - id_vector_temp.clear(); - id_vector_temp.push_back(source_sample_id); - id_vector_temp.push_back(source_sample_id); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_sample_id = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_sample_id, + source_sample_id, builder.makeUintConstant(1), + builder.makeUintConstant(1)); } } else { // 1x -> 4x. // Vertical samples (second bit) to Y pixels. - id_vector_temp.clear(); - id_vector_temp.push_back( + source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, builder.createBinOp(spv::OpShiftRightLogical, type_uint, - dest_sample_id, builder.makeUintConstant(1))); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - source_tile_pixel_y = - builder.createOp(spv::OpBitFieldInsert, type_uint, id_vector_temp); + dest_sample_id, builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } } else { // 1x/2x -> different 1x/2x. @@ -2917,13 +2877,10 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( source_sample_id, builder.makeUintConstant(1)); } else { - id_vector_temp.clear(); - id_vector_temp.push_back(source_sample_id); - id_vector_temp.push_back(source_sample_id); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - source_sample_id = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_sample_id, + source_sample_id, builder.makeUintConstant(1), + builder.makeUintConstant(1)); } source_tile_pixel_y = builder.createBinOp(spv::OpShiftRightLogical, type_uint, @@ -2934,25 +2891,19 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // second bit for 2x as 4x) of 2x destination to vertical pixels of 1x // source. if (msaa_2x_attachments_supported_) { - id_vector_temp.clear(); - id_vector_temp.push_back( + source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, builder.createBinOp(spv::OpBitwiseXor, type_uint, dest_sample_id, - builder.makeUintConstant(1))); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - source_tile_pixel_y = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } else { - id_vector_temp.clear(); - id_vector_temp.push_back( + source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, builder.createBinOp(spv::OpShiftRightLogical, type_uint, - dest_sample_id, builder.makeUintConstant(1))); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - source_tile_pixel_y = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + dest_sample_id, builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } } } @@ -3183,19 +3134,16 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( source_color[i][0], unorm_scale), unorm_round_offset)); for (uint32_t j = 1; j < 4; ++j) { - id_vector_temp.clear(); - id_vector_temp.push_back(packed[i]); - id_vector_temp.push_back(builder.createUnaryOp( - spv::OpConvertFToU, type_uint, - builder.createBinOp( - spv::OpFAdd, type_float, - builder.createBinOp(spv::OpFMul, type_float, - source_color[i][j], unorm_scale), - unorm_round_offset))); - id_vector_temp.push_back(builder.makeUintConstant(8 * j)); - id_vector_temp.push_back(component_width); - packed[i] = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + packed[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[i], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + source_color[i][j], unorm_scale), + unorm_round_offset)), + builder.makeUintConstant(8 * j), component_width); } } } break; @@ -3215,20 +3163,18 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( source_color[i][0], unorm_scale_rgb), unorm_round_offset)); for (uint32_t j = 1; j < 4; ++j) { - id_vector_temp.clear(); - id_vector_temp.push_back(packed[i]); - id_vector_temp.push_back(builder.createUnaryOp( - spv::OpConvertFToU, type_uint, - builder.createBinOp( - spv::OpFAdd, type_float, + packed[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[i], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, builder.createBinOp( - spv::OpFMul, type_float, source_color[i][j], - j == 3 ? unorm_scale_a : unorm_scale_rgb), - unorm_round_offset))); - id_vector_temp.push_back(builder.makeUintConstant(10 * j)); - id_vector_temp.push_back(j == 3 ? width_a : width_rgb); - packed[i] = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + spv::OpFAdd, type_float, + builder.createBinOp( + spv::OpFMul, type_float, source_color[i][j], + j == 3 ? unorm_scale_a : unorm_scale_rgb), + unorm_round_offset)), + builder.makeUintConstant(10 * j), + j == 3 ? width_a : width_rgb); } } } break; @@ -3248,37 +3194,26 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( packed[i] = SpirvShaderTranslator::UnclampedFloat32To7e3( builder, source_color[i][0], ext_inst_glsl_std_450); for (uint32_t j = 1; j < 3; ++j) { - id_vector_temp.clear(); - id_vector_temp.push_back(packed[i]); - id_vector_temp.push_back( + packed[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[i], SpirvShaderTranslator::UnclampedFloat32To7e3( - builder, source_color[i][j], ext_inst_glsl_std_450)); - id_vector_temp.push_back(builder.makeUintConstant(10 * j)); - id_vector_temp.push_back(width_rgb); - packed[i] = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + builder, source_color[i][j], ext_inst_glsl_std_450), + builder.makeUintConstant(10 * j), width_rgb); } // Saturate and convert the alpha. - id_vector_temp.clear(); - id_vector_temp.push_back(source_color[i][3]); - id_vector_temp.push_back(float_0); - id_vector_temp.push_back(float_1); - spv::Id alpha_saturated = - builder.createBuiltinCall(type_float, ext_inst_glsl_std_450, - GLSLstd450NClamp, id_vector_temp); - id_vector_temp.clear(); - id_vector_temp.push_back(packed[i]); - id_vector_temp.push_back(builder.createUnaryOp( - spv::OpConvertFToU, type_uint, - builder.createBinOp( - spv::OpFAdd, type_float, - builder.createBinOp(spv::OpFMul, type_float, - alpha_saturated, unorm_scale_a), - unorm_round_offset))); - id_vector_temp.push_back(offset_a); - id_vector_temp.push_back(width_a); - packed[i] = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + spv::Id alpha_saturated = builder.createTriBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, + source_color[i][3], float_0, float_1); + packed[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[i], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + alpha_saturated, unorm_scale_a), + unorm_round_offset)), + offset_a, width_a); } } break; // All 64bpp formats, and all 16 bits per component formats, are @@ -3295,13 +3230,10 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( spv::Id component_offset_width = builder.makeUintConstant(16); spv::Id color_16_in_32[2]; for (uint32_t i = 0; i < 2; ++i) { - id_vector_temp.clear(); - id_vector_temp.push_back(source_color[i][0]); - id_vector_temp.push_back(source_color[i][1]); - id_vector_temp.push_back(component_offset_width); - id_vector_temp.push_back(component_offset_width); - color_16_in_32[i] = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + color_16_in_32[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_color[i][0], + source_color[i][1], component_offset_width, + component_offset_width); } id_vector_temp.clear(); id_vector_temp.push_back(color_16_in_32[0]); @@ -3326,13 +3258,10 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( spv::Id component_offset_width = builder.makeUintConstant(16); spv::Id color_16_in_32[2]; for (uint32_t i = 0; i < 2; ++i) { - id_vector_temp.clear(); - id_vector_temp.push_back(source_color[0][i << 1]); - id_vector_temp.push_back(source_color[0][(i << 1) + 1]); - id_vector_temp.push_back(component_offset_width); - id_vector_temp.push_back(component_offset_width); - color_16_in_32[i] = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + color_16_in_32[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_color[0][i << 1], + source_color[0][(i << 1) + 1], component_offset_width, + component_offset_width); } id_vector_temp.clear(); id_vector_temp.push_back(color_16_in_32[0]); @@ -3383,14 +3312,13 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // Round to the nearest even integer. This seems to be the // correct conversion, adding +0.5 and rounding towards zero results // in red instead of black in the 4D5307E6 clear shader. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpFMul, type_float, source_depth_float[i], - builder.makeFloatConstant(float(0xFFFFFF)))); depth24 = builder.createUnaryOp( spv::OpConvertFToU, type_uint, - builder.createBuiltinCall(type_float, ext_inst_glsl_std_450, - GLSLstd450RoundEven, id_vector_temp)); + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp( + spv::OpFMul, type_float, source_depth_float[i], + builder.makeFloatConstant(float(0xFFFFFF))))); } break; case xenos::DepthRenderTargetFormat::kD24FS8: { depth24 = SpirvShaderTranslator::PreClampedDepthTo20e4( @@ -3399,13 +3327,9 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( } break; } // Merge depth and stencil. - id_vector_temp.clear(); - id_vector_temp.push_back(source_stencil[i]); - id_vector_temp.push_back(depth24); - id_vector_temp.push_back(depth_offset); - id_vector_temp.push_back(depth_width); - packed[i] = - builder.createOp(spv::OpBitFieldInsert, type_uint, id_vector_temp); + packed[i] = builder.createQuadOp(spv::OpBitFieldInsert, type_uint, + source_stencil[i], depth24, + depth_offset, depth_width); } } // Common path unless there was a specialized one - unpack two packed 32-bit @@ -3509,21 +3433,18 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( if (mode.output != TransferOutput::kStencilBit) { spv::Id component_width = builder.makeUintConstant(8); for (uint32_t i = 1; i < 4 - packed_component_offset; ++i) { - id_vector_temp.clear(); - id_vector_temp.push_back(packed); - id_vector_temp.push_back(builder.createUnaryOp( - spv::OpConvertFToU, type_uint, - builder.createBinOp( - spv::OpFAdd, type_float, + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed, + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, builder.createBinOp( - spv::OpFMul, type_float, - source_color[0][packed_component_offset + i], - unorm_scale), - unorm_round_offset))); - id_vector_temp.push_back(builder.makeUintConstant(8 * i)); - id_vector_temp.push_back(component_width); - packed = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + spv::OpFAdd, type_float, + builder.createBinOp( + spv::OpFMul, type_float, + source_color[0][packed_component_offset + i], + unorm_scale), + unorm_round_offset)), + builder.makeUintConstant(8 * i), component_width); } } } @@ -3557,20 +3478,18 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( spv::Id unorm_scale_a = builder.makeFloatConstant(3.0f); spv::Id width_a = builder.makeUintConstant(2); for (uint32_t i = 1; i < 4; ++i) { - id_vector_temp.clear(); - id_vector_temp.push_back(packed); - id_vector_temp.push_back(builder.createUnaryOp( - spv::OpConvertFToU, type_uint, - builder.createBinOp( - spv::OpFAdd, type_float, + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed, + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, builder.createBinOp( - spv::OpFMul, type_float, source_color[0][i], - i == 3 ? unorm_scale_a : unorm_scale_rgb), - unorm_round_offset))); - id_vector_temp.push_back(builder.makeUintConstant(10 * i)); - id_vector_temp.push_back(i == 3 ? width_a : width_rgb); - packed = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + spv::OpFAdd, type_float, + builder.createBinOp( + spv::OpFMul, type_float, source_color[0][i], + i == 3 ? unorm_scale_a : unorm_scale_rgb), + unorm_round_offset)), + builder.makeUintConstant(10 * i), + i == 3 ? width_a : width_rgb); } } } @@ -3598,38 +3517,28 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( if (mode.output != TransferOutput::kStencilBit) { spv::Id width_rgb = builder.makeUintConstant(10); for (uint32_t i = 1; i < 3; ++i) { - id_vector_temp.clear(); - id_vector_temp.push_back(packed); - id_vector_temp.push_back( + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed, SpirvShaderTranslator::UnclampedFloat32To7e3( - builder, source_color[0][i], ext_inst_glsl_std_450)); - id_vector_temp.push_back(builder.makeUintConstant(10 * i)); - id_vector_temp.push_back(width_rgb); - packed = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + builder, source_color[0][i], ext_inst_glsl_std_450), + builder.makeUintConstant(10 * i), width_rgb); } // Saturate and convert the alpha. - id_vector_temp.clear(); - id_vector_temp.push_back(source_color[0][3]); - id_vector_temp.push_back(builder.makeFloatConstant(0.0f)); - id_vector_temp.push_back(builder.makeFloatConstant(1.0f)); - spv::Id alpha_saturated = - builder.createBuiltinCall(type_float, ext_inst_glsl_std_450, - GLSLstd450NClamp, id_vector_temp); - id_vector_temp.clear(); - id_vector_temp.push_back(packed); - id_vector_temp.push_back(builder.createUnaryOp( - spv::OpConvertFToU, type_uint, - builder.createBinOp( - spv::OpFAdd, type_float, - builder.createBinOp(spv::OpFMul, type_float, - alpha_saturated, - builder.makeFloatConstant(3.0f)), - builder.makeFloatConstant(0.5f)))); - id_vector_temp.push_back(builder.makeUintConstant(30)); - id_vector_temp.push_back(builder.makeUintConstant(2)); - packed = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + spv::Id alpha_saturated = builder.createTriBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, + source_color[0][3], builder.makeFloatConstant(0.0f), + builder.makeFloatConstant(1.0f)); + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed, + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + alpha_saturated, + builder.makeFloatConstant(3.0f)), + builder.makeFloatConstant(0.5f))), + builder.makeUintConstant(30), builder.makeUintConstant(2)); } } } break; @@ -3659,13 +3568,9 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( packed = source_color[0][0]; if (mode.output != TransferOutput::kStencilBit) { spv::Id component_offset_width = builder.makeUintConstant(16); - id_vector_temp.clear(); - id_vector_temp.push_back(packed); - id_vector_temp.push_back(source_color[0][1]); - id_vector_temp.push_back(component_offset_width); - id_vector_temp.push_back(component_offset_width); - packed = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed, source_color[0][1], + component_offset_width, component_offset_width); } } } break; @@ -3689,14 +3594,13 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // Round to the nearest even integer. This seems to be the correct // conversion, adding +0.5 and rounding towards zero results in red // instead of black in the 4D5307E6 clear shader. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpFMul, type_float, source_depth_float[0], - builder.makeFloatConstant(float(0xFFFFFF)))); packed = builder.createUnaryOp( spv::OpConvertFToU, type_uint, - builder.createBuiltinCall(type_float, ext_inst_glsl_std_450, - GLSLstd450RoundEven, id_vector_temp)); + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp( + spv::OpFMul, type_float, source_depth_float[0], + builder.makeFloatConstant(float(0xFFFFFF))))); } break; case xenos::DepthRenderTargetFormat::kD24FS8: { packed = SpirvShaderTranslator::PreClampedDepthTo20e4( @@ -3708,13 +3612,9 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( packed_only_depth = true; } else { // Merge depth and stencil. - id_vector_temp.clear(); - id_vector_temp.push_back(source_stencil[0]); - id_vector_temp.push_back(packed); - id_vector_temp.push_back(builder.makeUintConstant(8)); - id_vector_temp.push_back(builder.makeUintConstant(24)); - packed = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + packed = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_stencil[0], packed, + builder.makeUintConstant(8), builder.makeUintConstant(24)); } } } @@ -3861,23 +3761,18 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // first bit for native 2x or 0/1 in the second bit for 2x as // 4x) to second sample bit. if (msaa_2x_attachments_supported_) { - id_vector_temp.clear(); - id_vector_temp.push_back(dest_tile_pixel_x); - id_vector_temp.push_back(builder.createBinOp( - spv::OpBitwiseXor, type_uint, dest_sample_id, - builder.makeUintConstant(1))); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - host_depth_source_sample_id = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + host_depth_source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_tile_pixel_x, + builder.createBinOp(spv::OpBitwiseXor, type_uint, + dest_sample_id, + builder.makeUintConstant(1)), + builder.makeUintConstant(1), + builder.makeUintConstant(31)); } else { - id_vector_temp.clear(); - id_vector_temp.push_back(dest_sample_id); - id_vector_temp.push_back(dest_tile_pixel_x); - id_vector_temp.push_back(builder.makeUintConstant(0)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - host_depth_source_sample_id = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + host_depth_source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, + dest_tile_pixel_x, builder.makeUintConstant(0), + builder.makeUintConstant(1)); } host_depth_source_tile_pixel_x = builder.createBinOp( spv::OpShiftRightLogical, type_uint, dest_tile_pixel_x, @@ -3885,15 +3780,13 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( } else { // 4x -> 1x. // Pixels to samples. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpBitwiseAnd, type_uint, dest_tile_pixel_x, - builder.makeUintConstant(1))); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - host_depth_source_sample_id = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + host_depth_source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpBitwiseAnd, type_uint, + dest_tile_pixel_x, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(1)); host_depth_source_tile_pixel_x = builder.createBinOp( spv::OpShiftRightLogical, type_uint, dest_tile_pixel_x, builder.makeUintConstant(1)); @@ -3906,13 +3799,10 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // Only the X part - Y is handled by common code. if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { // Horizontal samples to pixels. - id_vector_temp.clear(); - id_vector_temp.push_back(dest_sample_id); - id_vector_temp.push_back(dest_tile_pixel_x); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - host_depth_source_tile_pixel_x = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + host_depth_source_tile_pixel_x = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, + dest_tile_pixel_x, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } } // Host depth source Y and sample index for 1x/2x AA sources. @@ -3935,26 +3825,23 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( host_depth_source_sample_id, builder.makeUintConstant(1)); } else { - id_vector_temp.clear(); - id_vector_temp.push_back(host_depth_source_sample_id); - id_vector_temp.push_back(host_depth_source_sample_id); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - host_depth_source_sample_id = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + host_depth_source_sample_id = + builder.createQuadOp(spv::OpBitFieldInsert, type_uint, + host_depth_source_sample_id, + host_depth_source_sample_id, + builder.makeUintConstant(1), + builder.makeUintConstant(1)); } } else { // 1x -> 4x. // Vertical samples (second bit) to Y pixels. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpShiftRightLogical, type_uint, dest_sample_id, - builder.makeUintConstant(1))); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - host_depth_source_tile_pixel_y = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + host_depth_source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpShiftRightLogical, type_uint, + dest_sample_id, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } } else { // 1x/2x -> different 1x/2x. @@ -3972,13 +3859,12 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( host_depth_source_sample_id, builder.makeUintConstant(1)); } else { - id_vector_temp.clear(); - id_vector_temp.push_back(host_depth_source_sample_id); - id_vector_temp.push_back(host_depth_source_sample_id); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(1)); - host_depth_source_sample_id = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + host_depth_source_sample_id = + builder.createQuadOp(spv::OpBitFieldInsert, type_uint, + host_depth_source_sample_id, + host_depth_source_sample_id, + builder.makeUintConstant(1), + builder.makeUintConstant(1)); } host_depth_source_tile_pixel_y = builder.createBinOp( spv::OpShiftRightLogical, type_uint, dest_tile_pixel_y, @@ -3989,25 +3875,21 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // 0/1 in the second bit for 2x as 4x) of 2x destination to // vertical pixels of 1x source. if (msaa_2x_attachments_supported_) { - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpBitwiseXor, type_uint, dest_sample_id, - builder.makeUintConstant(1))); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - host_depth_source_tile_pixel_y = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + host_depth_source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpBitwiseXor, type_uint, + dest_sample_id, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } else { - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpShiftRightLogical, type_uint, dest_sample_id, - builder.makeUintConstant(1))); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - host_depth_source_tile_pixel_y = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + host_depth_source_tile_pixel_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpShiftRightLogical, + type_uint, dest_sample_id, + builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } } } @@ -4117,28 +3999,23 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( if (key.dest_msaa_samples >= xenos::MsaaSamples::k2X) { if (key.dest_msaa_samples >= xenos::MsaaSamples::k4X) { // Horizontal sample index in bit 0. - id_vector_temp.clear(); - id_vector_temp.push_back(dest_sample_id); - id_vector_temp.push_back(dest_tile_pixel_x); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - dest_tile_sample_x = builder.createOp( - spv::OpBitFieldInsert, type_uint, id_vector_temp); + dest_tile_sample_x = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, dest_sample_id, + dest_tile_pixel_x, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } // Vertical sample index as 1 or 0 in bit 0 for true 2x or as 0 // or 1 in bit 1 for 4x or for 2x emulated as 4x. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - (key.dest_msaa_samples == xenos::MsaaSamples::k2X && - msaa_2x_attachments_supported_) - ? spv::OpBitwiseXor - : spv::OpShiftRightLogical, - type_uint, dest_sample_id, builder.makeUintConstant(1))); - id_vector_temp.push_back(dest_tile_pixel_y); - id_vector_temp.push_back(builder.makeUintConstant(1)); - id_vector_temp.push_back(builder.makeUintConstant(31)); - dest_tile_sample_y = builder.createOp(spv::OpBitFieldInsert, - type_uint, id_vector_temp); + dest_tile_sample_y = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp( + (key.dest_msaa_samples == xenos::MsaaSamples::k2X && + msaa_2x_attachments_supported_) + ? spv::OpBitwiseXor + : spv::OpShiftRightLogical, + type_uint, dest_sample_id, builder.makeUintConstant(1)), + dest_tile_pixel_y, builder.makeUintConstant(1), + builder.makeUintConstant(31)); } // Combine the tile sample index and the tile index. // The tile index doesn't need to be wrapped, as the host depth is @@ -4184,15 +4061,13 @@ VkShaderModule VulkanRenderTargetCache::GetTransferShader( // Round to the nearest even integer. This seems to be the // correct conversion, adding +0.5 and rounding towards zero // results in red instead of black in the 4D5307E6 clear shader. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpFMul, type_float, host_depth32, - builder.makeFloatConstant(float(0xFFFFFF)))); host_depth24 = builder.createUnaryOp( spv::OpConvertFToU, type_uint, - builder.createBuiltinCall(type_float, ext_inst_glsl_std_450, - GLSLstd450RoundEven, - id_vector_temp)); + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp( + spv::OpFMul, type_float, host_depth32, + builder.makeFloatConstant(float(0xFFFFFF))))); } break; case xenos::DepthRenderTargetFormat::kD24FS8: { host_depth24 = SpirvShaderTranslator::PreClampedDepthTo20e4( @@ -5817,14 +5692,11 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) { source_sample_x, const_uint_1); // 4x MSAA source texture sample index - bit 0 for horizontal, bit 1 for // vertical. - id_vector_temp.clear(); - id_vector_temp.push_back(builder.createBinOp( - spv::OpBitwiseAnd, type_uint, source_sample_x, const_uint_1)); - id_vector_temp.push_back(source_sample_y); - id_vector_temp.push_back(const_uint_1); - id_vector_temp.push_back(const_uint_1); - source_sample_id = - builder.createOp(spv::OpBitFieldInsert, type_uint, id_vector_temp); + source_sample_id = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createBinOp(spv::OpBitwiseAnd, type_uint, source_sample_x, + const_uint_1), + source_sample_y, const_uint_1, const_uint_1); } else { // 2x MSAA source texture sample index - convert from the guest to // the Vulkan standard sample locations. @@ -5880,14 +5752,13 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) { // Round to the nearest even integer. This seems to be the correct // conversion, adding +0.5 and rounding towards zero results in red // instead of black in the 4D5307E6 clear shader. - id_vector_temp.clear(); - id_vector_temp.push_back( - builder.createBinOp(spv::OpFMul, type_float, source_depth32, - builder.makeFloatConstant(float(0xFFFFFF)))); packed[0] = builder.createUnaryOp( spv::OpConvertFToU, type_uint, - builder.createBuiltinCall(type_float, ext_inst_glsl_std_450, - GLSLstd450RoundEven, id_vector_temp)); + builder.createUnaryBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450RoundEven, + builder.createBinOp( + spv::OpFMul, type_float, source_depth32, + builder.makeFloatConstant(float(0xFFFFFF))))); } break; case xenos::DepthRenderTargetFormat::kD24FS8: { packed[0] = SpirvShaderTranslator::PreClampedDepthTo20e4( @@ -5895,13 +5766,9 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) { ext_inst_glsl_std_450); } break; } - id_vector_temp.clear(); - id_vector_temp.push_back(source_stencil); - id_vector_temp.push_back(packed[0]); - id_vector_temp.push_back(builder.makeUintConstant(8)); - id_vector_temp.push_back(builder.makeUintConstant(24)); - packed[0] = - builder.createOp(spv::OpBitFieldInsert, type_uint, id_vector_temp); + packed[0] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, source_stencil, packed[0], + builder.makeUintConstant(8), builder.makeUintConstant(24)); } else { switch (key.GetColorFormat()) { case xenos::ColorRenderTargetFormat::k_8_8_8_8: @@ -5919,21 +5786,18 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) { unorm_round_offset)); spv::Id component_width = builder.makeUintConstant(8); for (uint32_t i = 1; i < 4; ++i) { - id_vector_temp.clear(); - id_vector_temp.push_back(packed[0]); - id_vector_temp.push_back(builder.createUnaryOp( - spv::OpConvertFToU, type_uint, - builder.createBinOp( - spv::OpFAdd, type_float, - builder.createBinOp(spv::OpFMul, type_float, - builder.createCompositeExtract( - source_vec4, type_float, i), - unorm_scale), - unorm_round_offset))); - id_vector_temp.push_back(builder.makeUintConstant(8 * i)); - id_vector_temp.push_back(component_width); - packed[0] = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + packed[0] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[0], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + builder.createCompositeExtract( + source_vec4, type_float, i), + unorm_scale), + unorm_round_offset)), + builder.makeUintConstant(8 * i), component_width); } } break; case xenos::ColorRenderTargetFormat::k_2_10_10_10: @@ -5953,21 +5817,19 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) { spv::Id unorm_scale_a = builder.makeFloatConstant(3.0f); spv::Id width_a = builder.makeUintConstant(2); for (uint32_t i = 1; i < 4; ++i) { - id_vector_temp.clear(); - id_vector_temp.push_back(packed[0]); - id_vector_temp.push_back(builder.createUnaryOp( - spv::OpConvertFToU, type_uint, - builder.createBinOp( - spv::OpFAdd, type_float, - builder.createBinOp(spv::OpFMul, type_float, - builder.createCompositeExtract( - source_vec4, type_float, i), - i == 3 ? unorm_scale_a : unorm_scale_rgb), - unorm_round_offset))); - id_vector_temp.push_back(builder.makeUintConstant(10 * i)); - id_vector_temp.push_back(i == 3 ? width_a : width_rgb); - packed[0] = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + packed[0] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[0], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp( + spv::OpFMul, type_float, + builder.createCompositeExtract(source_vec4, + type_float, i), + i == 3 ? unorm_scale_a : unorm_scale_rgb), + unorm_round_offset)), + builder.makeUintConstant(10 * i), i == 3 ? width_a : width_rgb); } } break; case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT: @@ -5979,39 +5841,30 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) { ext_inst_glsl_std_450); spv::Id width_rgb = builder.makeUintConstant(10); for (uint32_t i = 1; i < 3; ++i) { - id_vector_temp.clear(); - id_vector_temp.push_back(packed[0]); - id_vector_temp.push_back(SpirvShaderTranslator::UnclampedFloat32To7e3( - builder, - builder.createCompositeExtract(source_vec4, type_float, i), - ext_inst_glsl_std_450)); - id_vector_temp.push_back(builder.makeUintConstant(10 * i)); - id_vector_temp.push_back(width_rgb); - packed[0] = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); - // Saturate and convert the alpha. - id_vector_temp.clear(); - id_vector_temp.push_back( - builder.createCompositeExtract(source_vec4, type_float, 3)); - id_vector_temp.push_back(builder.makeFloatConstant(0.0f)); - id_vector_temp.push_back(builder.makeFloatConstant(1.0f)); - spv::Id alpha_saturated = - builder.createBuiltinCall(type_float, ext_inst_glsl_std_450, - GLSLstd450NClamp, id_vector_temp); - id_vector_temp.clear(); - id_vector_temp.push_back(packed[0]); - id_vector_temp.push_back(builder.createUnaryOp( - spv::OpConvertFToU, type_uint, - builder.createBinOp( - spv::OpFAdd, type_float, - builder.createBinOp(spv::OpFMul, type_float, alpha_saturated, - builder.makeFloatConstant(3.0f)), - builder.makeFloatConstant(0.5f)))); - id_vector_temp.push_back(builder.makeUintConstant(30)); - id_vector_temp.push_back(builder.makeUintConstant(2)); - packed[0] = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + packed[0] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[0], + SpirvShaderTranslator::UnclampedFloat32To7e3( + builder, + builder.createCompositeExtract(source_vec4, type_float, i), + ext_inst_glsl_std_450), + builder.makeUintConstant(10 * i), width_rgb); } + // Saturate and convert the alpha. + spv::Id alpha_saturated = builder.createTriBuiltinCall( + type_float, ext_inst_glsl_std_450, GLSLstd450NClamp, + builder.createCompositeExtract(source_vec4, type_float, 3), + builder.makeFloatConstant(0.0f), builder.makeFloatConstant(1.0f)); + packed[0] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, packed[0], + builder.createUnaryOp( + spv::OpConvertFToU, type_uint, + builder.createBinOp( + spv::OpFAdd, type_float, + builder.createBinOp(spv::OpFMul, type_float, + alpha_saturated, + builder.makeFloatConstant(3.0f)), + builder.makeFloatConstant(0.5f))), + builder.makeUintConstant(30), builder.makeUintConstant(2)); } break; case xenos::ColorRenderTargetFormat::k_16_16: case xenos::ColorRenderTargetFormat::k_16_16_16_16: @@ -6026,15 +5879,11 @@ VkPipeline VulkanRenderTargetCache::GetDumpPipeline(DumpPipelineKey key) { // anyway). spv::Id component_offset_width = builder.makeUintConstant(16); for (uint32_t i = 0; i <= uint32_t(format_is_64bpp); ++i) { - id_vector_temp.clear(); - id_vector_temp.push_back( - builder.createCompositeExtract(source_vec4, type_uint, 2 * i)); - id_vector_temp.push_back(builder.createCompositeExtract( - source_vec4, type_uint, 2 * i + 1)); - id_vector_temp.push_back(component_offset_width); - id_vector_temp.push_back(component_offset_width); - packed[i] = builder.createOp(spv::OpBitFieldInsert, type_uint, - id_vector_temp); + packed[i] = builder.createQuadOp( + spv::OpBitFieldInsert, type_uint, + builder.createCompositeExtract(source_vec4, type_uint, 2 * i), + builder.createCompositeExtract(source_vec4, type_uint, 2 * i + 1), + component_offset_width, component_offset_width); } } break; // Float32 is transferred as uint32 to preserve NaN encodings. However,