[SPIR-V] Wrap NoContraction operations

This commit is contained in:
Triang3l 2023-04-19 11:53:45 +03:00
parent 78f1d55a36
commit 19d56001d2
6 changed files with 276 additions and 456 deletions

View File

@ -25,6 +25,20 @@ class SpirvBuilder : public spv::Builder {
// Make public rather than protected. // Make public rather than protected.
using spv::Builder::createSelectionMerge; 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 } // namespace gpu

View File

@ -1490,9 +1490,8 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
builder_->makeUintConstant( builder_->makeUintConstant(
static_cast<unsigned int>(kSysFlag_WNotReciprocal))), static_cast<unsigned int>(kSysFlag_WNotReciprocal))),
const_uint_0_); 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); spv::OpFDiv, type_float_, const_float_1_, position_w);
builder_->addDecoration(guest_position_w_inv, spv::DecorationNoContraction);
position_w = position_w =
builder_->createTriOp(spv::OpSelect, type_float_, is_w_not_reciprocal, builder_->createTriOp(spv::OpSelect, type_float_, is_w_not_reciprocal,
position_w, guest_position_w_inv); position_w, guest_position_w_inv);
@ -1516,10 +1515,8 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
builder_->makeUintConstant( builder_->makeUintConstant(
static_cast<unsigned int>(kSysFlag_XYDividedByW))), static_cast<unsigned int>(kSysFlag_XYDividedByW))),
const_uint_0_); 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); spv::OpVectorTimesScalar, type_float2_, position_xy, position_w);
builder_->addDecoration(guest_position_xy_mul_w,
spv::DecorationNoContraction);
position_xy = builder_->createTriOp( position_xy = builder_->createTriOp(
spv::OpSelect, type_float2_, spv::OpSelect, type_float2_,
builder_->smearScalar(spv::NoPrecision, is_xy_divided_by_w, builder_->smearScalar(spv::NoPrecision, is_xy_divided_by_w,
@ -1537,10 +1534,8 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
builder_->makeUintConstant( builder_->makeUintConstant(
static_cast<unsigned int>(kSysFlag_ZDividedByW))), static_cast<unsigned int>(kSysFlag_ZDividedByW))),
const_uint_0_); const_uint_0_);
spv::Id guest_position_z_mul_w = spv::Id guest_position_z_mul_w = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFMul, type_float_, position_z, position_w); spv::OpFMul, type_float_, position_z, position_w);
builder_->addDecoration(guest_position_z_mul_w,
spv::DecorationNoContraction);
position_z = position_z =
builder_->createTriOp(spv::OpSelect, type_float_, is_z_divided_by_w, builder_->createTriOp(spv::OpSelect, type_float_, is_z_divided_by_w,
guest_position_z_mul_w, position_z); guest_position_z_mul_w, position_z);
@ -1565,9 +1560,8 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
builder_->createAccessChain(spv::StorageClassUniform, builder_->createAccessChain(spv::StorageClassUniform,
uniform_system_constants_, id_vector_temp_), uniform_system_constants_, id_vector_temp_),
spv::NoPrecision); spv::NoPrecision);
position_xyz = position_xyz = builder_->createNoContractionBinOp(spv::OpFMul, type_float3_,
builder_->createBinOp(spv::OpFMul, type_float3_, position_xyz, ndc_scale); position_xyz, ndc_scale);
builder_->addDecoration(position_xyz, spv::DecorationNoContraction);
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back( id_vector_temp_.push_back(
builder_->makeIntConstant(kSystemConstantNdcOffset)); builder_->makeIntConstant(kSystemConstantNdcOffset));
@ -1575,12 +1569,10 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
builder_->createAccessChain(spv::StorageClassUniform, builder_->createAccessChain(spv::StorageClassUniform,
uniform_system_constants_, id_vector_temp_), uniform_system_constants_, id_vector_temp_),
spv::NoPrecision); 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); spv::OpVectorTimesScalar, type_float3_, ndc_offset, position_w);
builder_->addDecoration(ndc_offset_mul_w, spv::DecorationNoContraction); position_xyz = builder_->createNoContractionBinOp(
position_xyz = builder_->createBinOp(spv::OpFAdd, type_float3_, position_xyz, spv::OpFAdd, type_float3_, position_xyz, ndc_offset_mul_w);
ndc_offset_mul_w);
builder_->addDecoration(position_xyz, spv::DecorationNoContraction);
// Write the point size. // Write the point size.
if (output_point_size_ != spv::NoResult) { if (output_point_size_ != spv::NoResult) {
@ -1666,36 +1658,29 @@ void SpirvShaderTranslator::CompleteVertexOrTessEvalShaderInMain() {
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(builder_->makeIntConstant( id_vector_temp_.push_back(builder_->makeIntConstant(
kSystemConstantPointScreenDiameterToNdcRadius)); kSystemConstantPointScreenDiameterToNdcRadius));
spv::Id point_radius = builder_->createBinOp( spv::Id point_radius = builder_->createNoContractionBinOp(
spv::OpFMul, type_float2_, point_guest_diameter, spv::OpFMul, type_float2_, point_guest_diameter,
builder_->createLoad(builder_->createAccessChain( builder_->createLoad(builder_->createAccessChain(
spv::StorageClassUniform, spv::StorageClassUniform,
uniform_system_constants_, id_vector_temp_), uniform_system_constants_, id_vector_temp_),
spv::NoPrecision)); spv::NoPrecision));
builder_->addDecoration(point_radius, spv::DecorationNoContraction);
// Transform the radius from the normalized device coordinates to the clip // Transform the radius from the normalized device coordinates to the clip
// space. // space.
point_radius = builder_->createBinOp(spv::OpVectorTimesScalar, type_float2_, point_radius = builder_->createNoContractionBinOp(
point_radius, position_w); spv::OpVectorTimesScalar, type_float2_, point_radius, position_w);
builder_->addDecoration(point_radius, spv::DecorationNoContraction);
// Apply the direction of expansion for the current host vertex. // Expand the point sprite in the direction 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.
uint_vector_temp_.clear(); uint_vector_temp_.clear();
uint_vector_temp_.push_back(0); uint_vector_temp_.push_back(0);
uint_vector_temp_.push_back(1); uint_vector_temp_.push_back(1);
spv::Id point_position_xy = builder_->createBinOp( spv::Id point_position_xy = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float2_, spv::OpFAdd, type_float2_,
builder_->createRvalueSwizzle(spv::NoPrecision, type_float2_, builder_->createRvalueSwizzle(spv::NoPrecision, type_float2_,
position_xyz, uint_vector_temp_), position_xyz, uint_vector_temp_),
builder_->createTriOp(spv::OpSelect, type_float2_, builder_->createTriOp(spv::OpSelect, type_float2_,
point_vertex_positive, point_radius, point_vertex_positive, point_radius,
point_radius_negative)); builder_->createNoContractionUnaryOp(
builder_->addDecoration(point_position_xy, spv::DecorationNoContraction); spv::OpFNegate, type_float2_, point_radius)));
// Store the position. // Store the position.
spv::Id position; spv::Id position;
{ {
@ -2419,9 +2404,8 @@ spv::Id SpirvShaderTranslator::ApplyOperandModifiers(
} }
if (original_operand.is_negated != invert_negate) { if (original_operand.is_negated != invert_negate) {
EnsureBuildPointAvailable(); EnsureBuildPointAvailable();
operand_value = operand_value = builder_->createNoContractionUnaryOp(spv::OpFNegate, type,
builder_->createUnaryOp(spv::OpFNegate, type, operand_value); operand_value);
builder_->addDecoration(operand_value, spv::DecorationNoContraction);
} }
return operand_value; return operand_value;
} }
@ -3092,29 +3076,28 @@ spv::Id SpirvShaderTranslator::PWLGammaToLinear(spv::Id gamma,
spv::Op value_times_scalar_opcode = spv::Op value_times_scalar_opcode =
is_vector ? spv::OpVectorTimesScalar : spv::OpFMul; is_vector ? spv::OpVectorTimesScalar : spv::OpFMul;
// linear = gamma * (255.0f * 1024.0f) * scale + offset // linear = gamma * (255.0f * 1024.0f) * scale + offset
spv::Id linear = spv::Id linear = builder_->createNoContractionBinOp(
builder_->createBinOp(value_times_scalar_opcode, value_type, gamma, spv::OpFAdd, value_type,
builder_->makeFloatConstant(255.0f * 1024.0f)); builder_->createNoContractionBinOp(
builder_->addDecoration(linear, spv::DecorationNoContraction); spv::OpFMul, value_type,
linear = builder_->createBinOp(spv::OpFMul, value_type, linear, scale); builder_->createNoContractionBinOp(
builder_->addDecoration(linear, spv::DecorationNoContraction); value_times_scalar_opcode, value_type, gamma,
linear = builder_->createBinOp(spv::OpFAdd, value_type, linear, offset); builder_->makeFloatConstant(255.0f * 1024.0f)),
builder_->addDecoration(linear, spv::DecorationNoContraction); scale),
offset);
// linear += trunc(linear * scale) // linear += trunc(linear * scale)
spv::Id linear_integer_term = spv::Id linear_integer_term = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFMul, value_type, linear, scale); spv::OpFMul, value_type, linear, scale);
builder_->addDecoration(linear_integer_term, spv::DecorationNoContraction);
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(linear_integer_term); id_vector_temp_.push_back(linear_integer_term);
linear_integer_term = builder_->createBuiltinCall( linear_integer_term = builder_->createBuiltinCall(
value_type, ext_inst_glsl_std_450_, GLSLstd450Trunc, id_vector_temp_); value_type, ext_inst_glsl_std_450_, GLSLstd450Trunc, id_vector_temp_);
linear = builder_->createBinOp(spv::OpFAdd, value_type, linear, linear = builder_->createNoContractionBinOp(spv::OpFAdd, value_type, linear,
linear_integer_term); linear_integer_term);
builder_->addDecoration(linear, spv::DecorationNoContraction);
// linear *= 1.0f / 1023.0f // linear *= 1.0f / 1023.0f
linear = builder_->createBinOp(value_times_scalar_opcode, value_type, linear, linear = builder_->createNoContractionBinOp(
builder_->makeFloatConstant(1.0f / 1023.0f)); value_times_scalar_opcode, value_type, linear,
builder_->addDecoration(linear, spv::DecorationNoContraction); builder_->makeFloatConstant(1.0f / 1023.0f));
return linear; return linear;
} }
@ -3187,18 +3170,18 @@ spv::Id SpirvShaderTranslator::LinearToPWLGamma(spv::Id linear,
offset_3_or_2, offset_1_or_0); offset_3_or_2, offset_1_or_0);
// gamma = trunc(linear * scale) * (1.0f / 255.0f) + offset // gamma = trunc(linear * scale) * (1.0f / 255.0f) + offset
spv::Id gamma = builder_->createBinOp(spv::OpFMul, value_type, linear, scale); spv::Id gamma = builder_->createNoContractionBinOp(spv::OpFMul, value_type,
builder_->addDecoration(gamma, spv::DecorationNoContraction); linear, scale);
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(gamma); id_vector_temp_.push_back(gamma);
gamma = builder_->createBuiltinCall(value_type, ext_inst_glsl_std_450_, gamma = builder_->createBuiltinCall(value_type, ext_inst_glsl_std_450_,
GLSLstd450Trunc, id_vector_temp_); GLSLstd450Trunc, id_vector_temp_);
gamma = builder_->createBinOp( gamma = builder_->createNoContractionBinOp(
is_vector ? spv::OpVectorTimesScalar : spv::OpFMul, value_type, gamma, spv::OpFAdd, value_type,
builder_->makeFloatConstant(1.0f / 255.0f)); builder_->createNoContractionBinOp(
builder_->addDecoration(gamma, spv::DecorationNoContraction); is_vector ? spv::OpVectorTimesScalar : spv::OpFMul, value_type, gamma,
gamma = builder_->createBinOp(spv::OpFAdd, value_type, gamma, offset); builder_->makeFloatConstant(1.0f / 255.0f)),
builder_->addDecoration(gamma, spv::DecorationNoContraction); offset);
return gamma; return gamma;
} }

