Commit 3c0e0582 by Nicolas Capens Committed by Nicolas Capens

Skip texel address sample offset if zero

The SPIR-V spec states that the Sample operand of OpImageTexelPointer "must be a valid <id> for the value 0 if the OpTypeImage has MS of 0." This change optimizes for this common case by no performing texel address sample offset and bounds check calculations. Bug: b/163142358 Change-Id: I75932c264d45df1012fa8451fc4c57671191b59b Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/47808 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com>
parent 6287c18b
......@@ -2481,11 +2481,11 @@ SpirvShader::Operand::Operand(const SpirvShader *shader, const EmitState *state,
{}
SpirvShader::Operand::Operand(const EmitState *state, const Object &object)
: constant(object.constantValue.data())
: constant(object.kind == SpirvShader::Object::Kind::Constant ? object.constantValue.data() : nullptr)
, intermediate(object.kind == SpirvShader::Object::Kind::Intermediate ? &state->getIntermediate(object.id()) : nullptr)
, componentCount(intermediate ? intermediate->componentCount : object.constantValue.size())
{
ASSERT(intermediate || (object.kind == SpirvShader::Object::Kind::Constant));
ASSERT(intermediate || constant);
}
SpirvShader::Operand::Operand(const Intermediate &value)
......@@ -2495,6 +2495,24 @@ SpirvShader::Operand::Operand(const Intermediate &value)
{
}
bool SpirvShader::Operand::isConstantZero() const
{
if(!constant)
{
return false;
}
for(uint32_t i = 0; i < componentCount; i++)
{
if(constant[i] != 0)
{
return false;
}
}
return true;
}
SpirvRoutine::SpirvRoutine(vk::PipelineLayout const *pipelineLayout)
: pipelineLayout(pipelineLayout)
{
......
......@@ -1069,6 +1069,8 @@ private:
return SIMD::UInt(constant[i]);
}
bool isConstantZero() const;
private:
RR_PRINT_ONLY(friend struct rr::PrintValue::Ty<Operand>;)
......
......@@ -558,8 +558,11 @@ SIMD::Pointer SpirvShader::GetTexelAddress(EmitState const *state, Pointer<Byte>
if(sampleId.value())
{
Operand sample(this, state, sampleId);
n = sample.Int(0);
ptrOffset += n * samplePitch;
if(!sample.isConstantZero())
{
n = sample.Int(0);
ptrOffset += n * samplePitch;
}
}
// If the out-of-bounds behavior is set to nullify, then each coordinate must be tested individually.
......@@ -584,8 +587,12 @@ SIMD::Pointer SpirvShader::GetTexelAddress(EmitState const *state, Pointer<Byte>
if(sampleId.value())
{
SIMD::UInt sampleCount = *Pointer<UInt>(descriptor + OFFSET(vk::StorageImageDescriptor, sampleCount));
oobMask |= As<SIMD::Int>(CmpNLT(As<SIMD::UInt>(n), sampleCount));
Operand sample(this, state, sampleId);
if(!sample.isConstantZero())
{
SIMD::UInt sampleCount = *Pointer<UInt>(descriptor + OFFSET(vk::StorageImageDescriptor, sampleCount));
oobMask |= As<SIMD::Int>(CmpNLT(As<SIMD::UInt>(n), sampleCount));
}
}
constexpr int32_t OOB_OFFSET = 0x7FFFFFFF - 16; // SIMD pointer offsets are signed 32-bit, so this is the largest offset (for 16-byte texels).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment