Commit 89c37a4d by Chris Forbes

Factor out GetTexelOffset from EmitImageRead/EmitImageWrite

Also fix the addressing to correctly use the slice pitch to advance to the correct layer in an arrayed 1D texture, rather than using the row pitch. Bug: b/130768731 Test: dEQP-VK.image.* Change-Id: I46b8c4eb353d7901d5953df46138ff9e01f87ead Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29411Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Presubmit-Ready: Chris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 2f7f2ecb
...@@ -4412,6 +4412,32 @@ namespace sw ...@@ -4412,6 +4412,32 @@ namespace sw
return EmitResult::Continue; return EmitResult::Continue;
} }
SIMD::Int SpirvShader::GetTexelOffset(GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize) const
{
// returns a (lane-divergent) byte offset to a texel within a storage image.
bool isArrayed = imageType.definition.word(5) != 0;
int dims = getType(coordinate.type).sizeInComponents - (isArrayed ? 1 : 0);
SIMD::Int texelOffset = coordinate.Int(0) * SIMD::Int(texelSize);
if (dims > 1)
{
texelOffset += coordinate.Int(1) * SIMD::Int(
*Pointer<Int>(descriptor + OFFSET(vk::StorageImageDescriptor, rowPitchBytes)));
}
if (dims > 2)
{
texelOffset += coordinate.Int(2) * SIMD::Int(
*Pointer<Int>(descriptor + OFFSET(vk::StorageImageDescriptor, slicePitchBytes)));
}
if (isArrayed)
{
texelOffset += coordinate.Int(dims) * SIMD::Int(
*Pointer<Int>(descriptor + OFFSET(vk::StorageImageDescriptor, slicePitchBytes)));
}
return texelOffset;
}
SpirvShader::EmitResult SpirvShader::EmitImageRead(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitImageRead(InsnIterator insn, EmitState *state) const
{ {
auto &resultType = getType(Type::ID(insn.word(1))); auto &resultType = getType(Type::ID(insn.word(1)));
...@@ -4438,7 +4464,6 @@ namespace sw ...@@ -4438,7 +4464,6 @@ namespace sw
auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents); auto &dst = state->routine->createIntermediate(resultId, resultType.sizeInComponents);
SIMD::Int packed[4]; SIMD::Int packed[4];
auto numPackedElements = 0u; auto numPackedElements = 0u;
int texelSize = 0; int texelSize = 0;
...@@ -4483,17 +4508,7 @@ namespace sw ...@@ -4483,17 +4508,7 @@ namespace sw
UNIMPLEMENTED("spv::ImageFormat %u", format); UNIMPLEMENTED("spv::ImageFormat %u", format);
} }
SIMD::Int texelOffset = coordinate.Int(0) * SIMD::Int(texelSize); SIMD::Int texelOffset = GetTexelOffset(coordinate, imageType, binding, texelSize);
if (getType(coordinate.type).sizeInComponents > 1)
{
texelOffset += coordinate.Int(1) * SIMD::Int(
*Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, rowPitchBytes)));
}
if (getType(coordinate.type).sizeInComponents > 2)
{
texelOffset += coordinate.Int(2) * SIMD::Int(
*Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, slicePitchBytes)));
}
for (auto i = 0u; i < numPackedElements; i++) for (auto i = 0u; i < numPackedElements; i++)
{ {
...@@ -4674,17 +4689,7 @@ namespace sw ...@@ -4674,17 +4689,7 @@ namespace sw
UNIMPLEMENTED("spv::ImageFormat %u", format); UNIMPLEMENTED("spv::ImageFormat %u", format);
} }
SIMD::Int texelOffset = coordinate.Int(0) * SIMD::Int(texelSize); SIMD::Int texelOffset = GetTexelOffset(coordinate, imageType, binding, texelSize);
if (getType(coordinate.type).sizeInComponents > 1)
{
texelOffset += coordinate.Int(1) * SIMD::Int(
*Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, rowPitchBytes)));
}
if (getType(coordinate.type).sizeInComponents > 2)
{
texelOffset += coordinate.Int(2) * SIMD::Int(
*Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, slicePitchBytes)));
}
for (auto i = 0u; i < numPackedElements; i++) for (auto i = 0u; i < numPackedElements; i++)
{ {
......
...@@ -727,6 +727,8 @@ namespace sw ...@@ -727,6 +727,8 @@ namespace sw
EmitResult EmitImageRead(InsnIterator insn, EmitState *state) const; EmitResult EmitImageRead(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageWrite(InsnIterator insn, EmitState *state) const; EmitResult EmitImageWrite(InsnIterator insn, EmitState *state) const;
SIMD::Int GetTexelOffset(GenericValue const & coordinate, Type const & imageType, Pointer<Byte> descriptor, int texelSize) const;
// OpcodeName() returns the name of the opcode op. // OpcodeName() returns the name of the opcode op.
// If NDEBUG is defined, then OpcodeName() will only return the numerical code. // If NDEBUG is defined, then OpcodeName() will only return the numerical code.
static std::string OpcodeName(spv::Op op); static std::string OpcodeName(spv::Op op);
......
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