View File

@ -188,14 +188,12 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
switch (instr.vector_opcode) { switch (instr.vector_opcode) {
case ucode::AluVectorOpcode::kAdd: { case ucode::AluVectorOpcode::kAdd: {
spv::Id result = builder_->createBinOp( return builder_->createNoContractionBinOp(
spv::OpFAdd, result_type, spv::OpFAdd, result_type,
GetOperandComponents(operand_storage[0], instr.vector_operands[0], GetOperandComponents(operand_storage[0], instr.vector_operands[0],
used_result_components), used_result_components),
GetOperandComponents(operand_storage[1], instr.vector_operands[1], GetOperandComponents(operand_storage[1], instr.vector_operands[1],
used_result_components)); used_result_components));
builder_->addDecoration(result, spv::DecorationNoContraction);
return result;
} }
case ucode::AluVectorOpcode::kMul: case ucode::AluVectorOpcode::kMul:
case ucode::AluVectorOpcode::kMad: { case ucode::AluVectorOpcode::kMad: {
@ -205,9 +203,8 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
GetOperandComponents(operand_storage[i], instr.vector_operands[i], GetOperandComponents(operand_storage[i], instr.vector_operands[i],
used_result_components); used_result_components);
} }
spv::Id result = builder_->createBinOp( spv::Id result = builder_->createNoContractionBinOp(
spv::OpFMul, result_type, multiplicands[0], multiplicands[1]); spv::OpFMul, result_type, multiplicands[0], multiplicands[1]);
builder_->addDecoration(result, spv::DecorationNoContraction);
uint32_t multiplicands_different = uint32_t multiplicands_different =
used_result_components & used_result_components &
~instr.vector_operands[0].GetIdenticalComponents( ~instr.vector_operands[0].GetIdenticalComponents(
@ -302,11 +299,10 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
if (instr.vector_opcode == ucode::AluVectorOpcode::kMad) { if (instr.vector_opcode == ucode::AluVectorOpcode::kMad) {
// Not replacing true `0 + term` with conditional selection of the term // Not replacing true `0 + term` with conditional selection of the term
// because +0 + -0 should result in +0, not -0. // because +0 + -0 should result in +0, not -0.
result = builder_->createBinOp( result = builder_->createNoContractionBinOp(
spv::OpFAdd, result_type, result, spv::OpFAdd, result_type, result,
GetOperandComponents(operand_storage[2], instr.vector_operands[2], GetOperandComponents(operand_storage[2], instr.vector_operands[2],
used_result_components)); used_result_components));
builder_->addDecoration(result, spv::DecorationNoContraction);
} }
return result; return result;
} }
@ -329,10 +325,9 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
} else { } else {
maxa_operand_0_w = operand_0; maxa_operand_0_w = operand_0;
} }
spv::Id maxa_address = spv::Id maxa_address = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFAdd, type_float_, maxa_operand_0_w, spv::OpFAdd, type_float_, maxa_operand_0_w,
builder_->makeFloatConstant(0.5f)); builder_->makeFloatConstant(0.5f));
builder_->addDecoration(maxa_address, spv::DecorationNoContraction);
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(maxa_address); id_vector_temp_.push_back(maxa_address);
maxa_address = maxa_address =
@ -514,10 +509,9 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
operand_components[j] = operand_components[j] =
builder_->createCompositeExtract(operands[j], type_float_, i); builder_->createCompositeExtract(operands[j], type_float_, i);
} }
spv::Id product = spv::Id product = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFMul, type_float_, spv::OpFMul, type_float_, operand_components[0],
operand_components[0], operand_components[1]); operand_components[1]);
builder_->addDecoration(product, spv::DecorationNoContraction);
if (different & (1 << i)) { if (different & (1 << i)) {
// Shader Model 3: +0 or denormal * anything = +-0. // Shader Model 3: +0 or denormal * anything = +-0.
product = ZeroIfAnyOperandIsZero( product = ZeroIfAnyOperandIsZero(
@ -531,16 +525,14 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
result = product; result = product;
continue; continue;
} }
result = result = builder_->createNoContractionBinOp(spv::OpFAdd, type_float_,
builder_->createBinOp(spv::OpFAdd, type_float_, result, product); result, product);
builder_->addDecoration(result, spv::DecorationNoContraction);
} }
if (instr.vector_opcode == ucode::AluVectorOpcode::kDp2Add) { if (instr.vector_opcode == ucode::AluVectorOpcode::kDp2Add) {
result = builder_->createBinOp( result = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float_, result, spv::OpFAdd, type_float_, result,
GetOperandComponents(operand_storage[2], instr.vector_operands[2], GetOperandComponents(operand_storage[2], instr.vector_operands[2],
0b0001)); 0b0001));
builder_->addDecoration(result, spv::DecorationNoContraction);
} }
return result; return result;
} }
@ -574,17 +566,14 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
} }
spv::Id operand_neg[3] = {}; spv::Id operand_neg[3] = {};
if (used_result_components & 0b0001) { if (used_result_components & 0b0001) {
operand_neg[1] = operand_neg[1] = builder_->createNoContractionUnaryOp(
builder_->createUnaryOp(spv::OpFNegate, type_float_, operand[1]); spv::OpFNegate, type_float_, operand[1]);
builder_->addDecoration(operand_neg[1], spv::DecorationNoContraction);
} }
if (used_result_components & 0b0010) { if (used_result_components & 0b0010) {
operand_neg[0] = operand_neg[0] = builder_->createNoContractionUnaryOp(
builder_->createUnaryOp(spv::OpFNegate, type_float_, operand[0]); spv::OpFNegate, type_float_, operand[0]);
builder_->addDecoration(operand_neg[0], spv::DecorationNoContraction); operand_neg[2] = builder_->createNoContractionUnaryOp(
operand_neg[2] = spv::OpFNegate, type_float_, operand[2]);
builder_->createUnaryOp(spv::OpFNegate, type_float_, operand[2]);
builder_->addDecoration(operand_neg[2], spv::DecorationNoContraction);
} }
spv::Id ma_z_result[4] = {}, ma_yx_result[4] = {}; spv::Id ma_z_result[4] = {}, ma_yx_result[4] = {};
@ -724,9 +713,8 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
// Multiply the major axis by 2. // Multiply the major axis by 2.
spv::Id& ma2 = id_vector_temp_[xe::bit_count(used_result_components & spv::Id& ma2 = id_vector_temp_[xe::bit_count(used_result_components &
((1 << 2) - 1))]; ((1 << 2) - 1))];
ma2 = builder_->createBinOp(spv::OpFMul, type_float_, ma2 = builder_->createNoContractionBinOp(
builder_->makeFloatConstant(2.0f), ma2); spv::OpFMul, type_float_, builder_->makeFloatConstant(2.0f), ma2);
builder_->addDecoration(ma2, spv::DecorationNoContraction);
} }
if (used_result_component_count == 1) { if (used_result_component_count == 1) {
// Only one component - not composite. // Only one component - not composite.
@ -817,14 +805,12 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
builder_->createBinOp(spv::OpFOrdEqual, type_bool_, operands_x[0], builder_->createBinOp(spv::OpFOrdEqual, type_bool_, operands_x[0],
const_float_0_), const_float_0_),
builder_->createBinOp(op, type_bool_, operands_x[1], 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_, spv::OpFAdd, type_float_,
builder_->createTriOp(spv::OpSelect, type_float_, condition, builder_->createTriOp(spv::OpSelect, type_float_, condition,
builder_->makeFloatConstant(-1.0f), builder_->makeFloatConstant(-1.0f),
operands_x[0]), operands_x[0]),
const_float_1_); const_float_1_);
builder_->addDecoration(result, spv::DecorationNoContraction);
return result;
} }
case ucode::AluVectorOpcode::kKillEq: case ucode::AluVectorOpcode::kKillEq:
@ -872,9 +858,8 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
(used_result_components & 0b1000) (used_result_components & 0b1000)
? builder_->createCompositeExtract(operands[1], type_float_, 0) ? builder_->createCompositeExtract(operands[1], type_float_, 0)
: operands[1]; : operands[1];
result_y = builder_->createBinOp(spv::OpFMul, type_float_, result_y = builder_->createNoContractionBinOp(
operands_y[0], operands_y[1]); spv::OpFMul, type_float_, operands_y[0], operands_y[1]);
builder_->addDecoration(result_y, spv::DecorationNoContraction);
if (!(instr.vector_operands[0].GetIdenticalComponents( if (!(instr.vector_operands[0].GetIdenticalComponents(
instr.vector_operands[1]) & instr.vector_operands[1]) &
0b0010)) { 0b0010)) {
@ -997,26 +982,22 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
case ucode::AluScalarOpcode::kSubs: { case ucode::AluScalarOpcode::kSubs: {
spv::Id a, b; spv::Id a, b;
GetOperandScalarXY(operand_storage[0], instr.scalar_operands[0], 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); 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::kAddsPrev:
case ucode::AluScalarOpcode::kSubsPrev: { case ucode::AluScalarOpcode::kSubsPrev: {
spv::Id result = builder_->createBinOp( return builder_->createNoContractionBinOp(
spv::Op(kOps[size_t(instr.scalar_opcode)]), type_float_, spv::Op(kOps[size_t(instr.scalar_opcode)]), type_float_,
GetOperandComponents(operand_storage[0], instr.scalar_operands[0], GetOperandComponents(operand_storage[0], instr.scalar_operands[0],
0b0001), 0b0001),
builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision)); builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision));
builder_->addDecoration(result, spv::DecorationNoContraction);
return result;
} }
case ucode::AluScalarOpcode::kMuls: { case ucode::AluScalarOpcode::kMuls: {
spv::Id a, b; spv::Id a, b;
GetOperandScalarXY(operand_storage[0], instr.scalar_operands[0], a, b); GetOperandScalarXY(operand_storage[0], instr.scalar_operands[0], a, b);
spv::Id result = builder_->createBinOp(spv::OpFMul, type_float_, a, b); spv::Id result =
builder_->addDecoration(result, spv::DecorationNoContraction); builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, b);
if (a != b) { if (a != b) {
// Shader Model 3: +0 or denormal * anything = +-0. // Shader Model 3: +0 or denormal * anything = +-0.
result = ZeroIfAnyOperandIsZero( result = ZeroIfAnyOperandIsZero(
@ -1030,8 +1011,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
instr.scalar_operands[0], 0b0001); instr.scalar_operands[0], 0b0001);
spv::Id ps = spv::Id ps =
builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision); builder_->createLoad(var_main_previous_scalar_, spv::NoPrecision);
spv::Id result = builder_->createBinOp(spv::OpFMul, type_float_, a, ps); spv::Id result =
builder_->addDecoration(result, spv::DecorationNoContraction); builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, ps);
// Shader Model 3: +0 or denormal * anything = +-0. // Shader Model 3: +0 or denormal * anything = +-0.
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(ps); id_vector_temp_.push_back(ps);
@ -1056,9 +1037,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
id_vector_temp_.push_back(ps); id_vector_temp_.push_back(ps);
spv::Id ps_abs = builder_->createBuiltinCall( spv::Id ps_abs = builder_->createBuiltinCall(
type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, id_vector_temp_); type_float_, ext_inst_glsl_std_450_, GLSLstd450FAbs, id_vector_temp_);
spv::Id ps_abs_neg = spv::Id ps_abs_neg = builder_->createNoContractionUnaryOp(
builder_->createUnaryOp(spv::OpFNegate, type_float_, ps_abs); spv::OpFNegate, type_float_, ps_abs);
builder_->addDecoration(ps_abs_neg, spv::DecorationNoContraction);
condition = builder_->createBinOp( condition = builder_->createBinOp(
spv::OpLogicalAnd, type_bool_, condition, spv::OpLogicalAnd, type_bool_, condition,
builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_, builder_->createBinOp(spv::OpFOrdGreaterThanEqual, type_bool_,
@ -1076,9 +1056,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
} }
if (!instr.scalar_operands[0].is_absolute_value || if (!instr.scalar_operands[0].is_absolute_value ||
!instr.scalar_operands[0].is_negated) { !instr.scalar_operands[0].is_negated) {
b_abs_neg = b_abs_neg = builder_->createNoContractionUnaryOp(
builder_->createUnaryOp(spv::OpFNegate, type_float_, b_abs_neg); spv::OpFNegate, type_float_, b_abs_neg);
builder_->addDecoration(b_abs_neg, spv::DecorationNoContraction);
} }
condition = builder_->createBinOp( condition = builder_->createBinOp(
spv::OpLogicalAnd, type_bool_, condition, spv::OpLogicalAnd, type_bool_, condition,
@ -1101,8 +1080,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
? GetOperandComponents(operand_storage[0], ? GetOperandComponents(operand_storage[0],
instr.scalar_operands[0], 0b0001) instr.scalar_operands[0], 0b0001)
: b; : b;
product = builder_->createBinOp(spv::OpFMul, type_float_, a, ps); product =
builder_->addDecoration(product, spv::DecorationNoContraction); builder_->createNoContractionBinOp(spv::OpFMul, type_float_, a, ps);
// Shader Model 3: +0 or denormal * anything = +-0. // Shader Model 3: +0 or denormal * anything = +-0.
product = ZeroIfAnyOperandIsZero( product = ZeroIfAnyOperandIsZero(
product, GetAbsoluteOperand(a, instr.scalar_operands[0]), ps_abs); 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) // maxasf: a0 = (int)clamp(floor(src0.a), -256.0, 255.0)
spv::Id maxa_address; spv::Id maxa_address;
if (instr.scalar_opcode == ucode::AluScalarOpcode::kMaxAs) { if (instr.scalar_opcode == ucode::AluScalarOpcode::kMaxAs) {
maxa_address = builder_->createBinOp( maxa_address = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float_, a, builder_->makeFloatConstant(0.5f)); spv::OpFAdd, type_float_, a, builder_->makeFloatConstant(0.5f));
builder_->addDecoration(maxa_address, spv::DecorationNoContraction);
} else { } else {
maxa_address = a; maxa_address = a;
} }
@ -1212,11 +1190,10 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
builder_->makeFloatConstant(-FLT_MAX), result); builder_->makeFloatConstant(-FLT_MAX), result);
} }
case ucode::AluScalarOpcode::kRcpc: { case ucode::AluScalarOpcode::kRcpc: {
spv::Id result = builder_->createBinOp( spv::Id result = builder_->createNoContractionBinOp(
spv::OpFDiv, type_float_, const_float_1_, spv::OpFDiv, type_float_, const_float_1_,
GetOperandComponents(operand_storage[0], instr.scalar_operands[0], GetOperandComponents(operand_storage[0], instr.scalar_operands[0],
0b0001)); 0b0001));
builder_->addDecoration(result, spv::DecorationNoContraction);
result = builder_->createTriOp( result = builder_->createTriOp(
spv::OpSelect, type_float_, spv::OpSelect, type_float_,
builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result,
@ -1229,11 +1206,10 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
builder_->makeFloatConstant(FLT_MAX), result); builder_->makeFloatConstant(FLT_MAX), result);
} }
case ucode::AluScalarOpcode::kRcpf: { case ucode::AluScalarOpcode::kRcpf: {
spv::Id result = builder_->createBinOp( spv::Id result = builder_->createNoContractionBinOp(
spv::OpFDiv, type_float_, const_float_1_, spv::OpFDiv, type_float_, const_float_1_,
GetOperandComponents(operand_storage[0], instr.scalar_operands[0], GetOperandComponents(operand_storage[0], instr.scalar_operands[0],
0b0001)); 0b0001));
builder_->addDecoration(result, spv::DecorationNoContraction);
result = builder_->createTriOp( result = builder_->createTriOp(
spv::OpSelect, type_float_, spv::OpSelect, type_float_,
builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result, builder_->createBinOp(spv::OpFOrdEqual, type_bool_, result,
@ -1250,12 +1226,10 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
return builder_->createUnaryOp(spv::OpBitcast, type_float_, result); return builder_->createUnaryOp(spv::OpBitcast, type_float_, result);
} }
case ucode::AluScalarOpcode::kRcp: { case ucode::AluScalarOpcode::kRcp: {
spv::Id result = builder_->createBinOp( return builder_->createNoContractionBinOp(
spv::OpFDiv, type_float_, const_float_1_, spv::OpFDiv, type_float_, const_float_1_,
GetOperandComponents(operand_storage[0], instr.scalar_operands[0], GetOperandComponents(operand_storage[0], instr.scalar_operands[0],
0b0001)); 0b0001));
builder_->addDecoration(result, spv::DecorationNoContraction);
return result;
} }
case ucode::AluScalarOpcode::kRsqc: { case ucode::AluScalarOpcode::kRsqc: {
id_vector_temp_.clear(); id_vector_temp_.clear();
@ -1328,12 +1302,11 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
const_float_1_, a)); const_float_1_, a));
} }
case ucode::AluScalarOpcode::kSetpPop: { case ucode::AluScalarOpcode::kSetpPop: {
spv::Id a_minus_1 = builder_->createBinOp( spv::Id a_minus_1 = builder_->createNoContractionBinOp(
spv::OpFSub, type_float_, spv::OpFSub, type_float_,
GetOperandComponents(operand_storage[0], instr.scalar_operands[0], GetOperandComponents(operand_storage[0], instr.scalar_operands[0],
0b0001), 0b0001),
const_float_1_); const_float_1_);
builder_->addDecoration(a_minus_1, spv::DecorationNoContraction);
spv::Id predicate = builder_->createBinOp( spv::Id predicate = builder_->createBinOp(
spv::OpFOrdLessThanEqual, type_bool_, a_minus_1, const_float_0_); spv::OpFOrdLessThanEqual, type_bool_, a_minus_1, const_float_0_);
builder_->createStore(predicate, var_main_predicate_); builder_->createStore(predicate, var_main_predicate_);
@ -1377,9 +1350,8 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
operand_storage[0], instr.scalar_operands[0], 0b0001); operand_storage[0], instr.scalar_operands[0], 0b0001);
spv::Id operand_1 = GetOperandComponents( spv::Id operand_1 = GetOperandComponents(
operand_storage[1], instr.scalar_operands[1], 0b0001); operand_storage[1], instr.scalar_operands[1], 0b0001);
spv::Id result = spv::Id result = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFMul, type_float_, operand_0, operand_1); spv::OpFMul, type_float_, operand_0, operand_1);
builder_->addDecoration(result, spv::DecorationNoContraction);
if (!(instr.scalar_operands[0].GetIdenticalComponents( if (!(instr.scalar_operands[0].GetIdenticalComponents(
instr.scalar_operands[1]) & instr.scalar_operands[1]) &
0b0001)) { 0b0001)) {
@ -1394,14 +1366,12 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
case ucode::AluScalarOpcode::kAddsc1: case ucode::AluScalarOpcode::kAddsc1:
case ucode::AluScalarOpcode::kSubsc0: case ucode::AluScalarOpcode::kSubsc0:
case ucode::AluScalarOpcode::kSubsc1: { case ucode::AluScalarOpcode::kSubsc1: {
spv::Id result = builder_->createBinOp( return builder_->createNoContractionBinOp(
spv::Op(kOps[size_t(instr.scalar_opcode)]), type_float_, spv::Op(kOps[size_t(instr.scalar_opcode)]), type_float_,
GetOperandComponents(operand_storage[0], instr.scalar_operands[0], GetOperandComponents(operand_storage[0], instr.scalar_operands[0],
0b0001), 0b0001),
GetOperandComponents(operand_storage[1], instr.scalar_operands[1], GetOperandComponents(operand_storage[1], instr.scalar_operands[1],
0b0001)); 0b0001));
builder_->addDecoration(result, spv::DecorationNoContraction);
return result;
} }
case ucode::AluScalarOpcode::kRetainPrev: case ucode::AluScalarOpcode::kRetainPrev:

View File

@ -80,9 +80,8 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
spv::Id index = GetOperandComponents( spv::Id index = GetOperandComponents(
LoadOperandStorage(instr.operands[0]), instr.operands[0], 0b0001); LoadOperandStorage(instr.operands[0]), instr.operands[0], 0b0001);
if (instr.attributes.is_index_rounded) { if (instr.attributes.is_index_rounded) {
index = builder_->createBinOp(spv::OpFAdd, type_float_, index, index = builder_->createNoContractionBinOp(
builder_->makeFloatConstant(0.5f)); spv::OpFAdd, type_float_, index, builder_->makeFloatConstant(0.5f));
builder_->addDecoration(index, spv::DecorationNoContraction);
} }
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(index); id_vector_temp_.push_back(index);
@ -297,18 +296,16 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
if (instr.attributes.is_signed) { if (instr.attributes.is_signed) {
switch (instr.attributes.signed_rf_mode) { switch (instr.attributes.signed_rf_mode) {
case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne: case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne:
result = builder_->createBinOp( result = builder_->createNoContractionBinOp(
spv::OpVectorTimesScalar, result_type, result, spv::OpVectorTimesScalar, result_type, result,
builder_->makeFloatConstant(1.0f / 2147483647.0f)); 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 // No need to clamp to -1 if signed - 1/(2^31-1) is rounded to
// 1/(2^31) as float32. // 1/(2^31) as float32.
break; break;
case xenos::SignedRepeatingFractionMode::kNoZero: { case xenos::SignedRepeatingFractionMode::kNoZero: {
result = builder_->createBinOp( result = builder_->createNoContractionBinOp(
spv::OpVectorTimesScalar, result_type, result, spv::OpVectorTimesScalar, result_type, result,
builder_->makeFloatConstant(1.0f / 2147483647.5f)); builder_->makeFloatConstant(1.0f / 2147483647.5f));
builder_->addDecoration(result, spv::DecorationNoContraction);
spv::Id const_no_zero = spv::Id const_no_zero =
builder_->makeFloatConstant(0.5f / 2147483647.5f); builder_->makeFloatConstant(0.5f / 2147483647.5f);
if (used_format_component_count > 1) { if (used_format_component_count > 1) {
@ -319,18 +316,16 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
const_no_zero = builder_->makeCompositeConstant( const_no_zero = builder_->makeCompositeConstant(
result_type, id_vector_temp_); result_type, id_vector_temp_);
} }
result = builder_->createBinOp(spv::OpFAdd, result_type, result, result = builder_->createNoContractionBinOp(
const_no_zero); spv::OpFAdd, result_type, result, const_no_zero);
builder_->addDecoration(result, spv::DecorationNoContraction);
} break; } break;
default: default:
assert_unhandled_case(instr.attributes.signed_rf_mode); assert_unhandled_case(instr.attributes.signed_rf_mode);
} }
} else { } else {
result = builder_->createBinOp( result = builder_->createNoContractionBinOp(
spv::OpVectorTimesScalar, result_type, result, spv::OpVectorTimesScalar, result_type, result,
builder_->makeFloatConstant(1.0f / 4294967295.0f)); builder_->makeFloatConstant(1.0f / 4294967295.0f));
builder_->addDecoration(result, spv::DecorationNoContraction);
} }
} }
break; break;
@ -449,9 +444,8 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
} else { } else {
packed_scale_mul_op = spv::OpFMul; packed_scale_mul_op = spv::OpFMul;
} }
result = builder_->createBinOp(packed_scale_mul_op, result_type, result, result = builder_->createNoContractionBinOp(
const_packed_scale); packed_scale_mul_op, result_type, result, const_packed_scale);
builder_->addDecoration(result, spv::DecorationNoContraction);
if (instr.attributes.is_signed) { if (instr.attributes.is_signed) {
switch (instr.attributes.signed_rf_mode) { switch (instr.attributes.signed_rf_mode) {
case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne: { case xenos::SignedRepeatingFractionMode::kZeroClampMinusOne: {
@ -479,13 +473,12 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
id_vector_temp_.push_back( id_vector_temp_.push_back(
builder_->makeFloatConstant(0.5f * packed_scales[i])); builder_->makeFloatConstant(0.5f * packed_scales[i]));
} }
result = result = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFAdd, result_type, result, spv::OpFAdd, result_type, result,
used_format_component_count > 1 used_format_component_count > 1
? builder_->makeCompositeConstant( ? builder_->makeCompositeConstant(result_type,
result_type, id_vector_temp_) id_vector_temp_)
: id_vector_temp_[0]); : id_vector_temp_[0]);
builder_->addDecoration(result, spv::DecorationNoContraction);
break; break;
default: default:
assert_unhandled_case(instr.attributes.signed_rf_mode); assert_unhandled_case(instr.attributes.signed_rf_mode);
@ -497,11 +490,10 @@ void SpirvShaderTranslator::ProcessVertexFetchInstruction(
if (result != spv::NoResult) { if (result != spv::NoResult) {
// Apply the exponent bias. // Apply the exponent bias.
if (instr.attributes.exp_adjust) { if (instr.attributes.exp_adjust) {
result = builder_->createBinOp(spv::OpVectorTimesScalar, result = builder_->createNoContractionBinOp(
builder_->getTypeId(result), result, spv::OpVectorTimesScalar, builder_->getTypeId(result), result,
builder_->makeFloatConstant(std::ldexp( builder_->makeFloatConstant(
1.0f, instr.attributes.exp_adjust))); std::ldexp(1.0f, instr.attributes.exp_adjust)));
builder_->addDecoration(result, spv::DecorationNoContraction);
} }
// If any components not present in the format were requested, pad the // If any components not present in the format were requested, pad the
@ -1102,18 +1094,14 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
if (!instr.attributes.unnormalized_coordinates) { if (!instr.attributes.unnormalized_coordinates) {
spv::Id size_component = size[coordinate_component_index]; spv::Id size_component = size[coordinate_component_index];
assert_true(size_component != spv::NoResult); assert_true(size_component != spv::NoResult);
result_component = builder_->createBinOp( result_component = builder_->createNoContractionBinOp(
spv::OpFMul, type_float_, result_component, size_component); spv::OpFMul, type_float_, result_component, size_component);
builder_->addDecoration(result_component,
spv::DecorationNoContraction);
} }
float component_offset = offset_values[coordinate_component_index]; float component_offset = offset_values[coordinate_component_index];
if (component_offset) { if (component_offset) {
result_component = builder_->createBinOp( result_component = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float_, result_component, spv::OpFAdd, type_float_, result_component,
builder_->makeFloatConstant(component_offset)); builder_->makeFloatConstant(component_offset));
builder_->addDecoration(result_component,
spv::DecorationNoContraction);
} }
// 0.5 has already been subtracted via offsets previously. // 0.5 has already been subtracted via offsets previously.
id_vector_temp_.clear(); id_vector_temp_.clear();
@ -1137,27 +1125,21 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
spv::Id size_component = size[i]; spv::Id size_component = size[i];
if (instr.attributes.unnormalized_coordinates) { if (instr.attributes.unnormalized_coordinates) {
if (component_offset != spv::NoResult) { if (component_offset != spv::NoResult) {
coordinate_ref = builder_->createBinOp( coordinate_ref = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float_, coordinate_ref, component_offset); spv::OpFAdd, type_float_, coordinate_ref, component_offset);
builder_->addDecoration(coordinate_ref,
spv::DecorationNoContraction);
} }
assert_true(size_component != spv::NoResult); assert_true(size_component != spv::NoResult);
coordinate_ref = builder_->createBinOp( coordinate_ref = builder_->createNoContractionBinOp(
spv::OpFDiv, type_float_, coordinate_ref, size_component); spv::OpFDiv, type_float_, coordinate_ref, size_component);
builder_->addDecoration(coordinate_ref, spv::DecorationNoContraction);
} else { } else {
if (component_offset != spv::NoResult) { if (component_offset != spv::NoResult) {
assert_true(size_component != spv::NoResult); assert_true(size_component != spv::NoResult);
spv::Id component_offset_normalized = builder_->createBinOp( spv::Id component_offset_normalized =
spv::OpFDiv, type_float_, component_offset, size_component); builder_->createNoContractionBinOp(
builder_->addDecoration(component_offset_normalized, spv::OpFDiv, type_float_, component_offset, size_component);
spv::DecorationNoContraction); coordinate_ref = builder_->createNoContractionBinOp(
coordinate_ref = spv::OpFAdd, type_float_, coordinate_ref,
builder_->createBinOp(spv::OpFAdd, type_float_, coordinate_ref, component_offset_normalized);
component_offset_normalized);
builder_->addDecoration(coordinate_ref,
spv::DecorationNoContraction);
} }
} }
} }
@ -1170,10 +1152,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
if (instr.attributes.unnormalized_coordinates) { if (instr.attributes.unnormalized_coordinates) {
// Apply the offset, and normalize the Z coordinate for a 3D texture. // Apply the offset, and normalize the Z coordinate for a 3D texture.
if (z_offset != spv::NoResult) { if (z_offset != spv::NoResult) {
z_coordinate_ref = builder_->createBinOp( z_coordinate_ref = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float_, z_coordinate_ref, z_offset); 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_head = *builder_->getBuildPoint();
spv::Block& block_dimension_merge = builder_->makeNewBlock(); spv::Block& block_dimension_merge = builder_->makeNewBlock();
@ -1185,9 +1165,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
&block_dimension_merge); &block_dimension_merge);
builder_->setBuildPoint(&block_dimension_3d); builder_->setBuildPoint(&block_dimension_3d);
assert_true(z_size != spv::NoResult); assert_true(z_size != spv::NoResult);
spv::Id z_3d = builder_->createBinOp(spv::OpFDiv, type_float_, spv::Id z_3d = builder_->createNoContractionBinOp(
z_coordinate_ref, z_size); spv::OpFDiv, type_float_, z_coordinate_ref, z_size);
builder_->addDecoration(z_3d, spv::DecorationNoContraction);
builder_->createBranch(&block_dimension_merge); builder_->createBranch(&block_dimension_merge);
builder_->setBuildPoint(&block_dimension_merge); builder_->setBuildPoint(&block_dimension_merge);
{ {
@ -1222,13 +1201,10 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
builder_->setBuildPoint(block_dimension_3d); builder_->setBuildPoint(block_dimension_3d);
if (z_offset != spv::NoResult) { if (z_offset != spv::NoResult) {
assert_true(z_size != 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); spv::OpFDiv, type_float_, z_offset, z_size);
builder_->addDecoration(z_offset_normalized, z_3d = builder_->createNoContractionBinOp(
spv::DecorationNoContraction); spv::OpFAdd, type_float_, z_3d, z_offset_normalized);
z_3d = builder_->createBinOp(spv::OpFAdd, type_float_, z_3d,
z_offset_normalized);
builder_->addDecoration(z_3d, spv::DecorationNoContraction);
} }
builder_->createBranch(&block_dimension_merge); builder_->createBranch(&block_dimension_merge);
} }
@ -1236,13 +1212,11 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
builder_->setBuildPoint(&block_dimension_stacked); builder_->setBuildPoint(&block_dimension_stacked);
spv::Id z_stacked = z_coordinate_ref; spv::Id z_stacked = z_coordinate_ref;
assert_true(z_size != spv::NoResult); assert_true(z_size != spv::NoResult);
z_stacked = builder_->createBinOp(spv::OpFMul, type_float_, z_stacked, z_stacked = builder_->createNoContractionBinOp(
z_size); spv::OpFMul, type_float_, z_stacked, z_size);
builder_->addDecoration(z_stacked, spv::DecorationNoContraction);
if (z_offset != spv::NoResult) { if (z_offset != spv::NoResult) {
z_stacked = builder_->createBinOp(spv::OpFAdd, type_float_, z_stacked = builder_->createNoContractionBinOp(
z_stacked, z_offset); spv::OpFAdd, type_float_, z_stacked, z_offset);
builder_->addDecoration(z_stacked, spv::DecorationNoContraction);
} }
builder_->createBranch(&block_dimension_merge); builder_->createBranch(&block_dimension_merge);
// Select one of the two. // 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_2 = builder_->makeFloatConstant(2.0f);
spv::Id const_float_minus_3 = builder_->makeFloatConstant(-3.0f); spv::Id const_float_minus_3 = builder_->makeFloatConstant(-3.0f);
for (uint32_t i = 0; i < 2; ++i) { for (uint32_t i = 0; i < 2; ++i) {
spv::Id& coordinate_ref = coordinates[i]; coordinates[i] = builder_->createNoContractionBinOp(
coordinate_ref = builder_->createBinOp(spv::OpFMul, type_float_, spv::OpFAdd, type_float_,
coordinate_ref, const_float_2); builder_->createNoContractionBinOp(spv::OpFMul, type_float_,
builder_->addDecoration(coordinate_ref, spv::DecorationNoContraction); coordinates[i], const_float_2),
coordinate_ref = builder_->createBinOp( const_float_minus_3);
spv::OpFAdd, type_float_, coordinate_ref, const_float_minus_3);
builder_->addDecoration(coordinate_ref, spv::DecorationNoContraction);
} }
// Get the face index (floored, within 0...5 - OpConvertFToU is // Get the face index (floored, within 0...5 - OpConvertFToU is
// undefined for out-of-range values, so clamping from both sides // undefined for out-of-range values, so clamping from both sides
// manually). // manually).
spv::Id face = coordinates[2]; spv::Id face = coordinates[2];
if (offset_values[2]) { if (offset_values[2]) {
face = builder_->createBinOp( face = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float_, face, spv::OpFAdd, type_float_, face,
builder_->makeFloatConstant(offset_values[2])); builder_->makeFloatConstant(offset_values[2]));
builder_->addDecoration(face, spv::DecorationNoContraction);
} }
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(face); id_vector_temp_.push_back(face);
@ -1307,12 +1278,10 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
builder_->makeFloatConstant(-1.0f), builder_->makeFloatConstant(-1.0f),
builder_->makeFloatConstant(1.0f)); builder_->makeFloatConstant(1.0f));
// Remap the axes in a way opposite to the ALU cube instruction. // 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]); spv::OpFNegate, type_float_, coordinates[0]);
builder_->addDecoration(sc_negated, spv::DecorationNoContraction); spv::Id tc_negated = builder_->createNoContractionUnaryOp(
spv::Id tc_negated = builder_->createUnaryOp(
spv::OpFNegate, type_float_, coordinates[1]); spv::OpFNegate, type_float_, coordinates[1]);
builder_->addDecoration(tc_negated, spv::DecorationNoContraction);
spv::Block& block_ma_head = *builder_->getBuildPoint(); spv::Block& block_ma_head = *builder_->getBuildPoint();
spv::Block& block_ma_x = builder_->makeNewBlock(); spv::Block& block_ma_x = builder_->makeNewBlock();
spv::Block& block_ma_y = builder_->makeNewBlock(); spv::Block& block_ma_y = builder_->makeNewBlock();
@ -1578,7 +1547,7 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
// specification order: specified LOD + sampler LOD bias + instruction // specification order: specified LOD + sampler LOD bias + instruction
// LOD bias). // LOD bias).
// Fetch constant LOD (bits 12:21 of the word 4). // Fetch constant LOD (bits 12:21 of the word 4).
spv::Id lod = builder_->createBinOp( spv::Id lod = builder_->createNoContractionBinOp(
spv::OpFMul, type_float_, spv::OpFMul, type_float_,
builder_->createUnaryOp( builder_->createUnaryOp(
spv::OpConvertSToF, type_float_, spv::OpConvertSToF, type_float_,
@ -1587,21 +1556,18 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
builder_->makeUintConstant(12), builder_->makeUintConstant(12),
builder_->makeUintConstant(10))), builder_->makeUintConstant(10))),
builder_->makeFloatConstant(1.0f / 32.0f)); builder_->makeFloatConstant(1.0f / 32.0f));
builder_->addDecoration(lod, spv::DecorationNoContraction);
// Register LOD. // Register LOD.
if (instr.attributes.use_register_lod) { if (instr.attributes.use_register_lod) {
lod = builder_->createBinOp( lod = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float_, spv::OpFAdd, type_float_,
builder_->createLoad(var_main_tfetch_lod_, spv::NoPrecision), builder_->createLoad(var_main_tfetch_lod_, spv::NoPrecision),
lod); lod);
builder_->addDecoration(lod, spv::DecorationNoContraction);
} }
// Instruction LOD bias. // Instruction LOD bias.
if (instr.attributes.lod_bias) { if (instr.attributes.lod_bias) {
lod = builder_->createBinOp( lod = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float_, lod, spv::OpFAdd, type_float_, lod,
builder_->makeFloatConstant(instr.attributes.lod_bias)); builder_->makeFloatConstant(instr.attributes.lod_bias));
builder_->addDecoration(lod, spv::DecorationNoContraction);
} }
// Calculate the gradients for sampling the texture if needed. // Calculate the gradients for sampling the texture if needed.
@ -1639,14 +1605,10 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
if (instr.attributes.unnormalized_coordinates) { if (instr.attributes.unnormalized_coordinates) {
// Normalize the gradients. // Normalize the gradients.
assert_true(size[0] != spv::NoResult); 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]); spv::OpFDiv, type_float_, gradient_h_1d, size[0]);
builder_->addDecoration(gradient_h_1d, gradient_v_1d = builder_->createNoContractionBinOp(
spv::DecorationNoContraction);
gradient_v_1d = builder_->createBinOp(
spv::OpFDiv, type_float_, gradient_v_1d, size[0]); spv::OpFDiv, type_float_, gradient_v_1d, size[0]);
builder_->addDecoration(gradient_v_1d,
spv::DecorationNoContraction);
} }
} else { } else {
builder_->addCapability(spv::CapabilityDerivativeControl); builder_->addCapability(spv::CapabilityDerivativeControl);
@ -1655,14 +1617,10 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
gradient_v_1d = builder_->createUnaryOp( gradient_v_1d = builder_->createUnaryOp(
spv::OpDPdyCoarse, type_float_, coordinates[0]); 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); spv::OpFMul, type_float_, gradient_h_1d, lod_gradient_scale);
builder_->addDecoration(gradient_h_1d, gradient_v_1d = builder_->createNoContractionBinOp(
spv::DecorationNoContraction);
gradient_v_1d = builder_->createBinOp(
spv::OpFMul, type_float_, gradient_v_1d, lod_gradient_scale); 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 // 1D textures are sampled as 2D arrays - need 2-component
// gradients. // gradients.
id_vector_temp_.clear(); id_vector_temp_.clear();
@ -1690,15 +1648,11 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
if (instr.attributes.unnormalized_coordinates) { if (instr.attributes.unnormalized_coordinates) {
// Normalize the gradients. // Normalize the gradients.
assert_true(size[0] != spv::NoResult); 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]); spv::OpFDiv, type_float_, register_gradient_x, size[0]);
builder_->addDecoration(register_gradient_x,
spv::DecorationNoContraction);
assert_true(size[1] != spv::NoResult); 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]); spv::OpFDiv, type_float_, register_gradient_y, size[1]);
builder_->addDecoration(register_gradient_y,
spv::DecorationNoContraction);
} }
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(register_gradient_x); id_vector_temp_.push_back(register_gradient_x);
@ -1723,16 +1677,12 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
builder_->createUnaryOp(spv::OpDPdyCoarse, type_float2_, builder_->createUnaryOp(spv::OpDPdyCoarse, type_float2_,
gradient_coordinate_vector); gradient_coordinate_vector);
} }
gradients_h = gradients_h = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpVectorTimesScalar, type_float2_, spv::OpVectorTimesScalar, type_float2_, gradients_h,
gradients_h, lod_gradient_scale); lod_gradient_scale);
builder_->addDecoration(gradients_h, gradients_v = builder_->createNoContractionBinOp(
spv::DecorationNoContraction); spv::OpVectorTimesScalar, type_float2_, gradients_v,
gradients_v = lod_gradient_scale);
builder_->createBinOp(spv::OpVectorTimesScalar, type_float2_,
gradients_v, lod_gradient_scale);
builder_->addDecoration(gradients_v,
spv::DecorationNoContraction);
} break; } break;
case xenos::FetchOpDimension::k3DOrStacked: { case xenos::FetchOpDimension::k3DOrStacked: {
if (instr.attributes.use_register_gradients) { if (instr.attributes.use_register_gradients) {
@ -1747,13 +1697,12 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
id_vector_temp_.clear(); id_vector_temp_.clear();
for (uint32_t j = 0; j < 3; ++j) { for (uint32_t j = 0; j < 3; ++j) {
assert_true(size[j] != spv::NoResult); assert_true(size[j] != spv::NoResult);
id_vector_temp_.push_back(builder_->createBinOp( id_vector_temp_.push_back(
spv::OpFDiv, type_float_, builder_->createNoContractionBinOp(
builder_->createCompositeExtract(gradient_ref, spv::OpFDiv, type_float_,
type_float_, j), builder_->createCompositeExtract(gradient_ref,
size[j])); type_float_, j),
builder_->addDecoration(id_vector_temp_.back(), size[j]));
spv::DecorationNoContraction);
} }
gradient_ref = builder_->createCompositeConstruct( gradient_ref = builder_->createCompositeConstruct(
type_float3_, id_vector_temp_); type_float3_, id_vector_temp_);
@ -1775,16 +1724,12 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
builder_->createUnaryOp(spv::OpDPdyCoarse, type_float3_, builder_->createUnaryOp(spv::OpDPdyCoarse, type_float3_,
gradient_coordinate_vector); gradient_coordinate_vector);
} }
gradients_h = gradients_h = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_, spv::OpVectorTimesScalar, type_float3_, gradients_h,
gradients_h, lod_gradient_scale); lod_gradient_scale);
builder_->addDecoration(gradients_h, gradients_v = builder_->createNoContractionBinOp(
spv::DecorationNoContraction); spv::OpVectorTimesScalar, type_float3_, gradients_v,
gradients_v = lod_gradient_scale);
builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_,
gradients_v, lod_gradient_scale);
builder_->addDecoration(gradients_v,
spv::DecorationNoContraction);
} break; } break;
case xenos::FetchOpDimension::kCube: { case xenos::FetchOpDimension::kCube: {
if (instr.attributes.use_register_gradients) { if (instr.attributes.use_register_gradients) {
@ -1812,16 +1757,12 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
builder_->createUnaryOp(spv::OpDPdyCoarse, type_float3_, builder_->createUnaryOp(spv::OpDPdyCoarse, type_float3_,
gradient_coordinate_vector); gradient_coordinate_vector);
} }
gradients_h = gradients_h = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_, spv::OpVectorTimesScalar, type_float3_, gradients_h,
gradients_h, lod_gradient_scale); lod_gradient_scale);
builder_->addDecoration(gradients_h, gradients_v = builder_->createNoContractionBinOp(
spv::DecorationNoContraction); spv::OpVectorTimesScalar, type_float3_, gradients_v,
gradients_v = lod_gradient_scale);
builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_,
gradients_v, lod_gradient_scale);
builder_->addDecoration(gradients_v,
spv::DecorationNoContraction);
} break; } break;
} }
} }
@ -1911,10 +1852,8 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
if (!instr.attributes.unnormalized_coordinates) { if (!instr.attributes.unnormalized_coordinates) {
// Denormalize the gradient if provided as normalized. // Denormalize the gradient if provided as normalized.
assert_true(size[2] != spv::NoResult); 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]); spv::OpFMul, type_float_, layer_max_gradient, size[2]);
builder_->addDecoration(layer_max_gradient,
spv::DecorationNoContraction);
} }
// For NaN, considering that magnification is being done. // For NaN, considering that magnification is being done.
spv::Id is_minifying_z = builder_->createBinOp( 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 // 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. // first layer in filtering because 0.5 is in the middle of it.
if (vol_filter_is_linear != spv::NoResult) { 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( layer_coordinate = builder_->createTriOp(
spv::OpSelect, type_float_, vol_filter_is_linear, 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) { } else if (vol_mag_filter_is_linear) {
layer_coordinate = builder_->createBinOp( layer_coordinate = builder_->createNoContractionBinOp(
spv::OpFSub, type_float_, layer_coordinate, spv::OpFSub, type_float_, layer_coordinate,
builder_->makeFloatConstant(0.5f)); builder_->makeFloatConstant(0.5f));
builder_->addDecoration(layer_coordinate,
spv::DecorationNoContraction);
} }
// Sample the first layer, needed regardless of whether filtering is // Sample the first layer, needed regardless of whether filtering is
// needed. // needed.
@ -2324,16 +2259,14 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
// Unsigned biased. // Unsigned biased.
builder_->setBuildPoint(&block_sign_unsigned_biased); builder_->setBuildPoint(&block_sign_unsigned_biased);
spv::Id sample_result_component_unsigned_biased = spv::Id sample_result_component_unsigned_biased =
builder_->createBinOp(spv::OpFMul, type_float_, builder_->createNoContractionBinOp(
sample_result_component_unsigned, spv::OpFMul, type_float_, sample_result_component_unsigned,
const_float_2); const_float_2);
builder_->addDecoration(sample_result_component_unsigned_biased, sample_result_component_unsigned_biased =
spv::DecorationNoContraction); builder_->createNoContractionBinOp(
sample_result_component_unsigned_biased = builder_->createBinOp( spv::OpFAdd, type_float_,
spv::OpFAdd, type_float_, sample_result_component_unsigned_biased,
sample_result_component_unsigned_biased, const_float_minus_1); const_float_minus_1);
builder_->addDecoration(sample_result_component_unsigned_biased,
spv::DecorationNoContraction);
builder_->createBranch(&block_sign_merge); builder_->createBranch(&block_sign_merge);
// Gamma. // Gamma.
builder_->setBuildPoint(&block_sign_gamma_start); builder_->setBuildPoint(&block_sign_gamma_start);
@ -2384,12 +2317,9 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
&result_component_index)) { &result_component_index)) {
result_remaining_components &= result_remaining_components &=
~(UINT32_C(1) << result_component_index); ~(UINT32_C(1) << result_component_index);
spv::Id& result_component_ref = result[result_component_index]; result[result_component_index] = builder_->createNoContractionBinOp(
result_component_ref = builder_->createBinOp( spv::OpFMul, type_float_, result[result_component_index],
spv::OpFMul, type_float_, result_component_ref,
result_exponent_bias); result_exponent_bias);
builder_->addDecoration(result_component_ref,
spv::DecorationNoContraction);
} }
} }
} }
@ -2564,16 +2494,13 @@ void SpirvShaderTranslator::SampleTexture(
if (lerp_factor != spv::NoResult) { if (lerp_factor != spv::NoResult) {
spv::Id lerp_first = i ? lerp_first_signed : lerp_first_unsigned; spv::Id lerp_first = i ? lerp_first_signed : lerp_first_unsigned;
if (lerp_first != spv::NoResult) { if (lerp_first != spv::NoResult) {
spv::Id lerp_difference = builder_->createBinOp( spv::Id lerp_difference = builder_->createNoContractionBinOp(
spv::OpFSub, type_float4_, result, lerp_first); spv::OpVectorTimesScalar, type_float4_,
builder_->addDecoration(lerp_difference, spv::DecorationNoContraction); builder_->createNoContractionBinOp(spv::OpFSub, type_float4_,
lerp_difference = result, lerp_first),
builder_->createBinOp(spv::OpVectorTimesScalar, type_float4_, lerp_factor);
lerp_difference, lerp_factor); result = builder_->createNoContractionBinOp(spv::OpFAdd, type_float4_,
builder_->addDecoration(lerp_difference, spv::DecorationNoContraction); result, lerp_difference);
result = builder_->createBinOp(spv::OpFAdd, type_float4_, result,
lerp_difference);
builder_->addDecoration(result, spv::DecorationNoContraction);
} }
} }
builder_->createBranch(&block_sign_merge); builder_->createBranch(&block_sign_merge);

View File

@ -835,13 +835,12 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() {
builder_->makeIntConstant(kSystemConstantColorExpBias)); builder_->makeIntConstant(kSystemConstantColorExpBias));
id_vector_temp_.push_back( id_vector_temp_.push_back(
builder_->makeIntConstant(int32_t(color_target_index))); builder_->makeIntConstant(int32_t(color_target_index)));
color = builder_->createBinOp( color = builder_->createNoContractionBinOp(
spv::OpVectorTimesScalar, type_float4_, color, spv::OpVectorTimesScalar, type_float4_, color,
builder_->createLoad(builder_->createAccessChain( builder_->createLoad(builder_->createAccessChain(
spv::StorageClassUniform, spv::StorageClassUniform,
uniform_system_constants_, id_vector_temp_), uniform_system_constants_, id_vector_temp_),
spv::NoPrecision)); spv::NoPrecision));
builder_->addDecoration(color, spv::DecorationNoContraction);
if (edram_fragment_shader_interlock_) { if (edram_fragment_shader_interlock_) {
// Write the color to the target in the EDRAM only it was written on the // 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( spv::Id depth_max_slope = builder_->createBuiltinCall(
type_float_, ext_inst_glsl_std_450_, GLSLstd450FMax, id_vector_temp_); type_float_, ext_inst_glsl_std_450_, GLSLstd450FMax, id_vector_temp_);
// Calculate the polygon offset. // 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); spv::OpFMul, type_float_, poly_offset_scale, depth_max_slope);
builder_->addDecoration(slope_scaled_poly_offset, spv::Id poly_offset = builder_->createNoContractionBinOp(
spv::DecorationNoContraction);
spv::Id poly_offset = builder_->createBinOp(
spv::OpFAdd, type_float_, slope_scaled_poly_offset, poly_offset_offset); 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 // 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 // depth. Not clamping yet as this is at the center, which is not necessarily
// covered and not necessarily inside the bounds - derivatives scaled by // covered and not necessarily inside the bounds - derivatives scaled by
// sample locations will be added to this value, and it must be linear. // 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); 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. // Perform depth and stencil testing for each covered sample.
spv::Id new_sample_mask = main_fsi_sample_mask_; spv::Id new_sample_mask = main_fsi_sample_mask_;
@ -2076,17 +2071,14 @@ void SpirvShaderTranslator::FSI_DepthStencilTest(
} }
std::array<spv::Id, 2> sample_depth_dxy; std::array<spv::Id, 2> sample_depth_dxy;
for (uint32_t j = 0; j < 2; ++j) { 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]); 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::Id sample_depth32 = builder_->createNoContractionBinOp(
spv::OpFAdd, type_float_, sample_depth_dxy[0], sample_depth_dxy[1]); spv::OpFAdd, type_float_, center_depth32_biased,
builder_->addDecoration(sample_depth32, spv::DecorationNoContraction); builder_->createNoContractionBinOp(spv::OpFAdd, type_float_,
sample_depth32 = builder_->createBinOp( sample_depth_dxy[0],
spv::OpFAdd, type_float_, center_depth32_biased, sample_depth32); sample_depth_dxy[1]));
builder_->addDecoration(sample_depth32, spv::DecorationNoContraction);
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(sample_depth32); id_vector_temp_.push_back(sample_depth32);
id_vector_temp_.push_back(const_float_0_); 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 // conversion, adding +0.5 and rounding towards zero results in red instead
// of black in the 4D5307E6 clear shader. // of black in the 4D5307E6 clear shader.
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back( id_vector_temp_.push_back(builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFMul, type_float_, sample_depth32, spv::OpFMul, type_float_, sample_depth32,
builder_->makeFloatConstant(float(0xFFFFFF)))); builder_->makeFloatConstant(float(0xFFFFFF))));
builder_->addDecoration(id_vector_temp_.back(),
spv::DecorationNoContraction);
spv::Id sample_depth_unorm24 = builder_->createUnaryOp( spv::Id sample_depth_unorm24 = builder_->createUnaryOp(
spv::OpConvertFToU, type_uint_, spv::OpConvertFToU, type_uint_,
builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_,
@ -2582,15 +2572,13 @@ std::array<spv::Id, 2> SpirvShaderTranslator::FSI_ClampAndPackColor(
id_vector_temp_.push_back(color_float4); id_vector_temp_.push_back(color_float4);
id_vector_temp_.push_back(const_float4_0_); id_vector_temp_.push_back(const_float4_0_);
id_vector_temp_.push_back(const_float4_1_); id_vector_temp_.push_back(const_float4_1_);
spv::Id color_scaled = builder_->createBinOp( spv::Id color_scaled = builder_->createNoContractionBinOp(
spv::OpVectorTimesScalar, type_float4_, spv::OpVectorTimesScalar, type_float4_,
builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_, builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_,
GLSLstd450NClamp, id_vector_temp_), GLSLstd450NClamp, id_vector_temp_),
builder_->makeFloatConstant(255.0f)); builder_->makeFloatConstant(255.0f));
builder_->addDecoration(color_scaled, spv::DecorationNoContraction); spv::Id color_offset = builder_->createNoContractionBinOp(
spv::Id color_offset = builder_->createBinOp(
spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4);
builder_->addDecoration(color_offset, spv::DecorationNoContraction);
spv::Id color_uint4 = spv::Id color_uint4 =
builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset); builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset);
packed_8_8_8_8 = packed_8_8_8_8 =
@ -2647,13 +2635,11 @@ std::array<spv::Id, 2> SpirvShaderTranslator::FSI_ClampAndPackColor(
builder_->getBuildPoint()->addInstruction( builder_->getBuildPoint()->addInstruction(
std::move(color_gamma_composite_construct_op)); std::move(color_gamma_composite_construct_op));
} }
spv::Id color_scaled = spv::Id color_scaled = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpVectorTimesScalar, type_float4_, spv::OpVectorTimesScalar, type_float4_, color_gamma,
color_gamma, builder_->makeFloatConstant(255.0f)); builder_->makeFloatConstant(255.0f));
builder_->addDecoration(color_scaled, spv::DecorationNoContraction); spv::Id color_offset = builder_->createNoContractionBinOp(
spv::Id color_offset = builder_->createBinOp(
spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4);
builder_->addDecoration(color_offset, spv::DecorationNoContraction);
spv::Id color_uint4 = spv::Id color_uint4 =
builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset); builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset);
packed_8_8_8_8_gamma = packed_8_8_8_8_gamma =
@ -2690,13 +2676,11 @@ std::array<spv::Id, 2> SpirvShaderTranslator::FSI_ClampAndPackColor(
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.resize(3, builder_->makeFloatConstant(1023.0f)); id_vector_temp_.resize(3, builder_->makeFloatConstant(1023.0f));
id_vector_temp_.push_back(builder_->makeFloatConstant(3.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, spv::OpFMul, type_float4_, color_clamped,
builder_->makeCompositeConstant(type_float4_, id_vector_temp_)); builder_->makeCompositeConstant(type_float4_, id_vector_temp_));
builder_->addDecoration(color_scaled, spv::DecorationNoContraction); spv::Id color_offset = builder_->createNoContractionBinOp(
spv::Id color_offset = builder_->createBinOp(
spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4); spv::OpFAdd, type_float4_, color_scaled, unorm_round_offset_float4);
builder_->addDecoration(color_offset, spv::DecorationNoContraction);
spv::Id color_uint4 = spv::Id color_uint4 =
builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset); builder_->createUnaryOp(spv::OpConvertFToU, type_uint4_, color_offset);
packed_2_10_10_10 = packed_2_10_10_10 =
@ -2738,15 +2722,13 @@ std::array<spv::Id, 2> SpirvShaderTranslator::FSI_ClampAndPackColor(
builder_->createCompositeExtract(color_float4, type_float_, 3)); builder_->createCompositeExtract(color_float4, type_float_, 3));
id_vector_temp_.push_back(const_float_0_); id_vector_temp_.push_back(const_float_0_);
id_vector_temp_.push_back(const_float_1_); id_vector_temp_.push_back(const_float_1_);
spv::Id alpha_scaled = builder_->createBinOp( spv::Id alpha_scaled = builder_->createNoContractionBinOp(
spv::OpFMul, type_float_, spv::OpFMul, type_float_,
builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_, builder_->createBuiltinCall(type_float_, ext_inst_glsl_std_450_,
GLSLstd450NClamp, id_vector_temp_), GLSLstd450NClamp, id_vector_temp_),
builder_->makeFloatConstant(3.0f)); builder_->makeFloatConstant(3.0f));
builder_->addDecoration(alpha_scaled, spv::DecorationNoContraction); spv::Id alpha_offset = builder_->createNoContractionBinOp(
spv::Id alpha_offset = builder_->createBinOp(
spv::OpFAdd, type_float_, alpha_scaled, unorm_round_offset_float); spv::OpFAdd, type_float_, alpha_scaled, unorm_round_offset_float);
builder_->addDecoration(alpha_offset, spv::DecorationNoContraction);
color_components[3] = color_components[3] =
builder_->createUnaryOp(spv::OpConvertFToU, type_uint_, alpha_offset); builder_->createUnaryOp(spv::OpConvertFToU, type_uint_, alpha_offset);
// Pack. // Pack.
@ -2795,24 +2777,22 @@ std::array<spv::Id, 2> SpirvShaderTranslator::FSI_ClampAndPackColor(
const_float4_0_, color_float4)); const_float4_0_, color_float4));
id_vector_temp_.push_back(const_float4_minus_32); id_vector_temp_.push_back(const_float4_minus_32);
id_vector_temp_.push_back(const_float4_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_, spv::OpVectorTimesScalar, type_float4_,
builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_, builder_->createBuiltinCall(type_float4_, ext_inst_glsl_std_450_,
GLSLstd450FClamp, id_vector_temp_), GLSLstd450FClamp, id_vector_temp_),
builder_->makeFloatConstant(32767.0f / 32.0f)); builder_->makeFloatConstant(32767.0f / 32.0f));
builder_->addDecoration(color_scaled, spv::DecorationNoContraction);
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.resize(4, builder_->makeFloatConstant(-0.5f)); id_vector_temp_.resize(4, builder_->makeFloatConstant(-0.5f));
spv::Id unorm_round_offset_negative_float4 = spv::Id unorm_round_offset_negative_float4 =
builder_->makeCompositeConstant(type_float4_, id_vector_temp_); 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, spv::OpFAdd, type_float4_, color_scaled,
builder_->createTriOp( builder_->createTriOp(
spv::OpSelect, type_float4_, spv::OpSelect, type_float4_,
builder_->createBinOp(spv::OpFOrdLessThan, type_bool4_, builder_->createBinOp(spv::OpFOrdLessThan, type_bool4_,
color_scaled, const_float4_0_), color_scaled, const_float4_0_),
unorm_round_offset_negative_float4, unorm_round_offset_float4)); unorm_round_offset_negative_float4, unorm_round_offset_float4));
builder_->addDecoration(color_offset, spv::DecorationNoContraction);
spv::Id color_uint4 = builder_->createUnaryOp( spv::Id color_uint4 = builder_->createUnaryOp(
spv::OpBitcast, type_uint4_, spv::OpBitcast, type_uint4_,
builder_->createUnaryOp(spv::OpConvertFToS, type_int4_, color_offset)); builder_->createUnaryOp(spv::OpConvertFToS, type_int4_, color_offset));
@ -3028,7 +3008,7 @@ std::array<spv::Id, 4> SpirvShaderTranslator::FSI_UnpackColor(
builder_->setBuildPoint(i ? &block_format_8_8_8_8_gamma builder_->setBuildPoint(i ? &block_format_8_8_8_8_gamma
: &block_format_8_8_8_8); : &block_format_8_8_8_8);
for (uint32_t j = 0; j < 4; ++j) { for (uint32_t j = 0; j < 4; ++j) {
spv::Id component = builder_->createBinOp( spv::Id component = builder_->createNoContractionBinOp(
spv::OpFMul, type_float_, spv::OpFMul, type_float_,
builder_->createUnaryOp( builder_->createUnaryOp(
spv::OpConvertUToF, type_float_, spv::OpConvertUToF, type_float_,
@ -3036,7 +3016,6 @@ std::array<spv::Id, 4> SpirvShaderTranslator::FSI_UnpackColor(
spv::OpBitFieldUExtract, type_uint_, color_packed[0], spv::OpBitFieldUExtract, type_uint_, color_packed[0],
builder_->makeUintConstant(8 * j), component_width)), builder_->makeUintConstant(8 * j), component_width)),
component_scale); component_scale);
builder_->addDecoration(component, spv::DecorationNoContraction);
if (i && j <= 2) { if (i && j <= 2) {
component = PWLGammaToLinear(component, true); component = PWLGammaToLinear(component, true);
} }
@ -3060,7 +3039,7 @@ std::array<spv::Id, 4> SpirvShaderTranslator::FSI_UnpackColor(
spv::Id rgb_scale = builder_->makeFloatConstant(1.0f / 1023.0f); spv::Id rgb_scale = builder_->makeFloatConstant(1.0f / 1023.0f);
spv::Id alpha_scale = builder_->makeFloatConstant(1.0f / 3.0f); spv::Id alpha_scale = builder_->makeFloatConstant(1.0f / 3.0f);
for (uint32_t i = 0; i < 4; ++i) { 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_, spv::OpFMul, type_float_,
builder_->createUnaryOp( builder_->createUnaryOp(
spv::OpConvertUToF, type_float_, spv::OpConvertUToF, type_float_,
@ -3069,8 +3048,6 @@ std::array<spv::Id, 4> SpirvShaderTranslator::FSI_UnpackColor(
builder_->makeUintConstant(10 * i), builder_->makeUintConstant(10 * i),
i == 3 ? alpha_width : rgb_width)), i == 3 ? alpha_width : rgb_width)),
i == 3 ? alpha_scale : rgb_scale); i == 3 ? alpha_scale : rgb_scale);
builder_->addDecoration(component, spv::DecorationNoContraction);
unpacked_2_10_10_10[i] = component;
} }
builder_->createBranch(&block_format_merge); builder_->createBranch(&block_format_merge);
} }
@ -3093,7 +3070,7 @@ std::array<spv::Id, 4> SpirvShaderTranslator::FSI_UnpackColor(
builder_->makeUintConstant(10 * i), rgb_width), builder_->makeUintConstant(10 * i), rgb_width),
0, false, ext_inst_glsl_std_450_); 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_, spv::OpFMul, type_float_,
builder_->createUnaryOp( builder_->createUnaryOp(
spv::OpConvertUToF, type_float_, spv::OpConvertUToF, type_float_,
@ -3101,8 +3078,6 @@ std::array<spv::Id, 4> SpirvShaderTranslator::FSI_UnpackColor(
spv::OpBitFieldUExtract, type_uint_, color_packed[0], spv::OpBitFieldUExtract, type_uint_, color_packed[0],
builder_->makeUintConstant(30), builder_->makeUintConstant(2))), builder_->makeUintConstant(30), builder_->makeUintConstant(2))),
builder_->makeFloatConstant(1.0f / 3.0f)); builder_->makeFloatConstant(1.0f / 3.0f));
builder_->addDecoration(alpha, spv::DecorationNoContraction);
unpacked_2_10_10_10_float[3] = alpha;
builder_->createBranch(&block_format_merge); builder_->createBranch(&block_format_merge);
} }
spv::Block& block_format_2_10_10_10_float_end = *builder_->getBuildPoint(); spv::Block& block_format_2_10_10_10_float_end = *builder_->getBuildPoint();
@ -3129,7 +3104,7 @@ std::array<spv::Id, 4> SpirvShaderTranslator::FSI_UnpackColor(
builder_->createUnaryOp(spv::OpBitcast, type_int_, color_packed[j]); builder_->createUnaryOp(spv::OpBitcast, type_int_, color_packed[j]);
} }
for (uint32_t j = 0; j < uint32_t(i ? 4 : 2); ++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_, spv::OpFMul, type_float_,
builder_->createUnaryOp( builder_->createUnaryOp(
spv::OpConvertSToF, type_float_, spv::OpConvertSToF, type_float_,
@ -3138,7 +3113,6 @@ std::array<spv::Id, 4> SpirvShaderTranslator::FSI_UnpackColor(
builder_->makeUintConstant(16 * (j & 1)), builder_->makeUintConstant(16 * (j & 1)),
component_width)), component_width)),
component_scale); component_scale);
builder_->addDecoration(component, spv::DecorationNoContraction);
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(component_min); id_vector_temp_.push_back(component_min);
id_vector_temp_.push_back(component); id_vector_temp_.push_back(component);
@ -3414,51 +3388,36 @@ spv::Id SpirvShaderTranslator::FSI_ApplyColorBlendFactor(
// kSrc/Dst/ConstantColor // kSrc/Dst/ConstantColor
{ {
builder_->setBuildPoint(color_factor_blocks[i]); builder_->setBuildPoint(color_factor_blocks[i]);
spv::Id result_color = color_factor_results[i] = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFMul, type_float3_, value, color_factor); spv::OpFMul, type_float3_, value, color_factor);
builder_->addDecoration(result_color, spv::DecorationNoContraction);
color_factor_results[i] = result_color;
builder_->createBranch(&block_factor_merge); builder_->createBranch(&block_factor_merge);
} }
// kOneMinusSrc/Dst/ConstantColor // kOneMinusSrc/Dst/ConstantColor
{ {
builder_->setBuildPoint(one_minus_color_factor_blocks[i]); builder_->setBuildPoint(one_minus_color_factor_blocks[i]);
spv::Id one_minus_color_factor = builder_->createBinOp( one_minus_color_factor_results[i] = builder_->createNoContractionBinOp(
spv::OpFSub, type_float3_, const_float3_1_, color_factor); spv::OpFMul, type_float3_, value,
builder_->addDecoration(one_minus_color_factor, builder_->createNoContractionBinOp(spv::OpFSub, type_float3_,
spv::DecorationNoContraction); const_float3_1_, color_factor));
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;
builder_->createBranch(&block_factor_merge); builder_->createBranch(&block_factor_merge);
} }
// kSrc/Dst/ConstantAlpha // kSrc/Dst/ConstantAlpha
{ {
builder_->setBuildPoint(alpha_factor_blocks[i]); 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); spv::OpVectorTimesScalar, type_float3_, value, alpha_factor);
builder_->addDecoration(result_alpha, spv::DecorationNoContraction);
alpha_factor_results[i] = result_alpha;
builder_->createBranch(&block_factor_merge); builder_->createBranch(&block_factor_merge);
} }
// kOneMinusSrc/Dst/ConstantAlpha // kOneMinusSrc/Dst/ConstantAlpha
{ {
builder_->setBuildPoint(one_minus_alpha_factor_blocks[i]); builder_->setBuildPoint(one_minus_alpha_factor_blocks[i]);
spv::Id one_minus_alpha_factor = builder_->createBinOp( one_minus_alpha_factor_results[i] = builder_->createNoContractionBinOp(
spv::OpFSub, type_float_, const_float_1_, alpha_factor); spv::OpVectorTimesScalar, type_float3_, value,
builder_->addDecoration(one_minus_alpha_factor, builder_->createNoContractionBinOp(spv::OpFSub, type_float_,
spv::DecorationNoContraction); const_float_1_, alpha_factor));
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;
builder_->createBranch(&block_factor_merge); builder_->createBranch(&block_factor_merge);
} }
} }
@ -3467,19 +3426,16 @@ spv::Id SpirvShaderTranslator::FSI_ApplyColorBlendFactor(
spv::Id result_source_alpha_saturate; spv::Id result_source_alpha_saturate;
{ {
builder_->setBuildPoint(&block_factor_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); spv::OpFSub, type_float_, const_float_1_, dest_alpha);
builder_->addDecoration(one_minus_dest_alpha, spv::DecorationNoContraction);
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(source_alpha); id_vector_temp_.push_back(source_alpha);
id_vector_temp_.push_back(one_minus_dest_alpha); id_vector_temp_.push_back(one_minus_dest_alpha);
spv::Id factor_source_alpha_saturate = builder_->createBuiltinCall( spv::Id factor_source_alpha_saturate = builder_->createBuiltinCall(
type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, id_vector_temp_); type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, id_vector_temp_);
result_source_alpha_saturate = result_source_alpha_saturate = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpVectorTimesScalar, type_float3_, value, spv::OpVectorTimesScalar, type_float3_, value,
factor_source_alpha_saturate); factor_source_alpha_saturate);
builder_->addDecoration(result_source_alpha_saturate,
spv::DecorationNoContraction);
builder_->createBranch(&block_factor_merge); builder_->createBranch(&block_factor_merge);
} }
@ -3629,25 +3585,18 @@ spv::Id SpirvShaderTranslator::FSI_ApplyAlphaBlendFactor(
// kSrc/Dst/ConstantColor/Alpha // kSrc/Dst/ConstantColor/Alpha
{ {
builder_->setBuildPoint(alpha_factor_blocks[i]); builder_->setBuildPoint(alpha_factor_blocks[i]);
spv::Id result_alpha = alpha_factor_results[i] = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFMul, type_float_, value, alpha_factor); spv::OpFMul, type_float_, value, alpha_factor);
builder_->addDecoration(result_alpha, spv::DecorationNoContraction);
alpha_factor_results[i] = result_alpha;
builder_->createBranch(&block_factor_merge); builder_->createBranch(&block_factor_merge);
} }
// kOneMinusSrc/Dst/ConstantColor/Alpha // kOneMinusSrc/Dst/ConstantColor/Alpha
{ {
builder_->setBuildPoint(one_minus_alpha_factor_blocks[i]); builder_->setBuildPoint(one_minus_alpha_factor_blocks[i]);
spv::Id one_minus_alpha_factor = builder_->createBinOp( one_minus_alpha_factor_results[i] = builder_->createNoContractionBinOp(
spv::OpFSub, type_float_, const_float_1_, alpha_factor); spv::OpFMul, type_float_, value,
builder_->addDecoration(one_minus_alpha_factor, builder_->createNoContractionBinOp(spv::OpFSub, type_float_,
spv::DecorationNoContraction); const_float_1_, alpha_factor));
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;
builder_->createBranch(&block_factor_merge); builder_->createBranch(&block_factor_merge);
} }
} }
@ -3656,18 +3605,15 @@ spv::Id SpirvShaderTranslator::FSI_ApplyAlphaBlendFactor(
spv::Id result_source_alpha_saturate; spv::Id result_source_alpha_saturate;
{ {
builder_->setBuildPoint(&block_factor_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); spv::OpFSub, type_float_, const_float_1_, dest_alpha);
builder_->addDecoration(one_minus_dest_alpha, spv::DecorationNoContraction);
id_vector_temp_.clear(); id_vector_temp_.clear();
id_vector_temp_.push_back(source_alpha); id_vector_temp_.push_back(source_alpha);
id_vector_temp_.push_back(one_minus_dest_alpha); id_vector_temp_.push_back(one_minus_dest_alpha);
spv::Id factor_source_alpha_saturate = builder_->createBuiltinCall( spv::Id factor_source_alpha_saturate = builder_->createBuiltinCall(
type_float_, ext_inst_glsl_std_450_, GLSLstd450NMin, id_vector_temp_); 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); spv::OpFMul, type_float_, value, factor_source_alpha_saturate);
builder_->addDecoration(result_source_alpha_saturate,
spv::DecorationNoContraction);
builder_->createBranch(&block_factor_merge); builder_->createBranch(&block_factor_merge);
} }
@ -3812,24 +3758,20 @@ spv::Id SpirvShaderTranslator::FSI_BlendColorOrAlphaWithUnclampedResult(
// Addition case. // Addition case.
builder_->setBuildPoint(&block_signs_add); builder_->setBuildPoint(&block_signs_add);
spv::Id result_add = spv::Id result_add = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFAdd, value_type, term_source, term_dest); spv::OpFAdd, value_type, term_source, term_dest);
builder_->addDecoration(result_add, spv::DecorationNoContraction);
builder_->createBranch(&block_signs_merge); builder_->createBranch(&block_signs_merge);
// Subtraction case. // Subtraction case.
builder_->setBuildPoint(&block_signs_subtract); builder_->setBuildPoint(&block_signs_subtract);
spv::Id result_subtract = spv::Id result_subtract = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFSub, value_type, term_source, term_dest); spv::OpFSub, value_type, term_source, term_dest);
builder_->addDecoration(result_subtract, spv::DecorationNoContraction);
builder_->createBranch(&block_signs_merge); builder_->createBranch(&block_signs_merge);
// Reverse subtraction case. // Reverse subtraction case.
builder_->setBuildPoint(&block_signs_reverse_subtract); builder_->setBuildPoint(&block_signs_reverse_subtract);
spv::Id result_reverse_subtract = spv::Id result_reverse_subtract = builder_->createNoContractionBinOp(
builder_->createBinOp(spv::OpFSub, value_type, term_dest, term_source); spv::OpFSub, value_type, term_dest, term_source);
builder_->addDecoration(result_reverse_subtract,
spv::DecorationNoContraction);
builder_->createBranch(&block_signs_merge); builder_->createBranch(&block_signs_merge);
// Selection between the signs involved in the addition. // Selection between the signs involved in the addition.

