Implement OpImageSampleExplicitLod Emit a call to a different trampoline function for generating the sampler code, which unifies the implementation with OpImageSampleExplicitLod's by using a common EmitImageSample which takes a sampler 'method' enum. This is then passed at shader execution time to emitSamplerFunction. The lod parameter is parsed from the instruction stream in EmitImageSample. Other (optional) image operands are left unimplemented for now. Bug: b/129523279 Test: dEQP-VK.binding_model.shader_access.primary_cmd_buf.combined_image_sampler_mutable.fragment.single_descriptor.2d Change-Id: I265b81d953fe5a0496d029704a0f5eeff4229823 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29774 Tested-by: Nicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp index 5921e55..d8bf659 100644 --- a/src/Pipeline/SpirvShaderSampling.cpp +++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -39,14 +39,23 @@ namespace sw { -SpirvShader::ImageSampler *SpirvShader::getImageSampler(const vk::ImageView *imageView, const vk::Sampler *sampler) +SpirvShader::ImageSampler *SpirvShader::getImageSamplerImplicitLod(const vk::ImageView *imageView, const vk::Sampler *sampler) { - // TODO: Move somewhere sensible. + return getImageSampler(Implicit, imageView, sampler); +} +SpirvShader::ImageSampler *SpirvShader::getImageSamplerExplicitLod(const vk::ImageView *imageView, const vk::Sampler *sampler) +{ + return getImageSampler(Lod, imageView, sampler); +} + +SpirvShader::ImageSampler *SpirvShader::getImageSampler(SamplerMethod samplerMethod, const vk::ImageView *imageView, const vk::Sampler *sampler) +{ + // TODO(b/129523279): 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. + // FIXME(b/129523279): Don't use pointers: they can be deleted and reused. Instead combine some two unique ids. + // FIXME(b/129523279): Take instruction opcode and optional parameters into acount (SamplerMethod / SamplerOption). auto key = reinterpret_cast<uintptr_t>(imageView) ^ reinterpret_cast<uintptr_t>(sampler); std::unique_lock<std::mutex> lock(mutex); @@ -58,13 +67,14 @@ 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); + emitSamplerFunction(samplerMethod, imageView, sampler, image, in, out); auto fptr = reinterpret_cast<ImageSampler*>((void *)function("sampler")->getEntry()); cache.emplace(key, fptr); return fptr; } void SpirvShader::emitSamplerFunction( + SamplerMethod samplerMethod, const vk::ImageView *imageView, const vk::Sampler *sampler, Pointer<Byte> image, Pointer<SIMD::Float> in, Pointer<Byte> out) { @@ -102,11 +112,16 @@ 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) + SIMD::Float bias(0); 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) + SamplerFunction samplerFunction = { samplerMethod, None }; // TODO(b/129523279) + + if(samplerMethod == Lod) + { + bias = in[2]; // TODO(b/129523279): Index depends on view dimensions and other optional operands. + } Vector4f sample = s.sampleTexture(texture, u, v, w, q, bias, dsx, dsy, offset, samplerFunction);