Commit 96fbe081 by Ben Clayton

Dynamic dispatch for image samplers

Bug: b/130746922 Change-Id: I35dfcb93c8e902d0be566fad50ae991d5490e853 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29348Tested-by: 's avatarBen Clayton <bclayton@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 89c37a4d
...@@ -242,6 +242,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command> ...@@ -242,6 +242,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
<ClInclude Include="$(SolutionDir)src\Pipeline\SpirvID.hpp" /> <ClInclude Include="$(SolutionDir)src\Pipeline\SpirvID.hpp" />
<ClCompile Include="$(SolutionDir)src\Pipeline\SpirvShader.cpp" /> <ClCompile Include="$(SolutionDir)src\Pipeline\SpirvShader.cpp" />
<ClInclude Include="$(SolutionDir)src\Pipeline\SpirvShader.hpp" /> <ClInclude Include="$(SolutionDir)src\Pipeline\SpirvShader.hpp" />
<ClCompile Include="$(SolutionDir)src\Pipeline\SpirvShaderSampling.cpp" />
<ClCompile Include="$(SolutionDir)src\Pipeline\SpirvShader_dbg.cpp" /> <ClCompile Include="$(SolutionDir)src\Pipeline\SpirvShader_dbg.cpp" />
<ClCompile Include="$(SolutionDir)src\Pipeline\VertexProgram.cpp" /> <ClCompile Include="$(SolutionDir)src\Pipeline\VertexProgram.cpp" />
<ClInclude Include="$(SolutionDir)src\Pipeline\VertexProgram.hpp" /> <ClInclude Include="$(SolutionDir)src\Pipeline\VertexProgram.hpp" />
......
...@@ -79,6 +79,9 @@ ...@@ -79,6 +79,9 @@
<ClCompile Include="$(SolutionDir)src\Pipeline\SpirvShader_dbg.cpp"> <ClCompile Include="$(SolutionDir)src\Pipeline\SpirvShader_dbg.cpp">
<Filter>src\Pipeline</Filter> <Filter>src\Pipeline</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)src\Pipeline\SpirvShaderSampling.cpp">
<Filter>src\Pipeline</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)src\Pipeline\VertexProgram.cpp"> <ClCompile Include="$(SolutionDir)src\Pipeline\VertexProgram.cpp">
<Filter>src\Pipeline</Filter> <Filter>src\Pipeline</Filter>
</ClCompile> </ClCompile>
......
...@@ -4301,63 +4301,20 @@ namespace sw ...@@ -4301,63 +4301,20 @@ namespace sw
auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet); auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
size_t bindingOffset = setLayout->getBindingOffset(d.Binding, arrayIndex); size_t bindingOffset = setLayout->getBindingOffset(d.Binding, arrayIndex);
const uint8_t *p = reinterpret_cast<const uint8_t*>(state->descriptorSets[d.DescriptorSet]) + bindingOffset; auto descriptor = state->routine->descriptorSets[d.DescriptorSet] + bindingOffset; // vk::SampledImageDescriptor*
const auto *t = reinterpret_cast<const vk::SampledImageDescriptor*>(p); auto sampler = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, sampler)); // vk::Sampler*
auto imageView = *Pointer<Pointer<Byte>>(descriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView*
Sampler::State samplerState;
samplerState.textureType = TEXTURE_2D; ASSERT(t->imageView->getType() == VK_IMAGE_VIEW_TYPE_2D); // TODO(b/129523279) auto samplerFunc = Call(getImageSampler, imageView, sampler);
samplerState.textureFormat = t->imageView->getFormat();
samplerState.textureFilter = FILTER_POINT; ASSERT(t->sampler->magFilter == VK_FILTER_NEAREST); ASSERT(t->sampler->minFilter == VK_FILTER_NEAREST); // TODO(b/129523279) Array<SIMD::Float> in(2);
in[0] = coordinate.Float(0);
samplerState.addressingModeU = ADDRESSING_WRAP; ASSERT(t->sampler->addressModeU == VK_SAMPLER_ADDRESS_MODE_REPEAT); // TODO(b/129523279) in[1] = coordinate.Float(1);
samplerState.addressingModeV = ADDRESSING_WRAP; ASSERT(t->sampler->addressModeV == VK_SAMPLER_ADDRESS_MODE_REPEAT); // TODO(b/129523279)
samplerState.addressingModeW = ADDRESSING_WRAP; ASSERT(t->sampler->addressModeW == VK_SAMPLER_ADDRESS_MODE_REPEAT); // TODO(b/129523279) Array<SIMD::Float> out(4);
samplerState.mipmapFilter = MIPMAP_POINT; ASSERT(t->sampler->mipmapMode == VK_SAMPLER_MIPMAP_MODE_NEAREST); // TODO(b/129523279) Call<ImageSampler>(samplerFunc, sampledImage, &in[0], &out[0]);
samplerState.sRGB = false; ASSERT(t->imageView->getFormat().isSRGBformat() == false); // TODO(b/129523279)
samplerState.swizzleR = SWIZZLE_RED; ASSERT(t->imageView->getComponentMapping().r == VK_COMPONENT_SWIZZLE_R); // TODO(b/129523279) for (int i = 0; i < 4; i++) { result.move(i, out[i]); }
samplerState.swizzleG = SWIZZLE_GREEN; ASSERT(t->imageView->getComponentMapping().g == VK_COMPONENT_SWIZZLE_G); // TODO(b/129523279)
samplerState.swizzleB = SWIZZLE_BLUE; ASSERT(t->imageView->getComponentMapping().b == VK_COMPONENT_SWIZZLE_B); // TODO(b/129523279)
samplerState.swizzleA = SWIZZLE_ALPHA; ASSERT(t->imageView->getComponentMapping().a == VK_COMPONENT_SWIZZLE_A); // TODO(b/129523279)
samplerState.highPrecisionFiltering = false;
samplerState.compare = COMPARE_BYPASS; ASSERT(t->sampler->compareEnable == VK_FALSE); // TODO(b/129523279)
// minLod // TODO(b/129523279)
// maxLod // TODO(b/129523279)
// borderColor // TODO(b/129523279)
ASSERT(t->sampler->mipLodBias == 0.0f); // TODO(b/129523279)
ASSERT(t->sampler->anisotropyEnable == VK_FALSE); // TODO(b/129523279)
ASSERT(t->sampler->unnormalizedCoordinates == VK_FALSE); // TODO(b/129523279)
SamplerCore sampler(constants, samplerState);
Pointer<Byte> texture = sampledImage + OFFSET(vk::SampledImageDescriptor, texture); // sw::Texture*
SIMD::Float u = coordinate.Float(0);
SIMD::Float v = coordinate.Float(1);
SIMD::Float w(0); // TODO(b/129523279)
SIMD::Float q(0); // TODO(b/129523279)
SIMD::Float bias(0); // TODO(b/129523279)
Vector4f dsx; // TODO(b/129523279)
Vector4f dsy; // TODO(b/129523279)
Vector4f offset; // TODO(b/129523279)
SamplerFunction samplerFunction = { Implicit, None }; ASSERT(insn.wordCount() == 5); // TODO(b/129523279)
Vector4f sample = sampler.sampleTextureF(texture, u, v, w, q, bias, dsx, dsy, offset, samplerFunction);
if(getType(resultType.element).opcode() == spv::OpTypeFloat)
{
result.move(0, sample.x);
result.move(1, sample.y);
result.move(2, sample.z);
result.move(3, sample.w);
}
else
{
// TODO(b/129523279): Add a Sampler::sampleTextureI() method.
result.move(0, As<SIMD::Int>(sample.x * SIMD::Float(0xFF)));
result.move(1, As<SIMD::Int>(sample.y * SIMD::Float(0xFF)));
result.move(2, As<SIMD::Int>(sample.z * SIMD::Float(0xFF)));
result.move(3, As<SIMD::Int>(sample.w * SIMD::Float(0xFF)));
}
return EmitResult::Continue; return EmitResult::Continue;
} }
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
namespace vk namespace vk
{ {
class PipelineLayout; class PipelineLayout;
class ImageView;
class Sampler;
} // namespace vk } // namespace vk
namespace sw namespace sw
...@@ -745,6 +747,13 @@ namespace sw ...@@ -745,6 +747,13 @@ namespace sw
// x = significand * 2^exponent // x = significand * 2^exponent
// Returns the pair <significand, exponent> // Returns the pair <significand, exponent>
std::pair<SIMD::Float, SIMD::Int> Frexp(RValue<SIMD::Float> val) const; std::pair<SIMD::Float, SIMD::Int> Frexp(RValue<SIMD::Float> val) const;
using ImageSampler = void(void* image, void* uvsIn, void* texelOut);
static ImageSampler *getImageSampler(vk::ImageView *imageView, vk::Sampler *sampler);
static void emitSamplerFunction(
vk::ImageView *imageView, vk::Sampler *sampler,
Pointer<Byte> image, Pointer<SIMD::Float> in, Pointer<Byte> out);
}; };
class SpirvRoutine class SpirvRoutine
......
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "SpirvShader.hpp"
#include "SamplerCore.hpp" // TODO: Figure out what's needed.
#include "System/Math.hpp"
#include "Vulkan/VkBuffer.hpp"
#include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkDescriptorSet.hpp"
#include "Vulkan/VkPipelineLayout.hpp"
#include "Vulkan/VkImageView.hpp"
#include "Vulkan/VkSampler.hpp"
#include "Vulkan/VkDescriptorSetLayout.hpp"
#include "Device/Config.hpp"
#include <spirv/unified1/spirv.hpp>
#include <spirv/unified1/GLSL.std.450.h>
#include <mutex>
#ifdef Bool
#undef Bool // b/127920555
#undef None
#endif
namespace sw {
SpirvShader::ImageSampler *SpirvShader::getImageSampler(vk::ImageView *imageView, vk::Sampler *sampler)
{
// TODO: Move somewhere sensible.
static std::unordered_map<uintptr_t, ImageSampler*> cache;
static std::mutex mutex;
// TODO: Don't use pointers they can be deleted and reused, combine some two
// unique ids.
auto key = reinterpret_cast<uintptr_t>(imageView) ^ reinterpret_cast<uintptr_t>(sampler);
std::unique_lock<std::mutex> lock(mutex);
auto it = cache.find(key);
if (it != cache.end()) { return it->second; }
// TODO: Hold a separate mutex lock for the sampler being built.
auto function = rr::Function<Void(Pointer<Byte> image, Pointer<SIMD::Float>, Pointer<SIMD::Float>)>();
Pointer<Byte> image = function.Arg<0>();
Pointer<SIMD::Float> in = function.Arg<1>();
Pointer<SIMD::Float> out = function.Arg<2>();
emitSamplerFunction(imageView, sampler, image, in, out);
auto fptr = reinterpret_cast<ImageSampler*>((void *)function("sampler")->getEntry());
cache.emplace(key, fptr);
return fptr;
}
void SpirvShader::emitSamplerFunction(
vk::ImageView *imageView, 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.textureFormat = imageView->getFormat();
samplerState.textureFilter = FILTER_POINT; ASSERT(sampler->magFilter == VK_FILTER_NEAREST); ASSERT(sampler->minFilter == VK_FILTER_NEAREST); // TODO(b/129523279)
samplerState.addressingModeU = ADDRESSING_WRAP; ASSERT(sampler->addressModeU == VK_SAMPLER_ADDRESS_MODE_REPEAT); // TODO(b/129523279)
samplerState.addressingModeV = ADDRESSING_WRAP; ASSERT(sampler->addressModeV == VK_SAMPLER_ADDRESS_MODE_REPEAT); // TODO(b/129523279)
samplerState.addressingModeW = ADDRESSING_WRAP; ASSERT(sampler->addressModeW == VK_SAMPLER_ADDRESS_MODE_REPEAT); // TODO(b/129523279)
samplerState.mipmapFilter = MIPMAP_POINT; ASSERT(sampler->mipmapMode == VK_SAMPLER_MIPMAP_MODE_NEAREST); // TODO(b/129523279)
samplerState.sRGB = false; ASSERT(imageView->getFormat().isSRGBformat() == false); // TODO(b/129523279)
samplerState.swizzleR = SWIZZLE_RED; ASSERT(imageView->getComponentMapping().r == VK_COMPONENT_SWIZZLE_R); // TODO(b/129523279)
samplerState.swizzleG = SWIZZLE_GREEN; ASSERT(imageView->getComponentMapping().g == VK_COMPONENT_SWIZZLE_G); // TODO(b/129523279)
samplerState.swizzleB = SWIZZLE_BLUE; ASSERT(imageView->getComponentMapping().b == VK_COMPONENT_SWIZZLE_B); // TODO(b/129523279)
samplerState.swizzleA = SWIZZLE_ALPHA; ASSERT(imageView->getComponentMapping().a == VK_COMPONENT_SWIZZLE_A); // TODO(b/129523279)
samplerState.highPrecisionFiltering = false;
samplerState.compare = COMPARE_BYPASS; ASSERT(sampler->compareEnable == VK_FALSE); // TODO(b/129523279)
// minLod // TODO(b/129523279)
// maxLod // TODO(b/129523279)
// borderColor // TODO(b/129523279)
ASSERT(sampler->mipLodBias == 0.0f); // TODO(b/129523279)
ASSERT(sampler->anisotropyEnable == VK_FALSE); // TODO(b/129523279)
ASSERT(sampler->unnormalizedCoordinates == VK_FALSE); // TODO(b/129523279)
SamplerCore s(constants, samplerState);
Pointer<Byte> texture = image + OFFSET(vk::SampledImageDescriptor, texture); // sw::Texture*
SIMD::Float w(0); // TODO(b/129523279)
SIMD::Float q(0); // TODO(b/129523279)
SIMD::Float bias(0); // TODO(b/129523279)
Vector4f dsx; // TODO(b/129523279)
Vector4f dsy; // TODO(b/129523279)
Vector4f offset; // TODO(b/129523279)
SamplerFunction samplerFunction = { Implicit, None }; // ASSERT(insn.wordCount() == 5); // TODO(b/129523279)
Vector4f sample = s.sampleTextureF(texture, u, v, w, q, bias, dsx, dsy, offset, samplerFunction);
if(!vk::Format(imageView->getFormat()).isNonNormalizedInteger())
{
Pointer<SIMD::Float> rgba = out;
rgba[0] = sample.x;
rgba[1] = sample.y;
rgba[2] = sample.z;
rgba[3] = sample.w;
}
else
{
// TODO(b/129523279): Add a Sampler::sampleTextureI() method.
Pointer<SIMD::Int> rgba = out;
rgba[0] = As<SIMD::Int>(sample.x * SIMD::Float(0xFF));
rgba[1] = As<SIMD::Int>(sample.y * SIMD::Float(0xFF));
rgba[2] = As<SIMD::Int>(sample.z * SIMD::Float(0xFF));
rgba[3] = As<SIMD::Int>(sample.w * SIMD::Float(0xFF));
}
}
} // namespace sw
\ No newline at end of file
...@@ -160,6 +160,7 @@ IF EXIST "$(SolutionDir)..\deqp\build\external\vulkancts\modules\vulkan\" (copy ...@@ -160,6 +160,7 @@ IF EXIST "$(SolutionDir)..\deqp\build\external\vulkancts\modules\vulkan\" (copy
<ClCompile Include="..\Pipeline\SetupRoutine.cpp" /> <ClCompile Include="..\Pipeline\SetupRoutine.cpp" />
<ClCompile Include="..\Pipeline\ShaderCore.cpp" /> <ClCompile Include="..\Pipeline\ShaderCore.cpp" />
<ClCompile Include="..\Pipeline\SpirvShader.cpp" /> <ClCompile Include="..\Pipeline\SpirvShader.cpp" />
<ClCompile Include="..\Pipeline\SpirvShaderSampling.cpp" />
<ClCompile Include="..\Pipeline\SpirvShader_dbg.cpp" /> <ClCompile Include="..\Pipeline\SpirvShader_dbg.cpp" />
<ClCompile Include="..\Pipeline\VertexProgram.cpp" /> <ClCompile Include="..\Pipeline\VertexProgram.cpp" />
<ClCompile Include="..\Pipeline\VertexRoutine.cpp" /> <ClCompile Include="..\Pipeline\VertexRoutine.cpp" />
......
...@@ -252,6 +252,9 @@ ...@@ -252,6 +252,9 @@
<ClCompile Include="..\Pipeline\SpirvShader.cpp"> <ClCompile Include="..\Pipeline\SpirvShader.cpp">
<Filter>Source Files\Pipeline</Filter> <Filter>Source Files\Pipeline</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\Pipeline\SpirvShaderSampling.cpp">
<Filter>Source Files\Pipeline</Filter>
</ClCompile>
<ClCompile Include="..\Pipeline\SpirvShader_dbg.cpp"> <ClCompile Include="..\Pipeline\SpirvShader_dbg.cpp">
<Filter>Source Files\Pipeline</Filter> <Filter>Source Files\Pipeline</Filter>
</ClCompile> </ClCompile>
......
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