Implement 1D image sampling
1D images are currently sampled as if they're 2D images, by setting the
second coordinate to 0.
Bug: b/129523279
Test: dEQP-VK.binding_model.shader_access.primary_cmd_buf.combined_image_sampler_mutable.fragment.single_descriptor.1d
Change-Id: I9aa20cb8b4d43cfdce28c1ec697a72fb6c49c6b5
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29775
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-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 841fe70..75bc8e1 100644
--- a/src/Device/Sampler.hpp
+++ b/src/Device/Sampler.hpp
@@ -70,14 +70,17 @@
enum TextureType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
{
- TEXTURE_NULL,
+ TEXTURE_NULL, // TODO(b/129523279): Eliminate
+ TEXTURE_1D,
TEXTURE_2D,
- TEXTURE_RECTANGLE,
- TEXTURE_CUBE,
TEXTURE_3D,
+ TEXTURE_RECTANGLE, // TODO(b/129523279): Eliminate
+ TEXTURE_CUBE,
+ TEXTURE_1D_ARRAY,
TEXTURE_2D_ARRAY,
+ TEXTURE_CUBE_ARRAY,
- TEXTURE_LAST = TEXTURE_2D_ARRAY
+ TEXTURE_LAST = TEXTURE_CUBE_ARRAY
};
enum FilterType ENUM_UNDERLYING_TYPE_UNSIGNED_INT
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index d11cbce..634833d 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -868,6 +868,7 @@
Pointer<Byte> image, Pointer<SIMD::Float> in, Pointer<Byte> out);
// TODO(b/129523279): Eliminate conversion and use vk::Sampler members directly.
+ static sw::TextureType convertTextureType(VkImageViewType imageViewType);
static sw::FilterType convertFilterMode(const vk::Sampler *sampler);
static sw::MipmapType convertMipmapMode(const vk::Sampler *sampler);
static sw::AddressingMode convertAddressingMode(VkSamplerAddressMode);
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index d8bf659..8dca8fb 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -78,13 +78,10 @@
const vk::ImageView *imageView, const vk::Sampler *sampler,
Pointer<Byte> image, Pointer<SIMD::Float> in, Pointer<Byte> out)
{
- SIMD::Float u = in[0];
- SIMD::Float v = in[1];
-
Pointer<Byte> constants; // FIXME(b/129523279)
Sampler::State samplerState;
- samplerState.textureType = TEXTURE_2D; ASSERT(imageView->getType() == VK_IMAGE_VIEW_TYPE_2D); // TODO(b/129523279)
+ samplerState.textureType = convertTextureType(imageView->getType());
samplerState.textureFormat = imageView->getFormat();
samplerState.textureFilter = convertFilterMode(sampler);
@@ -110,6 +107,7 @@
SamplerCore s(constants, samplerState);
Pointer<Byte> texture = image + OFFSET(vk::SampledImageDescriptor, texture); // sw::Texture*
+ SIMD::Float uv[2];
SIMD::Float w(0); // TODO(b/129523279)
SIMD::Float q(0); // TODO(b/129523279)
SIMD::Float bias(0);
@@ -118,12 +116,32 @@
Vector4f offset; // TODO(b/129523279)
SamplerFunction samplerFunction = { samplerMethod, None }; // TODO(b/129523279)
- if(samplerMethod == Lod)
+ // TODO(b/129523279): Currently 1D textures are treated as 2D by setting the second coordinate to 0.
+ // Implement optimized 1D sampling.
+ uv[1] = SIMD::Float(0);
+
+ int coordinateCount = 0;
+ switch(imageView->getType())
{
- bias = in[2]; // TODO(b/129523279): Index depends on view dimensions and other optional operands.
+ case VK_IMAGE_VIEW_TYPE_1D: coordinateCount = 1; break;
+ case VK_IMAGE_VIEW_TYPE_2D: coordinateCount = 2; break;
+ default:
+ UNIMPLEMENTED("imageView type %d", imageView->getType());
}
- Vector4f sample = s.sampleTexture(texture, u, v, w, q, bias, dsx, dsy, offset, samplerFunction);
+ for(int i = 0; i < coordinateCount; i++)
+ {
+ uv[i] = in[i];
+ }
+
+ if(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[coordinateCount];
+ }
+
+ Vector4f sample = s.sampleTexture(texture, uv[0], uv[1], w, q, bias, dsx, dsy, offset, samplerFunction);
Pointer<SIMD::Float> rgba = out;
rgba[0] = sample.x;
@@ -132,6 +150,23 @@
rgba[3] = sample.w;
}
+sw::TextureType SpirvShader::convertTextureType(VkImageViewType imageViewType)
+{
+ switch(imageViewType)
+ {
+ case VK_IMAGE_VIEW_TYPE_1D: return TEXTURE_1D;
+ case VK_IMAGE_VIEW_TYPE_2D: return TEXTURE_2D;
+// case VK_IMAGE_VIEW_TYPE_3D: return TEXTURE_3D;
+// case VK_IMAGE_VIEW_TYPE_CUBE: return TEXTURE_CUBE;
+// case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return TEXTURE_1D_ARRAY;
+// case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return TEXTURE_2D_ARRAY;
+// case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return TEXTURE_CUBE_ARRAY;
+ default:
+ UNIMPLEMENTED("imageViewType %d", imageViewType);
+ return TEXTURE_2D;
+ }
+}
+
sw::FilterType SpirvShader::convertFilterMode(const vk::Sampler *sampler)
{
switch(sampler->magFilter)