Commit 977a0a43 by Nicolas Capens Committed by Nicolas Capens

Implement OpImageQueryLod

Vulkan 1.1 spec section 15.6.7. Scale Factor Operation, Level-of-Detail Operation and Image Level(s) Selection clarifies that the first returned parameter is the clamped LOD, rounded to the nearest integer if mipmapMode is VK_SAMPLER_MIPMAP_MODE_NEAREST, and the second parameter is the unclamped LOD with base level and sampler bias applied (we don't take maxSamplerLodBias into account, it is infinite). Bug: b/129523279 Tests: dEQP-VK.glsl.texture_functions.query.texturequerylod.* Tests: dEQP-VK.ycbcr.query.lod.* Change-Id: I4aa2f16716e1e23548b6fb3e0862e7cc442e3678 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31629 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com>
parent f4f427ad
......@@ -83,7 +83,7 @@ namespace sw
cubeFace(face, uuuu, vvvv, u, v, w, M);
}
if(function == Implicit || function == Bias || function == Grad)
if(function == Implicit || function == Bias || function == Grad || function == Query)
{
if(state.textureType != TEXTURE_3D)
{
......@@ -124,8 +124,27 @@ namespace sw
if(function != Base && function != Fetch)
{
lod += *Pointer<Float>(sampler + OFFSET(vk::Sampler, mipLodBias));
if(function == Query)
{
c.y = Float4(lod); // Unclamped LOD.
}
lod = Max(lod, *Pointer<Float>(sampler + OFFSET(vk::Sampler, minLod)));
lod = Min(lod, *Pointer<Float>(sampler + OFFSET(vk::Sampler, maxLod)));
if(function == Query)
{
if(state.mipmapFilter == MIPMAP_POINT)
{
lod = Round(lod); // TODO: Preferred formula is ceil(lod + 0.5) - 1
}
c.x = lod;
// c.y contains unclamped LOD.
return c;
}
}
bool force32BitFiltering = state.highPrecisionFiltering && !hasYuvFormat() && (state.textureFilter != FILTER_POINT);
......
......@@ -35,7 +35,8 @@ namespace sw
Grad, // Use provided gradients.
Fetch, // Use provided integer coordinates.
Base, // Sample base level.
SAMPLER_METHOD_LAST = Base,
Query, // Return implicit LOD.
SAMPLER_METHOD_LAST = Query,
};
enum SamplerOption
......
......@@ -13,8 +13,8 @@
// limitations under the License.
#include "SpirvShader.hpp"
#include "SamplerCore.hpp"
#include "SamplerCore.hpp"
#include "Reactor/Coroutine.hpp"
#include "System/Math.hpp"
#include "Vulkan/VkBuffer.hpp"
......@@ -919,8 +919,9 @@ namespace sw
case spv::OpImageSampleProjDrefImplicitLod:
case spv::OpImageSampleProjDrefExplicitLod:
case spv::OpImageFetch:
case spv::OpImageQuerySize:
case spv::OpImageQuerySizeLod:
case spv::OpImageQuerySize:
case spv::OpImageQueryLod:
case spv::OpImageQueryLevels:
case spv::OpImageQuerySamples:
case spv::OpImageRead:
......@@ -2471,11 +2472,14 @@ namespace sw
case spv::OpImageFetch:
return EmitImageFetch(insn, state);
case spv::OpImageQuerySizeLod:
return EmitImageQuerySizeLod(insn, state);
case spv::OpImageQuerySize:
return EmitImageQuerySize(insn, state);
case spv::OpImageQuerySizeLod:
return EmitImageQuerySizeLod(insn, state);
case spv::OpImageQueryLod:
return EmitImageQueryLod(insn, state);
case spv::OpImageQueryLevels:
return EmitImageQueryLevels(insn, state);
......@@ -4839,12 +4843,12 @@ namespace sw
return EmitResult::Continue;
}
SpirvShader::EmitResult SpirvShader::EmitImageQuerySize(InsnIterator insn, EmitState *state) const
SpirvShader::EmitResult SpirvShader::EmitImageQuerySizeLod(InsnIterator insn, EmitState *state) const
{
auto &resultTy = getType(Type::ID(insn.word(1)));
auto resultId = Object::ID(insn.word(2));
auto imageId = Object::ID(insn.word(3));
auto lodId = Object::ID(0);
auto lodId = Object::ID(insn.word(4));
auto &dst = state->routine->createIntermediate(resultId, resultTy.sizeInComponents);
GetImageDimensions(state->routine, resultTy, imageId, lodId, dst);
......@@ -4852,12 +4856,12 @@ namespace sw
return EmitResult::Continue;
}
SpirvShader::EmitResult SpirvShader::EmitImageQuerySizeLod(InsnIterator insn, EmitState *state) const
SpirvShader::EmitResult SpirvShader::EmitImageQuerySize(InsnIterator insn, EmitState *state) const
{
auto &resultTy = getType(Type::ID(insn.word(1)));
auto resultId = Object::ID(insn.word(2));
auto imageId = Object::ID(insn.word(3));
auto lodId = Object::ID(insn.word(4));
auto lodId = Object::ID(0);
auto &dst = state->routine->createIntermediate(resultId, resultTy.sizeInComponents);
GetImageDimensions(state->routine, resultTy, imageId, lodId, dst);
......@@ -4865,6 +4869,11 @@ namespace sw
return EmitResult::Continue;
}
SpirvShader::EmitResult SpirvShader::EmitImageQueryLod(InsnIterator insn, EmitState *state) const
{
return EmitImageSample({None, Query}, insn, state);
}
void SpirvShader::GetImageDimensions(SpirvRoutine const *routine, Type const &resultTy, Object::ID imageId, Object::ID lodId, Intermediate &dst) const
{
auto &image = getObject(imageId);
......
......@@ -480,7 +480,7 @@ namespace sw
// OpImageSample variants
enum Variant
{
None,
None, // No Dref or Proj. Also used by OpImageFetch and OpImageQueryLod.
Dref,
Proj,
ProjDref,
......@@ -938,8 +938,9 @@ namespace sw
EmitResult EmitImageSampleExplicitLod(Variant variant, InsnIterator insn, EmitState *state) const;
EmitResult EmitImageFetch(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageSample(ImageInstruction instruction, InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQuerySize(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQuerySizeLod(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQuerySize(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQueryLod(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQueryLevels(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageQuerySamples(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageRead(InsnIterator insn, EmitState *state) const;
......
......@@ -89,8 +89,6 @@ SpirvShader::ImageSampler *SpirvShader::emitSamplerFunction(ImageInstruction ins
Pointer<SIMD::Float> out = function.Arg<3>();
Pointer<Byte> constants = function.Arg<4>();
SamplerCore s(constants, samplerState);
SIMD::Float uvw[4];
SIMD::Float q;
SIMD::Float lodOrBias; // Explicit level-of-detail, or bias added to the implicit level-of-detail (depending on samplerMethod).
......@@ -149,6 +147,7 @@ SpirvShader::ImageSampler *SpirvShader::emitSamplerFunction(ImageInstruction ins
}
}
SamplerCore s(constants, samplerState);
Vector4f sample = s.sampleTexture(texture, sampler, uvw[0], uvw[1], uvw[2], q, lodOrBias, dsx, dsy, offset, samplerFunction);
Pointer<SIMD::Float> rgba = out;
......
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