Plumb through Dref parameter to sampler
Bug: b/129523279
Test: dEQP-VK.texture.shadow.*
Test: dEQP-VK.glsl.*
Change-Id: I7e8241cb458200aeabb22992c02f0feb86479ac2
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30649
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Device/Sampler.hpp b/src/Device/Sampler.hpp
index 752d018..c306494 100644
--- a/src/Device/Sampler.hpp
+++ b/src/Device/Sampler.hpp
@@ -150,7 +150,8 @@
MipmapType mipmapFilter;
VkComponentMapping swizzle;
bool highPrecisionFiltering;
- CompareFunc compare;
+ bool compareEnable;
+ VkCompareOp compareOp;
VkBorderColor border;
#if PERF_PROFILE
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 9e2c952..2c0cbf6 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -130,11 +130,11 @@
bool forceFloatFiltering = state.highPrecisionFiltering && !hasYuvFormat() && (state.textureFilter != FILTER_POINT);
bool seamlessCube = (state.addressingModeU == ADDRESSING_SEAMLESS);
bool rectangleTexture = (state.textureType == TEXTURE_RECTANGLE);
- if(hasFloatTexture() || hasUnnormalizedIntegerTexture() || forceFloatFiltering || seamlessCube || rectangleTexture) // FIXME: Mostly identical to integer sampling
+ if(hasFloatTexture() || hasUnnormalizedIntegerTexture() || forceFloatFiltering || seamlessCube || rectangleTexture || state.compareEnable) // FIXME: Mostly identical to integer sampling
{
c = sampleFloatFilter(texture, uuuu, vvvv, wwww, qqqq, offset, lod, anisotropy, uDelta, vDelta, face, function);
- if(!hasFloatTexture() && !hasUnnormalizedIntegerTexture())
+ if(!hasFloatTexture() && !hasUnnormalizedIntegerTexture() && !state.compareEnable)
{
if(has16bitTextureFormat())
{
@@ -1993,27 +1993,29 @@
}
}
- if(state.compare != COMPARE_BYPASS)
+ if(state.compareEnable)
{
Float4 ref = z;
if(!hasFloatTexture())
{
+ // D16_UNORM: clamp reference, normalize texel value
ref = Min(Max(ref, Float4(0.0f)), Float4(1.0f));
+ c.x = c.x * Float4(1.0f / 0xFFFF);
}
Int4 boolean;
- switch(state.compare)
+ switch(state.compareOp)
{
- case COMPARE_LESSEQUAL: boolean = CmpLE(ref, c.x); break;
- case COMPARE_GREATEREQUAL: boolean = CmpNLT(ref, c.x); break;
- case COMPARE_LESS: boolean = CmpLT(ref, c.x); break;
- case COMPARE_GREATER: boolean = CmpNLE(ref, c.x); break;
- case COMPARE_EQUAL: boolean = CmpEQ(ref, c.x); break;
- case COMPARE_NOTEQUAL: boolean = CmpNEQ(ref, c.x); break;
- case COMPARE_ALWAYS: boolean = Int4(-1); break;
- case COMPARE_NEVER: boolean = Int4(0); break;
+ case VK_COMPARE_OP_LESS_OR_EQUAL: boolean = CmpLE(ref, c.x); break;
+ case VK_COMPARE_OP_GREATER_OR_EQUAL: boolean = CmpNLT(ref, c.x); break;
+ case VK_COMPARE_OP_LESS: boolean = CmpLT(ref, c.x); break;
+ case VK_COMPARE_OP_GREATER: boolean = CmpNLE(ref, c.x); break;
+ case VK_COMPARE_OP_EQUAL: boolean = CmpEQ(ref, c.x); break;
+ case VK_COMPARE_OP_NOT_EQUAL: boolean = CmpNEQ(ref, c.x); break;
+ case VK_COMPARE_OP_ALWAYS: boolean = Int4(-1); break;
+ case VK_COMPARE_OP_NEVER: boolean = Int4(0); break;
default: ASSERT(false);
}
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 1a8a261..16a4d73 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -4578,10 +4578,11 @@
Object::ID offsetId = 0;
bool sample = false;
- if(insn.wordCount() > 5)
+ uint32_t operand = instruction.isDref() ? 6 : 5;
+
+ if(insn.wordCount() > operand)
{
- imageOperands = static_cast<spv::ImageOperandsMask>(insn.word(5));
- uint32_t operand = 6;
+ imageOperands = static_cast<spv::ImageOperandsMask>(insn.word(operand++));
if(imageOperands & spv::ImageOperandsBiasMask)
{
@@ -4653,7 +4654,9 @@
if(instruction.isDref())
{
- UNIMPLEMENTED("OpImageSample*Dref*"); // TODO(b/129523279)
+ auto drefValue = GenericValue(this, state->routine, insn.word(5));
+ in[i] = drefValue.Float(0);
+ i++;
}
if(lodOrBias)
@@ -4701,7 +4704,7 @@
Array<SIMD::Float> out(4);
Call<ImageSampler>(samplerFunc, texture, sampler, &in[0], &out[0], state->routine->constants);
- for (int i = 0; i < 4; i++) { result.move(i, out[i]); }
+ for (auto i = 0u; i < resultType.sizeInComponents; i++) { result.move(i, out[i]); }
return EmitResult::Continue;
}
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index b8f1c50..265749b 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -515,6 +515,7 @@
// Parameters are passed to the sampling routine in this order:
uint32_t coordinates : 3; // 1-4 (does not contain projection component)
+ // uint32_t dref : 1; // Indicated by Variant::ProjDref|Dref
// uint32_t lodOrBias : 1; // Indicated by SamplerMethod::Lod|Bias
uint32_t gradComponents : 2; // 0-3 (for each of dx / dy)
uint32_t offsetComponents : 2; // 0-3
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index af7c494..7ea5bfc 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -66,7 +66,8 @@
samplerState.mipmapFilter = convertMipmapMode(sampler);
samplerState.swizzle = imageView->getComponentMapping();
samplerState.highPrecisionFiltering = false;
- samplerState.compare = COMPARE_BYPASS; ASSERT(sampler->compareEnable == VK_FALSE); // TODO(b/129523279)
+ samplerState.compareEnable = (sampler->compareEnable == VK_TRUE);
+ samplerState.compareOp = sampler->compareOp;
ASSERT(sampler->anisotropyEnable == VK_FALSE); // TODO(b/129523279)
ASSERT(sampler->unnormalizedCoordinates == VK_FALSE); // TODO(b/129523279)
@@ -104,6 +105,12 @@
uvw[i] = in[i];
}
+ if (instruction.isDref())
+ {
+ q = in[i];
+ i++;
+ }
+
// TODO(b/129523279): Currently 1D textures are treated as 2D by setting the second coordinate to 0.
// Implement optimized 1D sampling.
if(samplerState.textureType == TEXTURE_1D ||
diff --git a/src/Vulkan/VkFormat.cpp b/src/Vulkan/VkFormat.cpp
index d1debf4..0c41831 100644
--- a/src/Vulkan/VkFormat.cpp
+++ b/src/Vulkan/VkFormat.cpp
@@ -1945,6 +1945,7 @@
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
+ case VK_FORMAT_D16_UNORM:
return false;
case VK_FORMAT_R32_SINT:
case VK_FORMAT_R32_UINT: