Commit 7d867277 by Nicolas Capens Committed by Nicolas Capens

Implement basic SPIR-V texture sampling

Replaces VkDescriptorImageInfo with a more concrete SampledImageDescriptor, which contains an sw::Texture that SamplerCore uses. The parameters can be looked up statically only because the shaderSampledImageArrayDynamicIndexing feature is currently not supported. Bug b/129523279 Test: dEQP-VK.texture.filtering.2d.formats.r8g8b8a8_unorm.nearest Change-Id: I619b5b48b2b4552d9bfc70b087df2c31eabb49ea Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28434 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 avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com>
parent 98e6b968
...@@ -510,8 +510,8 @@ namespace sw ...@@ -510,8 +510,8 @@ namespace sw
{ {
VkOffset3D offset = { 0, 0, static_cast<int32_t>(context->renderTargetLayer[index]) }; VkOffset3D offset = { 0, 0, static_cast<int32_t>(context->renderTargetLayer[index]) };
data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->getOffsetPointer(offset, VK_IMAGE_ASPECT_COLOR_BIT); data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->getOffsetPointer(offset, VK_IMAGE_ASPECT_COLOR_BIT);
data->colorPitchB[index] = context->renderTarget[index]->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT); data->colorPitchB[index] = context->renderTarget[index]->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
data->colorSliceB[index] = context->renderTarget[index]->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT); data->colorSliceB[index] = context->renderTarget[index]->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
} }
} }
...@@ -522,16 +522,16 @@ namespace sw ...@@ -522,16 +522,16 @@ namespace sw
{ {
VkOffset3D offset = { 0, 0, static_cast<int32_t>(context->depthBufferLayer) }; VkOffset3D offset = { 0, 0, static_cast<int32_t>(context->depthBufferLayer) };
data->depthBuffer = (float*)context->depthBuffer->getOffsetPointer(offset, VK_IMAGE_ASPECT_DEPTH_BIT); data->depthBuffer = (float*)context->depthBuffer->getOffsetPointer(offset, VK_IMAGE_ASPECT_DEPTH_BIT);
data->depthPitchB = context->depthBuffer->rowPitchBytes(VK_IMAGE_ASPECT_DEPTH_BIT); data->depthPitchB = context->depthBuffer->rowPitchBytes(VK_IMAGE_ASPECT_DEPTH_BIT, 0);
data->depthSliceB = context->depthBuffer->slicePitchBytes(VK_IMAGE_ASPECT_DEPTH_BIT); data->depthSliceB = context->depthBuffer->slicePitchBytes(VK_IMAGE_ASPECT_DEPTH_BIT, 0);
} }
if(draw->stencilBuffer) if(draw->stencilBuffer)
{ {
VkOffset3D offset = { 0, 0, static_cast<int32_t>(context->stencilBufferLayer) }; VkOffset3D offset = { 0, 0, static_cast<int32_t>(context->stencilBufferLayer) };
data->stencilBuffer = (unsigned char*)context->stencilBuffer->getOffsetPointer(offset, VK_IMAGE_ASPECT_STENCIL_BIT); data->stencilBuffer = (unsigned char*)context->stencilBuffer->getOffsetPointer(offset, VK_IMAGE_ASPECT_STENCIL_BIT);
data->stencilPitchB = context->stencilBuffer->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT); data->stencilPitchB = context->stencilBuffer->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
data->stencilSliceB = context->stencilBuffer->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT); data->stencilSliceB = context->stencilBuffer->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
} }
} }
...@@ -881,9 +881,9 @@ namespace sw ...@@ -881,9 +881,9 @@ namespace sw
query->state = vk::Query::FINISHED; query->state = vk::Query::FINISHED;
} }
// Manual unlocking is done before notifying, to avoid // Manual unlocking is done before notifying, to avoid
// waking up the waiting thread only to block again // waking up the waiting thread only to block again
mutexLock.unlock(); mutexLock.unlock();
query->condition.notify_one(); query->condition.notify_one();
} }
......
...@@ -56,13 +56,13 @@ namespace sw ...@@ -56,13 +56,13 @@ namespace sw
float4 heightLOD; float4 heightLOD;
float4 depthLOD; float4 depthLOD;
word4 borderColor4[4]; word4 borderColor4[4]; // FIXME(b/129523279): Part of Vulkan sampler.
float4 borderColorF[4]; float4 borderColorF[4]; // FIXME(b/129523279): Part of Vulkan sampler.
float maxAnisotropy; float maxAnisotropy; // FIXME(b/129523279): Part of Vulkan sampler.
int baseLevel; int baseLevel;
int maxLevel; int maxLevel;
float minLod; float minLod; // FIXME(b/129523279): Part of Vulkan sampler.
float maxLod; float maxLod; // FIXME(b/129523279): Part of Vulkan sampler.
}; };
enum SamplerType enum SamplerType
......
...@@ -227,7 +227,7 @@ namespace sw ...@@ -227,7 +227,7 @@ namespace sw
return c; return c;
} }
Vector4f SamplerCore::sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function) Vector4f SamplerCore::sampleTextureF(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function)
{ {
Vector4f c; Vector4f c;
......
...@@ -51,7 +51,7 @@ namespace sw ...@@ -51,7 +51,7 @@ namespace sw
SamplerCore(Pointer<Byte> &constants, const Sampler::State &state); SamplerCore(Pointer<Byte> &constants, const Sampler::State &state);
Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy); Vector4s sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy);
Vector4f sampleTexture(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function); Vector4f sampleTextureF(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &bias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
static Vector4f textureSize(Pointer<Byte> &mipmap, Float4 &lod); static Vector4f textureSize(Pointer<Byte> &mipmap, Float4 &lod);
private: private:
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "SpirvShader.hpp" #include "SpirvShader.hpp"
#include "SamplerCore.hpp"
#include "System/Math.hpp" #include "System/Math.hpp"
#include "Vulkan/VkBuffer.hpp" #include "Vulkan/VkBuffer.hpp"
#include "Vulkan/VkDebug.hpp" #include "Vulkan/VkDebug.hpp"
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
#ifdef Bool #ifdef Bool
#undef Bool // b/127920555 #undef Bool // b/127920555
#undef None
#endif #endif
namespace namespace
...@@ -338,6 +340,12 @@ namespace sw ...@@ -338,6 +340,12 @@ namespace sw
break; // Correctly handled. break; // Correctly handled.
case spv::StorageClassUniformConstant: case spv::StorageClassUniformConstant:
// This storage class is for data stored within the descriptor itself,
// unlike StorageClassUniform which contains handles to buffers.
// For Vulkan it corresponds with samplers, images, or combined image samplers.
object.kind = Object::Kind::SampledImage;
break;
case spv::StorageClassWorkgroup: case spv::StorageClassWorkgroup:
case spv::StorageClassCrossWorkgroup: case spv::StorageClassCrossWorkgroup:
case spv::StorageClassGeneric: case spv::StorageClassGeneric:
...@@ -470,9 +478,12 @@ namespace sw ...@@ -470,9 +478,12 @@ namespace sw
break; break;
case spv::OpFConvert: case spv::OpFConvert:
UNIMPLEMENTED("No valid uses for OpFConvert until we support multiple bit widths enabled by features such as Float16/Float64 etc.");
break;
case spv::OpSConvert: case spv::OpSConvert:
case spv::OpUConvert: case spv::OpUConvert:
UNIMPLEMENTED("No valid uses for Op*Convert until we support multiple bit widths"); UNIMPLEMENTED("No valid uses for Op*Convert until we support multiple bit widths enabled by features such as Int16/Int64 etc.");
break; break;
case spv::OpLoad: case spv::OpLoad:
...@@ -597,18 +608,10 @@ namespace sw ...@@ -597,18 +608,10 @@ namespace sw
case spv::OpFwidthFine: case spv::OpFwidthFine:
case spv::OpAtomicLoad: case spv::OpAtomicLoad:
case spv::OpPhi: case spv::OpPhi:
// Instructions that yield an intermediate value or divergent case spv::OpImageSampleImplicitLod:
// pointer // Instructions that yield an intermediate value or divergent pointer
{ DefineResult(insn);
Type::ID typeId = insn.word(1);
Object::ID resultId = insn.word(2);
auto &object = defs[resultId];
object.type = typeId;
object.kind = (getType(typeId).opcode() == spv::OpTypePointer)
? Object::Kind::DivergentPointer : Object::Kind::Intermediate;
object.definition = insn;
break; break;
}
case spv::OpStore: case spv::OpStore:
case spv::OpAtomicStore: case spv::OpAtomicStore:
...@@ -1852,6 +1855,8 @@ namespace sw ...@@ -1852,6 +1855,8 @@ namespace sw
case spv::OpTypeStruct: case spv::OpTypeStruct:
case spv::OpTypePointer: case spv::OpTypePointer:
case spv::OpTypeFunction: case spv::OpTypeFunction:
case spv::OpTypeImage:
case spv::OpTypeSampledImage:
case spv::OpExecutionMode: case spv::OpExecutionMode:
case spv::OpMemoryModel: case spv::OpMemoryModel:
case spv::OpFunction: case spv::OpFunction:
...@@ -2056,6 +2061,9 @@ namespace sw ...@@ -2056,6 +2061,9 @@ namespace sw
case spv::OpKill: case spv::OpKill:
return EmitKill(insn, state); return EmitKill(insn, state);
case spv::OpImageSampleImplicitLod:
return EmitImageSampleImplicitLod(insn, state);
default: default:
UNIMPLEMENTED("opcode: %s", OpcodeName(opcode).c_str()); UNIMPLEMENTED("opcode: %s", OpcodeName(opcode).c_str());
break; break;
...@@ -2095,6 +2103,20 @@ namespace sw ...@@ -2095,6 +2103,20 @@ namespace sw
routine->createPointer(resultId, &routine->getVariable(resultId)[0]); routine->createPointer(resultId, &routine->getVariable(resultId)[0]);
break; break;
} }
case spv::StorageClassUniformConstant:
{
const auto &d = descriptorDecorations.at(resultId);
ASSERT(d.DescriptorSet >= 0);
ASSERT(d.Binding >= 0);
uint32_t arrayIndex = 0; // TODO(b/129523279)
auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
size_t bindingOffset = setLayout->getBindingOffset(d.Binding, arrayIndex);
Pointer<Byte> set = routine->descriptorSets[d.DescriptorSet]; // DescriptorSet*
Pointer<Byte> binding = Pointer<Byte>(set + bindingOffset); // SampledImageDescriptor*
routine->createPointer(resultId, binding);
break;
}
case spv::StorageClassUniform: case spv::StorageClassUniform:
case spv::StorageClassStorageBuffer: case spv::StorageClassStorageBuffer:
{ {
...@@ -2133,6 +2155,16 @@ namespace sw ...@@ -2133,6 +2155,16 @@ namespace sw
ASSERT(Type::ID(insn.word(1)) == result.type); ASSERT(Type::ID(insn.word(1)) == result.type);
ASSERT(!atomic || getType(getType(pointer.type).element).opcode() == spv::OpTypeInt); // Vulkan 1.1: "Atomic instructions must declare a scalar 32-bit integer type, for the value pointed to by Pointer." ASSERT(!atomic || getType(getType(pointer.type).element).opcode() == spv::OpTypeInt); // Vulkan 1.1: "Atomic instructions must declare a scalar 32-bit integer type, for the value pointed to by Pointer."
if(pointer.kind == Object::Kind::SampledImage)
{
// Just propagate the pointer.
// TODO(b/129523279)
auto &ptr = routine->getPointer(pointerId);
routine->createPointer(resultId, ptr);
return EmitResult::Continue;
}
if(atomic) if(atomic)
{ {
Object::ID semanticsId = insn.word(5); Object::ID semanticsId = insn.word(5);
...@@ -4125,6 +4157,86 @@ namespace sw ...@@ -4125,6 +4157,86 @@ namespace sw
return EmitResult::Continue; return EmitResult::Continue;
} }
SpirvShader::EmitResult SpirvShader::EmitImageSampleImplicitLod(InsnIterator insn, EmitState *state) const
{
Type::ID resultTypeId = insn.word(1);
Object::ID resultId = insn.word(2);
Object::ID sampledImageId = insn.word(3);
Object::ID coordinateId = insn.word(4);
auto &resultType = getType(resultTypeId);
auto &result = state->routine->createIntermediate(resultId, resultType.sizeInComponents);
auto &sampledImage = state->routine->getPointer(sampledImageId);
auto coordinate = GenericValue(this, state->routine, coordinateId);
Pointer<Byte> constants; // FIXME(b/129523279)
const DescriptorDecorations &d = descriptorDecorations.at(sampledImageId);
uint32_t arrayIndex = 0; // TODO(b/129523279)
auto setLayout = state->routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
size_t bindingOffset = setLayout->getBindingOffset(d.Binding, arrayIndex);
const uint8_t *p = reinterpret_cast<const uint8_t*>(state->descriptorSets[d.DescriptorSet]) + bindingOffset;
const auto *t = reinterpret_cast<const vk::SampledImageDescriptor*>(p);
Sampler::State samplerState;
samplerState.textureType = TEXTURE_2D; ASSERT(t->imageView->getType() == VK_IMAGE_VIEW_TYPE_2D); // TODO(b/129523279)
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)
samplerState.addressingModeU = ADDRESSING_WRAP; ASSERT(t->sampler->addressModeU == VK_SAMPLER_ADDRESS_MODE_REPEAT); // TODO(b/129523279)
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)
samplerState.mipmapFilter = MIPMAP_POINT; ASSERT(t->sampler->mipmapMode == VK_SAMPLER_MIPMAP_MODE_NEAREST); // TODO(b/129523279)
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)
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;
}
void SpirvShader::emitEpilog(SpirvRoutine *routine) const void SpirvShader::emitEpilog(SpirvRoutine *routine) const
{ {
for (auto insn : *this) for (auto insn : *this)
......
...@@ -283,6 +283,9 @@ namespace sw ...@@ -283,6 +283,9 @@ namespace sw
// A pointer to a vk::DescriptorSet*. // A pointer to a vk::DescriptorSet*.
// Pointer held by SpirvRoutine::pointers. // Pointer held by SpirvRoutine::pointers.
DescriptorSet, DescriptorSet,
// Pointer to an image/sampler descriptor.
SampledImage,
}; };
Kind kind = Kind::Unknown; Kind kind = Kind::Unknown;
...@@ -719,6 +722,7 @@ namespace sw ...@@ -719,6 +722,7 @@ namespace sw
EmitResult EmitReturn(InsnIterator insn, EmitState *state) const; EmitResult EmitReturn(InsnIterator insn, EmitState *state) const;
EmitResult EmitKill(InsnIterator insn, EmitState *state) const; EmitResult EmitKill(InsnIterator insn, EmitState *state) const;
EmitResult EmitPhi(InsnIterator insn, EmitState *state) const; EmitResult EmitPhi(InsnIterator insn, EmitState *state) const;
EmitResult EmitImageSampleImplicitLod(InsnIterator insn, EmitState *state) const;
// OpcodeName() returns the name of the opcode op. // OpcodeName() returns the name of the opcode op.
// If NDEBUG is defined, then OpcodeName() will only return the numerical code. // If NDEBUG is defined, then OpcodeName() will only return the numerical code.
......
...@@ -17,11 +17,25 @@ ...@@ -17,11 +17,25 @@
#include "VkObject.hpp" #include "VkObject.hpp"
#include "Vulkan/VkSampler.hpp"
#include "Vulkan/VkImageView.hpp"
#include "Device/Sampler.hpp"
namespace vk namespace vk
{ {
class DescriptorSet; class DescriptorSet;
// TODO(b/129523279): Move to the Device or Pipeline layer.
struct SampledImageDescriptor
{
// TODO(b/129523279): Minimize to the data actually needed.
vk::Sampler *sampler;
vk::ImageView *imageView;
sw::Texture texture;
};
class DescriptorSetLayout : public Object<DescriptorSetLayout, VkDescriptorSetLayout> class DescriptorSetLayout : public Object<DescriptorSetLayout, VkDescriptorSetLayout>
{ {
public: public:
......
...@@ -144,7 +144,6 @@ bool Format::isSRGBformat() const ...@@ -144,7 +144,6 @@ bool Format::isSRGBformat() const
bool Format::isSRGBreadable() const bool Format::isSRGBreadable() const
{ {
// Keep in sync with Capabilities::isSRGBreadable
switch(format) switch(format)
{ {
case VK_FORMAT_B8G8R8A8_UNORM: case VK_FORMAT_B8G8R8A8_UNORM:
...@@ -160,7 +159,6 @@ bool Format::isSRGBreadable() const ...@@ -160,7 +159,6 @@ bool Format::isSRGBreadable() const
bool Format::isSRGBwritable() const bool Format::isSRGBwritable() const
{ {
// Keep in sync with Capabilities::isSRGBwritable
switch(format) switch(format)
{ {
case VK_FORMAT_UNDEFINED: case VK_FORMAT_UNDEFINED:
......
...@@ -36,23 +36,28 @@ public: ...@@ -36,23 +36,28 @@ public:
void clear(const VkClearValue& clearValue, VkImageAspectFlags aspectMask, const VkClearRect& renderArea); void clear(const VkClearValue& clearValue, VkImageAspectFlags aspectMask, const VkClearRect& renderArea);
void resolve(ImageView* resolveAttachment); void resolve(ImageView* resolveAttachment);
VkImageViewType getType() const { return viewType; }
Format getFormat() const { return format; } Format getFormat() const { return format; }
int getSampleCount() const { return image->getSampleCountFlagBits(); } int getSampleCount() const { return image->getSampleCountFlagBits(); }
int rowPitchBytes(VkImageAspectFlagBits aspect) const { return image->rowPitchBytes(aspect, subresourceRange.baseMipLevel); } int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const { return image->rowPitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel); }
int slicePitchBytes(VkImageAspectFlagBits aspect) const { return image->slicePitchBytes(aspect, subresourceRange.baseMipLevel); } int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const { return image->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel); }
VkExtent3D getMipLevelExtent(uint32_t mipLevel) const { return image->getMipLevelExtent(subresourceRange.baseMipLevel + mipLevel); }
void *getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect) const; void *getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect) const;
bool hasDepthAspect() const { return (subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; } bool hasDepthAspect() const { return (subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; }
bool hasStencilAspect() const { return (subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; } bool hasStencilAspect() const { return (subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; }
const VkComponentMapping &getComponentMapping() const { return components; }
const VkImageSubresourceRange &getSubresourceRange() const { return subresourceRange; }
private: private:
bool imageTypesMatch(VkImageType imageType) const; bool imageTypesMatch(VkImageType imageType) const;
Image* image = nullptr; Image *const image = nullptr;
VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_2D; const VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_2D;
Format format; const Format format;
VkComponentMapping components = {}; const VkComponentMapping components = {};
VkImageSubresourceRange subresourceRange = {}; const VkImageSubresourceRange subresourceRange = {};
}; };
static inline ImageView* Cast(VkImageView object) static inline ImageView* Cast(VkImageView object)
......
...@@ -49,22 +49,21 @@ public: ...@@ -49,22 +49,21 @@ public:
return 0; return 0;
} }
private: const VkFilter magFilter = VK_FILTER_NEAREST;
VkFilter magFilter = VK_FILTER_NEAREST; const VkFilter minFilter = VK_FILTER_NEAREST;
VkFilter minFilter = VK_FILTER_NEAREST; const VkSamplerMipmapMode mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
VkSamplerMipmapMode mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; const VkSamplerAddressMode addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
VkSamplerAddressMode addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; const VkSamplerAddressMode addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
VkSamplerAddressMode addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; const VkSamplerAddressMode addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
VkSamplerAddressMode addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; const float mipLodBias = 0.0f;
float mipLodBias = 0.0f; const VkBool32 anisotropyEnable = VK_FALSE;
VkBool32 anisotropyEnable = VK_FALSE; const float maxAnisotropy = 0.0f;
float maxAnisotropy = 0.0f; const VkBool32 compareEnable = VK_FALSE;
VkBool32 compareEnable = VK_FALSE; const VkCompareOp compareOp = VK_COMPARE_OP_NEVER;
VkCompareOp compareOp = VK_COMPARE_OP_NEVER; const float minLod = 0.0f;
float minLod = 0.0f; const float maxLod = 0.0f;
float maxLod = 0.0f; const VkBorderColor borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
VkBorderColor borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; const VkBool32 unnormalizedCoordinates = VK_FALSE;
VkBool32 unnormalizedCoordinates = VK_FALSE;
}; };
static inline Sampler* Cast(VkSampler object) static inline Sampler* Cast(VkSampler object)
......
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