View File

@ -1393,21 +1393,19 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) {
id_vector_temp.push_back(builder.makeIntConstant( id_vector_temp.push_back(builder.makeIntConstant(
int32_t(kPointConstantScreenDiameterToNdcRadius))); int32_t(kPointConstantScreenDiameterToNdcRadius)));
id_vector_temp.push_back(const_int_0); 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, spv::OpFMul, type_float, point_guest_diameter_x,
builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, builder.createLoad(builder.createAccessChain(spv::StorageClassUniform,
uniform_system_constants, uniform_system_constants,
id_vector_temp), id_vector_temp),
spv::NoPrecision)); spv::NoPrecision));
builder.addDecoration(point_radius_x, spv::DecorationNoContraction);
id_vector_temp.back() = const_int_1; 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, spv::OpFMul, type_float, point_guest_diameter_y,
builder.createLoad(builder.createAccessChain(spv::StorageClassUniform, builder.createLoad(builder.createAccessChain(spv::StorageClassUniform,
uniform_system_constants, uniform_system_constants,
id_vector_temp), id_vector_temp),
spv::NoPrecision)); spv::NoPrecision));
builder.addDecoration(point_radius_y, spv::DecorationNoContraction);
id_vector_temp.clear(); id_vector_temp.clear();
// 0 is the input primitive vertex index. // 0 is the input primitive vertex index.
id_vector_temp.push_back(const_int_0); id_vector_temp.push_back(const_int_0);
@ -1418,12 +1416,10 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) {
spv::NoPrecision); spv::NoPrecision);
spv::Id point_w = spv::Id point_w =
builder.createCompositeExtract(point_position, type_float, 3); builder.createCompositeExtract(point_position, type_float, 3);
point_radius_x = point_radius_x = builder.createNoContractionBinOp(
builder.createBinOp(spv::OpFMul, type_float, point_radius_x, point_w); spv::OpFMul, type_float, point_radius_x, point_w);
builder.addDecoration(point_radius_x, spv::DecorationNoContraction); point_radius_y = builder.createNoContractionBinOp(
point_radius_y = spv::OpFMul, type_float, point_radius_y, point_w);
builder.createBinOp(spv::OpFMul, type_float, point_radius_y, point_w);
builder.addDecoration(point_radius_y, spv::DecorationNoContraction);
// Load the inputs for the guest point. // Load the inputs for the guest point.
// Interpolators. // Interpolators.
@ -1445,12 +1441,10 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) {
std::array<spv::Id, 2> point_edge_x, point_edge_y; std::array<spv::Id, 2> point_edge_x, point_edge_y;
for (uint32_t i = 0; i < 2; ++i) { for (uint32_t i = 0; i < 2; ++i) {
spv::Op point_radius_add_op = i ? spv::OpFAdd : spv::OpFSub; spv::Op point_radius_add_op = i ? spv::OpFAdd : spv::OpFSub;
point_edge_x[i] = builder.createBinOp(point_radius_add_op, type_float, point_edge_x[i] = builder.createNoContractionBinOp(
point_x, point_radius_x); point_radius_add_op, type_float, point_x, point_radius_x);
builder.addDecoration(point_edge_x[i], spv::DecorationNoContraction); point_edge_y[i] = builder.createNoContractionBinOp(
point_edge_y[i] = builder.createBinOp(point_radius_add_op, type_float, point_radius_add_op, type_float, point_y, point_radius_y);
point_y, point_radius_y);
builder.addDecoration(point_edge_y[i], spv::DecorationNoContraction);
}; };
spv::Id point_z = spv::Id point_z =
builder.createCompositeExtract(point_position, type_float, 2); builder.createCompositeExtract(point_position, type_float, 2);
@ -1699,24 +1693,20 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) {
id_vector_temp), id_vector_temp),
spv::NoPrecision); spv::NoPrecision);
id_vector_temp[0] = vertex_indices[1]; 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, spv::OpFSub, type_float4,
builder.createLoad( builder.createLoad(
builder.createAccessChain(spv::StorageClassInput, builder.createAccessChain(spv::StorageClassInput,
in_interpolator, id_vector_temp), in_interpolator, id_vector_temp),
spv::NoPrecision), spv::NoPrecision),
vertex_interpolator_v0); vertex_interpolator_v0);
builder.addDecoration(vertex_interpolator_v01,
spv::DecorationNoContraction);
id_vector_temp[0] = vertex_indices[2]; 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, spv::OpFAdd, type_float4, vertex_interpolator_v01,
builder.createLoad( builder.createLoad(
builder.createAccessChain(spv::StorageClassInput, builder.createAccessChain(spv::StorageClassInput,
in_interpolator, id_vector_temp), in_interpolator, id_vector_temp),
spv::NoPrecision)); spv::NoPrecision));
builder.addDecoration(vertex_interpolator_v3,
spv::DecorationNoContraction);
builder.createStore(vertex_interpolator_v3, out_interpolators[i]); builder.createStore(vertex_interpolator_v3, out_interpolators[i]);
} }
// Point coordinates. // Point coordinates.
@ -1733,22 +1723,20 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) {
id_vector_temp), id_vector_temp),
spv::NoPrecision); spv::NoPrecision);
id_vector_temp[0] = vertex_indices[1]; 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, spv::OpFSub, type_float4,
builder.createLoad( builder.createLoad(
builder.createAccessChain(spv::StorageClassInput, builder.createAccessChain(spv::StorageClassInput,
in_gl_per_vertex, id_vector_temp), in_gl_per_vertex, id_vector_temp),
spv::NoPrecision), spv::NoPrecision),
vertex_position_v0); vertex_position_v0);
builder.addDecoration(vertex_position_v01, spv::DecorationNoContraction);
id_vector_temp[0] = vertex_indices[2]; 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, spv::OpFAdd, type_float4, vertex_position_v01,
builder.createLoad( builder.createLoad(
builder.createAccessChain(spv::StorageClassInput, builder.createAccessChain(spv::StorageClassInput,
in_gl_per_vertex, id_vector_temp), in_gl_per_vertex, id_vector_temp),
spv::NoPrecision)); spv::NoPrecision));
builder.addDecoration(vertex_position_v3, spv::DecorationNoContraction);
id_vector_temp.clear(); id_vector_temp.clear();
id_vector_temp.push_back(const_member_out_gl_per_vertex_position); id_vector_temp.push_back(const_member_out_gl_per_vertex_position);
builder.createStore( builder.createStore(
@ -1767,24 +1755,20 @@ VkShaderModule VulkanPipelineCache::GetGeometryShader(GeometryShaderKey key) {
id_vector_temp), id_vector_temp),
spv::NoPrecision); spv::NoPrecision);
id_vector_temp[0] = vertex_indices[1]; 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, spv::OpFSub, type_float,
builder.createLoad( builder.createLoad(
builder.createAccessChain(spv::StorageClassInput, builder.createAccessChain(spv::StorageClassInput,
in_gl_per_vertex, id_vector_temp), in_gl_per_vertex, id_vector_temp),
spv::NoPrecision), spv::NoPrecision),
vertex_clip_distance_v0); vertex_clip_distance_v0);
builder.addDecoration(vertex_clip_distance_v01,
spv::DecorationNoContraction);
id_vector_temp[0] = vertex_indices[2]; 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, spv::OpFAdd, type_float, vertex_clip_distance_v01,
builder.createLoad( builder.createLoad(
builder.createAccessChain(spv::StorageClassInput, builder.createAccessChain(spv::StorageClassInput,
in_gl_per_vertex, id_vector_temp), in_gl_per_vertex, id_vector_temp),
spv::NoPrecision)); spv::NoPrecision));
builder.addDecoration(vertex_clip_distance_v3,
spv::DecorationNoContraction);
id_vector_temp.clear(); id_vector_temp.clear();
id_vector_temp.push_back(const_member_in_gl_per_vertex_clip_distance); id_vector_temp.push_back(const_member_in_gl_per_vertex_clip_distance);
id_vector_temp.push_back(const_int_i); id_vector_temp.push_back(const_int_i);