Commit 420d9da0 by Nicolas Capens Committed by Nicolas Capens

Implement OpImageSampleExplicitLod with Grad operand

OpImageSampleExplicitLod can either have a Lod or Grad operand. Bug: b/129523279 Test: dEQP-VK.glsl.texture_functions.texturegrad.sampler2d_fixed_fragment Change-Id: I0c4a885cc6833614572ed7a061b53c9f41838f0b Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30032 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com>
parent 7889633a
...@@ -4456,16 +4456,23 @@ namespace sw ...@@ -4456,16 +4456,23 @@ namespace sw
SpirvShader::EmitResult SpirvShader::EmitImageSampleImplicitLod(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitImageSampleImplicitLod(InsnIterator insn, EmitState *state) const
{ {
ImageInstruction imageInstruction(Implicit); return EmitImageSample({Implicit}, insn, state);
return EmitImageSample(imageInstruction, insn, state);
} }
SpirvShader::EmitResult SpirvShader::EmitImageSampleExplicitLod(InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitImageSampleExplicitLod(InsnIterator insn, EmitState *state) const
{ {
ImageInstruction imageInstruction(Lod); uint32_t imageOperands = static_cast<spv::ImageOperandsMask>(insn.word(5));
return EmitImageSample(imageInstruction, insn, state); if((imageOperands & spv::ImageOperandsLodMask) == imageOperands)
{
return EmitImageSample({Lod}, insn, state);
}
else if((imageOperands & spv::ImageOperandsGradMask) == imageOperands)
{
return EmitImageSample({Grad}, insn, state);
}
else UNIMPLEMENTED("Image Operands %x", imageOperands);
return EmitResult::Continue;
} }
SpirvShader::EmitResult SpirvShader::EmitImageSample(ImageInstruction instruction, InsnIterator insn, EmitState *state) const SpirvShader::EmitResult SpirvShader::EmitImageSample(ImageInstruction instruction, InsnIterator insn, EmitState *state) const
...@@ -4485,14 +4492,13 @@ namespace sw ...@@ -4485,14 +4492,13 @@ namespace sw
auto sampler = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, sampler)); // vk::Sampler* auto sampler = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, sampler)); // vk::Sampler*
auto imageView = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView* auto imageView = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView*
instruction.coordinates = coordinateType.sizeInComponents;
auto samplerFunc = Call(getImageSampler, instruction.parameters, imageView, sampler);
uint32_t imageOperands = spv::ImageOperandsMaskNone; uint32_t imageOperands = spv::ImageOperandsMaskNone;
bool bias = false; bool bias = false;
bool lod = false; bool lod = false;
Object::ID lodId = 0; Object::ID lodId = 0;
bool grad = false; bool grad = false;
Object::ID gradDxId = 0;
Object::ID gradDyId = 0;
bool constOffset = false; bool constOffset = false;
bool sample = false; bool sample = false;
...@@ -4518,8 +4524,11 @@ namespace sw ...@@ -4518,8 +4524,11 @@ namespace sw
if(imageOperands & spv::ImageOperandsGradMask) if(imageOperands & spv::ImageOperandsGradMask)
{ {
UNIMPLEMENTED("Image operand %x", spv::ImageOperandsGradMask); (void)grad; ASSERT(!lod); // SPIR-V 1.3: "It is invalid to set both the Lod and Grad bits."
grad = true; grad = true;
gradDxId = insn.word(operand + 0);
gradDyId = insn.word(operand + 1);
operand += 2;
imageOperands &= ~spv::ImageOperandsGradMask; imageOperands &= ~spv::ImageOperandsGradMask;
} }
...@@ -4543,7 +4552,7 @@ namespace sw ...@@ -4543,7 +4552,7 @@ namespace sw
} }
} }
Array<SIMD::Float> in(coordinateType.sizeInComponents + lod); Array<SIMD::Float> in(16); // Maximum 16 input parameter components.
uint32_t i = 0; uint32_t i = 0;
for( ; i < coordinateType.sizeInComponents; i++) for( ; i < coordinateType.sizeInComponents; i++)
...@@ -4557,6 +4566,31 @@ namespace sw ...@@ -4557,6 +4566,31 @@ namespace sw
in[i] = lodValue.Float(0); in[i] = lodValue.Float(0);
i++; i++;
} }
else if(grad)
{
auto dxValue = GenericValue(this, state->routine, gradDxId);
auto dyValue = GenericValue(this, state->routine, gradDyId);
auto &dxyType = getType(dxValue.type);
ASSERT(dxyType.sizeInComponents == getType(dyValue.type).sizeInComponents);
instruction.gradComponents = dxyType.sizeInComponents;
for(uint32_t j = 0; j < dxyType.sizeInComponents; j++)
{
in[i] = dxValue.Float(j);
i++;
}
for(uint32_t j = 0; j < dxyType.sizeInComponents; j++)
{
in[i] = dyValue.Float(j);
i++;
}
}
instruction.coordinates = coordinateType.sizeInComponents;
auto samplerFunc = Call(getImageSampler, instruction.parameters, imageView, sampler);
Array<SIMD::Float> out(4); Array<SIMD::Float> out(4);
Call<ImageSampler>(samplerFunc, sampledImage.base, &in[0], &out[0], state->routine->constants); Call<ImageSampler>(samplerFunc, sampledImage.base, &in[0], &out[0], state->routine->constants);
......
...@@ -491,7 +491,8 @@ namespace sw ...@@ -491,7 +491,8 @@ namespace sw
struct struct
{ {
uint32_t samplerMethod : BITS(SAMPLER_METHOD_LAST); uint32_t samplerMethod : BITS(SAMPLER_METHOD_LAST);
uint32_t coordinates : 3; uint32_t coordinates : 3; // 1-4
uint32_t gradComponents : 2; // 0-3 (for each of dx / dy)
}; };
uint32_t parameters = 0; uint32_t parameters = 0;
......
...@@ -119,12 +119,23 @@ void SpirvShader::emitSamplerFunction( ...@@ -119,12 +119,23 @@ void SpirvShader::emitSamplerFunction(
uvw[1] = SIMD::Float(0); uvw[1] = SIMD::Float(0);
} }
// Lod and Grad are explicit-lod image operands, and always come after the coordinates.
if(instruction.samplerMethod == Lod) if(instruction.samplerMethod == Lod)
{ {
// Lod is the second optional image operand, and is incompatible with the first one (Bias),
// so it always comes after the coordinates.
bias = in[instruction.coordinates]; bias = in[instruction.coordinates];
} }
else if(instruction.samplerMethod == Grad)
{
for(uint32_t i = 0; i < instruction.gradComponents; i++)
{
dsx[i] = in[instruction.coordinates + i];
}
for(uint32_t i = 0; i < instruction.gradComponents; i++)
{
dsy[i] = in[instruction.coordinates + instruction.gradComponents + i];
}
}
Vector4f sample = s.sampleTexture(texture, uvw[0], uvw[1], uvw[2], q, bias, dsx, dsy, offset, samplerFunction); Vector4f sample = s.sampleTexture(texture, uvw[0], uvw[1], uvw[2], q, bias, dsx, dsy, offset, samplerFunction);
......
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