Wire up depth and stencil attachments to pipeline
- Fix broken use of VkImageCreateFlags in various places as an aspect mask
- Be consistent about layout of D+S images. Layout is now [aspect][layer][level].
- Allow fetching an offset into a particular aspect.
Fixes dEQP-VK.pipeline.depth.*
Bug: b/118619338
Change-Id: I46adc9c637882e7144945eaeacce9f087d53caf0
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26011
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index e116de4..9634c10 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -159,6 +159,38 @@
const VkIndexType indexType;
};
+void CommandBuffer::ExecutionState::bindAttachments()
+{
+ // Binds all the attachments for the current subpass
+ // Ideally this would be performed by BeginRenderPass and NextSubpass, but
+ // there is too much stomping of the renderer's state by setContext() in
+ // draws.
+
+ for (auto i = 0u; i < renderPass->getCurrentSubpass().colorAttachmentCount; i++)
+ {
+ auto attachmentReference = renderPass->getCurrentSubpass().pColorAttachments[i];
+ if (attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
+ {
+ auto attachment = renderPassFramebuffer->getAttachment(attachmentReference.attachment);
+ renderer->setRenderTarget(i, attachment, 0);
+ }
+ }
+
+ auto attachmentReference = renderPass->getCurrentSubpass().pDepthStencilAttachment;
+ if (attachmentReference && attachmentReference->attachment != VK_ATTACHMENT_UNUSED)
+ {
+ auto attachment = renderPassFramebuffer->getAttachment(attachmentReference->attachment);
+ if (attachment->hasDepthAspect())
+ {
+ renderer->setDepthBuffer(attachment, 0);
+ }
+ if (attachment->hasStencilAspect())
+ {
+ renderer->setStencilBuffer(attachment, 0);
+ }
+ }
+}
+
struct Draw : public CommandBuffer::Command
{
Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
@@ -189,15 +221,7 @@
executionState.renderer->setViewport(pipeline->getViewport());
executionState.renderer->setBlendConstant(pipeline->getBlendConstants());
- for (auto i = 0u; i < executionState.renderPass->getCurrentSubpass().colorAttachmentCount; i++)
- {
- auto attachmentReference = executionState.renderPass->getCurrentSubpass().pColorAttachments[i];
- if (attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
- {
- auto attachment = executionState.renderPassFramebuffer->getAttachment(attachmentReference.attachment);
- executionState.renderer->setRenderTarget(i, attachment, 0);
- }
- }
+ executionState.bindAttachments();
const uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount);
const uint32_t lastInstance = firstInstance + instanceCount - 1;
@@ -247,15 +271,7 @@
executionState.renderer->setViewport(pipeline->getViewport());
executionState.renderer->setBlendConstant(pipeline->getBlendConstants());
- for (auto i = 0u; i < executionState.renderPass->getCurrentSubpass().colorAttachmentCount; i++)
- {
- auto attachmentReference = executionState.renderPass->getCurrentSubpass().pColorAttachments[i];
- if (attachmentReference.attachment != VK_ATTACHMENT_UNUSED)
- {
- auto attachment = executionState.renderPassFramebuffer->getAttachment(attachmentReference.attachment);
- executionState.renderer->setRenderTarget(i, attachment, 0);
- }
- }
+ executionState.bindAttachments();
auto drawType = executionState.indexType == VK_INDEX_TYPE_UINT16
? (context.drawType | sw::DRAW_INDEXED16) : (context.drawType | sw::DRAW_INDEXED32);
diff --git a/src/Vulkan/VkCommandBuffer.hpp b/src/Vulkan/VkCommandBuffer.hpp
index eb5f891..38d8e59 100644
--- a/src/Vulkan/VkCommandBuffer.hpp
+++ b/src/Vulkan/VkCommandBuffer.hpp
@@ -135,6 +135,8 @@
VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
VertexInputBinding indexBufferBinding;
VkIndexType indexType;
+
+ void bindAttachments();
};
void submit(CommandBuffer::ExecutionState& executionState);
diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp
index 17c3213..463a8f7 100644
--- a/src/Vulkan/VkImage.cpp
+++ b/src/Vulkan/VkImage.cpp
@@ -19,6 +19,25 @@
#include "Device/Surface.hpp"
#include <cstring>
+namespace
+{
+ VkImageAspectFlags GetAspects(VkFormat format)
+ {
+ // TODO: probably just flatten this out to a full format list, and alter
+ // isDepth / isStencil etc to check for their aspect
+
+ VkImageAspectFlags aspects = 0;
+ if (sw::Surface::isDepth(format)) aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
+ if (sw::Surface::isStencil(format)) aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
+
+ // TODO: YCbCr planar formats have different aspects
+
+ // Anything else is "color".
+ if (!aspects) aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
+ return aspects;
+ }
+}
+
namespace vk
{
@@ -55,7 +74,7 @@
VkMemoryRequirements memoryRequirements;
memoryRequirements.alignment = vk::REQUIRED_MEMORY_ALIGNMENT;
memoryRequirements.memoryTypeBits = vk::MEMORY_TYPE_GENERIC_BIT;
- memoryRequirements.size = getStorageSize(flags);
+ memoryRequirements.size = getStorageSize(GetAspects(format));
return memoryRequirements;
}
@@ -67,11 +86,19 @@
void Image::getSubresourceLayout(const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout) const
{
- pLayout->offset = getMemoryOffset(flags, pSubresource->mipLevel, pSubresource->arrayLayer);
- pLayout->size = getMipLevelSize(flags, pSubresource->mipLevel);
- pLayout->rowPitch = rowPitchBytes(flags, pSubresource->mipLevel);
- pLayout->depthPitch = slicePitchBytes(flags, pSubresource->mipLevel);
- pLayout->arrayPitch = getLayerSize(flags);
+ // By spec, aspectMask has a single bit set.
+ if (!((pSubresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
+ (pSubresource->aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
+ (pSubresource->aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)))
+ {
+ UNIMPLEMENTED();
+ }
+ auto aspect = static_cast<VkImageAspectFlagBits>(pSubresource->aspectMask);
+ pLayout->offset = getMemoryOffset(aspect, pSubresource->mipLevel, pSubresource->arrayLayer);
+ pLayout->size = getMipLevelSize(aspect, pSubresource->mipLevel);
+ pLayout->rowPitch = rowPitchBytes(aspect, pSubresource->mipLevel);
+ pLayout->depthPitch = slicePitchBytes(aspect, pSubresource->mipLevel);
+ pLayout->arrayPitch = getLayerSize(aspect);
}
void Image::copyTo(VkImage dstImage, const VkImageCopy& pRegion)
@@ -79,8 +106,6 @@
// Image copy does not perform any conversion, it simply copies memory from
// an image to another image that has the same number of bytes per pixel.
Image* dst = Cast(dstImage);
- int srcBytesPerTexel = bytesPerTexel(pRegion.srcSubresource.aspectMask);
- ASSERT(srcBytesPerTexel == dst->bytesPerTexel(pRegion.dstSubresource.aspectMask));
if(!((pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
(pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
@@ -100,13 +125,19 @@
UNIMPLEMENTED();
}
+ VkImageAspectFlagBits srcAspect = static_cast<VkImageAspectFlagBits>(pRegion.srcSubresource.aspectMask);
+ VkImageAspectFlagBits dstAspect = static_cast<VkImageAspectFlagBits>(pRegion.dstSubresource.aspectMask);
+
+ int srcBytesPerTexel = bytesPerTexel(srcAspect);
+ ASSERT(srcBytesPerTexel == dst->bytesPerTexel(dstAspect));
+
const char* srcMem = static_cast<const char*>(getTexelPointer(pRegion.srcOffset, pRegion.srcSubresource));
char* dstMem = static_cast<char*>(dst->getTexelPointer(pRegion.dstOffset, pRegion.dstSubresource));
- int srcRowPitchBytes = rowPitchBytes(pRegion.srcSubresource.aspectMask, pRegion.srcSubresource.mipLevel);
- int srcSlicePitchBytes = slicePitchBytes(pRegion.srcSubresource.aspectMask, pRegion.srcSubresource.mipLevel);
- int dstRowPitchBytes = dst->rowPitchBytes(pRegion.dstSubresource.aspectMask, pRegion.dstSubresource.mipLevel);
- int dstSlicePitchBytes = dst->slicePitchBytes(pRegion.dstSubresource.aspectMask, pRegion.dstSubresource.mipLevel);
+ int srcRowPitchBytes = rowPitchBytes(srcAspect, pRegion.srcSubresource.mipLevel);
+ int srcSlicePitchBytes = slicePitchBytes(srcAspect, pRegion.srcSubresource.mipLevel);
+ int dstRowPitchBytes = dst->rowPitchBytes(dstAspect, pRegion.dstSubresource.mipLevel);
+ int dstSlicePitchBytes = dst->slicePitchBytes(dstAspect, pRegion.dstSubresource.mipLevel);
VkExtent3D srcExtent = getMipLevelExtent(pRegion.srcSubresource.mipLevel);
VkExtent3D dstExtent = dst->getMipLevelExtent(pRegion.dstSubresource.mipLevel);
@@ -167,10 +198,12 @@
UNIMPLEMENTED();
}
+ VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(region.imageSubresource.aspectMask);
+
VkExtent3D mipLevelExtent = getMipLevelExtent(region.imageSubresource.mipLevel);
- int imageBytesPerTexel = bytesPerTexel(region.imageSubresource.aspectMask);
- int imageRowPitchBytes = rowPitchBytes(region.imageSubresource.aspectMask, region.imageSubresource.mipLevel);
- int imageSlicePitchBytes = slicePitchBytes(region.imageSubresource.aspectMask, region.imageSubresource.mipLevel);
+ int imageBytesPerTexel = bytesPerTexel(aspect);
+ int imageRowPitchBytes = rowPitchBytes(aspect, region.imageSubresource.mipLevel);
+ int imageSlicePitchBytes = slicePitchBytes(aspect, region.imageSubresource.mipLevel);
int bufferRowPitchBytes = ((region.bufferRowLength == 0) ? region.imageExtent.width : region.bufferRowLength) *
imageBytesPerTexel;
int bufferSlicePitchBytes = (((region.bufferImageHeight == 0) || (region.bufferRowLength == 0))) ?
@@ -189,10 +222,10 @@
bool isEntirePlane = isEntireLine && (region.imageExtent.height == mipLevelExtent.height) &&
(imageSlicePitchBytes == bufferSlicePitchBytes);
- VkDeviceSize layerSize = getLayerSize(flags);
+ VkDeviceSize layerSize = getLayerSize(aspect);
char* bufferMemory = static_cast<char*>(Cast(buffer)->getOffsetPointer(region.bufferOffset));
char* imageMemory = static_cast<char*>(deviceMemory->getOffsetPointer(
- getMemoryOffset(region.imageSubresource.aspectMask, region.imageSubresource.mipLevel,
+ getMemoryOffset(aspect, region.imageSubresource.mipLevel,
region.imageSubresource.baseArrayLayer) +
texelOffsetBytesInStorage(region.imageOffset, region.imageSubresource)));
char* srcMemory = bufferIsSource ? bufferMemory : imageMemory;
@@ -265,15 +298,17 @@
void* Image::getTexelPointer(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const
{
+ VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(subresource.aspectMask);
return deviceMemory->getOffsetPointer(texelOffsetBytesInStorage(offset, subresource) +
- getMemoryOffset(flags, subresource.mipLevel, subresource.baseArrayLayer));
+ getMemoryOffset(aspect, subresource.mipLevel, subresource.baseArrayLayer));
}
VkDeviceSize Image::texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const
{
- return offset.z * slicePitchBytes(flags, subresource.mipLevel) +
- offset.y * rowPitchBytes(flags, subresource.mipLevel) +
- offset.x * bytesPerTexel(flags);
+ VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(subresource.aspectMask);
+ return offset.z * slicePitchBytes(aspect, subresource.mipLevel) +
+ offset.y * rowPitchBytes(aspect, subresource.mipLevel) +
+ offset.x * bytesPerTexel(aspect);
}
VkExtent3D Image::getMipLevelExtent(uint32_t mipLevel) const
@@ -298,34 +333,34 @@
return mipLevelExtent;
}
-int Image::rowPitchBytes(const VkImageAspectFlags& flags, uint32_t mipLevel) const
+int Image::rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
// Depth and Stencil pitch should be computed separately
- ASSERT((flags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
+ ASSERT((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
- return sw::Surface::pitchB(getMipLevelExtent(mipLevel).width, isCube() ? 1 : 0, getFormat(flags), false);
+ return sw::Surface::pitchB(getMipLevelExtent(mipLevel).width, isCube() ? 1 : 0, getFormat(aspect), false);
}
-int Image::slicePitchBytes(const VkImageAspectFlags& flags, uint32_t mipLevel) const
+int Image::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
// Depth and Stencil slice should be computed separately
- ASSERT((flags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
+ ASSERT((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
VkExtent3D mipLevelExtent = getMipLevelExtent(mipLevel);
- return sw::Surface::sliceB(mipLevelExtent.width, mipLevelExtent.height, isCube() ? 1 : 0, getFormat(flags), false);
+ return sw::Surface::sliceB(mipLevelExtent.width, mipLevelExtent.height, isCube() ? 1 : 0, getFormat(aspect), false);
}
-int Image::bytesPerTexel(const VkImageAspectFlags& flags) const
+int Image::bytesPerTexel(VkImageAspectFlagBits aspect) const
{
// Depth and Stencil bytes should be computed separately
- ASSERT((flags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
+ ASSERT((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) !=
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
- return sw::Surface::bytes(getFormat(flags));
+ return sw::Surface::bytes(getFormat(aspect));
}
-VkFormat Image::getFormat(const VkImageAspectFlags& flags) const
+VkFormat Image::getFormat(VkImageAspectFlagBits aspect) const
{
- switch(flags)
+ switch(aspect)
{
case VK_IMAGE_ASPECT_DEPTH_BIT:
switch(format)
@@ -363,14 +398,14 @@
return (flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && (imageType == VK_IMAGE_TYPE_2D);
}
-VkDeviceSize Image::getMemoryOffset(const VkImageAspectFlags& flags) const
+VkDeviceSize Image::getMemoryOffset(VkImageAspectFlagBits aspect) const
{
switch(format)
{
case VK_FORMAT_D16_UNORM_S8_UINT:
case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
- if(flags == VK_IMAGE_ASPECT_STENCIL_BIT)
+ if(aspect == VK_IMAGE_ASPECT_STENCIL_BIT)
{
// Offset by depth buffer to get to stencil buffer
return memoryOffset + getStorageSize(VK_IMAGE_ASPECT_DEPTH_BIT);
@@ -383,81 +418,64 @@
return memoryOffset;
}
-VkDeviceSize Image::getMemoryOffset(const VkImageAspectFlags& flags, uint32_t mipLevel) const
+VkDeviceSize Image::getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
- VkDeviceSize offset = getMemoryOffset(flags);
+ VkDeviceSize offset = getMemoryOffset(aspect);
for(uint32_t i = 0; i < mipLevel; ++i)
{
- offset += getMipLevelSize(flags, i);
+ offset += getMipLevelSize(aspect, i);
}
return offset;
}
-VkDeviceSize Image::getMemoryOffset(const VkImageAspectFlags& flags, uint32_t mipLevel, uint32_t layer) const
+VkDeviceSize Image::getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const
{
- return layer * getLayerSize(flags) + getMemoryOffset(flags, mipLevel);
+ return layer * getLayerSize(aspect) + getMemoryOffset(aspect, mipLevel);
}
-VkDeviceSize Image::getMipLevelSize(const VkImageAspectFlags& flags, uint32_t mipLevel) const
+VkDeviceSize Image::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const
{
- int slicePitchB = 0;
- if(sw::Surface::isDepth(format) && sw::Surface::isStencil(format))
- {
- switch(flags)
- {
- case VK_IMAGE_ASPECT_DEPTH_BIT:
- case VK_IMAGE_ASPECT_STENCIL_BIT:
- slicePitchB = slicePitchBytes(flags, mipLevel);
- break;
- default:
- // Allow allocating both depth and stencil contiguously
- slicePitchB = (slicePitchBytes(VK_IMAGE_ASPECT_DEPTH_BIT, mipLevel) +
- slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, mipLevel));
- break;
- }
- }
- else
- {
- slicePitchB = slicePitchBytes(flags, mipLevel);
- }
-
- return getMipLevelExtent(mipLevel).depth * slicePitchB;
+ return getMipLevelExtent(mipLevel).depth * slicePitchBytes(aspect, mipLevel);
}
-VkDeviceSize Image::getLayerSize(const VkImageAspectFlags& flags) const
+VkDeviceSize Image::getLayerSize(VkImageAspectFlagBits aspect) const
{
VkDeviceSize layerSize = 0;
for(uint32_t mipLevel = 0; mipLevel < mipLevels; ++mipLevel)
{
- layerSize += getMipLevelSize(flags, mipLevel);
+ layerSize += getMipLevelSize(aspect, mipLevel);
}
return layerSize;
}
-VkDeviceSize Image::getStorageSize(const VkImageAspectFlags& flags) const
+VkDeviceSize Image::getStorageSize(VkImageAspectFlags aspectMask) const
{
- return arrayLayers * getLayerSize(flags);
+ if (aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT))
+ {
+ return arrayLayers * (getLayerSize(VK_IMAGE_ASPECT_DEPTH_BIT) + getLayerSize(VK_IMAGE_ASPECT_STENCIL_BIT));
+ }
+ return arrayLayers * getLayerSize(static_cast<VkImageAspectFlagBits>(aspectMask));
}
-sw::Surface* Image::asSurface(const VkImageAspectFlags& flags, uint32_t mipLevel, uint32_t layer) const
+sw::Surface* Image::asSurface(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const
{
VkExtent3D mipLevelExtent = getMipLevelExtent(mipLevel);
- return sw::Surface::create(mipLevelExtent.width, mipLevelExtent.height, mipLevelExtent.depth, getFormat(flags),
- deviceMemory->getOffsetPointer(getMemoryOffset(flags, mipLevel, layer)),
- rowPitchBytes(flags, mipLevel), slicePitchBytes(flags, mipLevel));
+ return sw::Surface::create(mipLevelExtent.width, mipLevelExtent.height, mipLevelExtent.depth, getFormat(aspect),
+ deviceMemory->getOffsetPointer(getMemoryOffset(aspect, mipLevel, layer)),
+ rowPitchBytes(aspect, mipLevel), slicePitchBytes(aspect, mipLevel));
}
void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter)
{
- VkImageAspectFlags srcFlags = region.srcSubresource.aspectMask;
- VkImageAspectFlags dstFlags = region.dstSubresource.aspectMask;
+ VkImageAspectFlagBits srcAspect = static_cast<VkImageAspectFlagBits>(region.srcSubresource.aspectMask);
+ VkImageAspectFlagBits dstAspect = static_cast<VkImageAspectFlagBits>(region.dstSubresource.aspectMask);
if((region.srcSubresource.baseArrayLayer != 0) ||
(region.dstSubresource.baseArrayLayer != 0) ||
(region.srcSubresource.layerCount != 1) ||
(region.dstSubresource.layerCount != 1) ||
- (srcFlags != dstFlags))
+ (srcAspect != dstAspect))
{
UNIMPLEMENTED();
}
@@ -465,8 +483,8 @@
int32_t numSlices = (region.srcOffsets[1].z - region.srcOffsets[0].z);
ASSERT(numSlices == (region.dstOffsets[1].z - region.dstOffsets[0].z));
- sw::Surface* srcSurface = asSurface(srcFlags, region.srcSubresource.mipLevel, 0);
- sw::Surface* dstSurface = Cast(dstImage)->asSurface(dstFlags, region.dstSubresource.mipLevel, 0);
+ sw::Surface* srcSurface = asSurface(srcAspect, region.srcSubresource.mipLevel, 0);
+ sw::Surface* dstSurface = Cast(dstImage)->asSurface(dstAspect, region.dstSubresource.mipLevel, 0);
sw::SliceRectF sRect(static_cast<float>(region.srcOffsets[0].x), static_cast<float>(region.srcOffsets[0].y),
static_cast<float>(region.srcOffsets[1].x), static_cast<float>(region.srcOffsets[1].y),
@@ -478,7 +496,7 @@
for(int i = 0; i < numSlices; i++)
{
blitter->blit(srcSurface, sRect, dstSurface, dRect,
- {filter != VK_FILTER_NEAREST, srcFlags == VK_IMAGE_ASPECT_STENCIL_BIT, false});
+ {filter != VK_FILTER_NEAREST, srcAspect == VK_IMAGE_ASPECT_STENCIL_BIT, false});
sRect.slice++;
dRect.slice++;
}
@@ -515,7 +533,7 @@
mipLevels : (subresourceRange.baseMipLevel + subresourceRange.levelCount)) - 1;
}
-void Image::clear(void* pixelData, VkFormat format, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlags aspectMask)
+void Image::clear(void* pixelData, VkFormat format, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlagBits aspect)
{
uint32_t firstLayer = subresourceRange.baseArrayLayer;
uint32_t lastLayer = getLastLayerIndex(subresourceRange);
@@ -528,7 +546,7 @@
for(uint32_t s = 0; s < mipLevelExtent.depth; ++s)
{
const sw::SliceRect dRect(0, 0, mipLevelExtent.width, mipLevelExtent.height, s);
- sw::Surface* surface = asSurface(aspectMask, mipLevel, layer);
+ sw::Surface* surface = asSurface(aspect, mipLevel, layer);
blitter->clear(pixelData, format, surface, dRect, 0xF);
delete surface;
}
@@ -536,7 +554,7 @@
}
}
-void Image::clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlags aspectMask)
+void Image::clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlagBits aspect)
{
if((subresourceRange.baseMipLevel != 0) ||
(subresourceRange.levelCount != 1))
@@ -555,7 +573,7 @@
for(uint32_t s = 0; s < extent.depth; ++s)
{
dRect.slice = s;
- sw::Surface* surface = asSurface(aspectMask, 0, layer);
+ sw::Surface* surface = asSurface(aspect, 0, layer);
blitter->clear(pixelData, format, surface, dRect, 0xF);
delete surface;
}
@@ -620,4 +638,4 @@
}
}
-} // namespace vk
\ No newline at end of file
+} // namespace vk
diff --git a/src/Vulkan/VkImage.hpp b/src/Vulkan/VkImage.hpp
index 594091a..d3a77cd 100644
--- a/src/Vulkan/VkImage.hpp
+++ b/src/Vulkan/VkImage.hpp
@@ -53,29 +53,29 @@
VkFormat getFormat() const { return format; }
uint32_t getArrayLayers() const { return arrayLayers; }
VkSampleCountFlagBits getSampleCountFlagBits() const { return samples; }
- int rowPitchBytes(const VkImageAspectFlags& flags, uint32_t mipLevel) const;
- int slicePitchBytes(const VkImageAspectFlags& flags, uint32_t mipLevel) const;
+ int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
+ int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
void* getTexelPointer(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const;
bool isCube() const;
private:
- sw::Surface* asSurface(const VkImageAspectFlags& flags, uint32_t mipLevel, uint32_t layer) const;
+ sw::Surface* asSurface(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const;
void copy(VkBuffer buffer, const VkBufferImageCopy& region, bool bufferIsSource);
- VkDeviceSize getStorageSize(const VkImageAspectFlags& flags) const;
- VkDeviceSize getMipLevelSize(const VkImageAspectFlags& flags, uint32_t mipLevel) const;
- VkDeviceSize getLayerSize(const VkImageAspectFlags& flags) const;
- VkDeviceSize getMemoryOffset(const VkImageAspectFlags& flags, uint32_t mipLevel) const;
- VkDeviceSize getMemoryOffset(const VkImageAspectFlags& flags, uint32_t mipLevel, uint32_t layer) const;
+ VkDeviceSize getStorageSize(VkImageAspectFlags flags) const;
+ VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
+ VkDeviceSize getLayerSize(VkImageAspectFlagBits aspect) const;
+ VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
+ VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const;
VkDeviceSize texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const;
- VkDeviceSize getMemoryOffset(const VkImageAspectFlags& flags) const;
- int bytesPerTexel(const VkImageAspectFlags& flags) const;
+ VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect) const;
+ int bytesPerTexel(VkImageAspectFlagBits flags) const;
VkExtent3D getMipLevelExtent(uint32_t mipLevel) const;
- VkFormat getFormat(const VkImageAspectFlags& flags) const;
+ VkFormat getFormat(VkImageAspectFlagBits flags) const;
uint32_t getLastLayerIndex(const VkImageSubresourceRange& subresourceRange) const;
uint32_t getLastMipLevel(const VkImageSubresourceRange& subresourceRange) const;
VkFormat getClearFormat() const;
- void clear(void* pixelData, VkFormat format, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlags aspectMask);
- void clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlags aspectMask);
+ void clear(void* pixelData, VkFormat format, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlagBits aspect);
+ void clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlagBits aspect);
DeviceMemory* deviceMemory = nullptr;
VkDeviceSize memoryOffset = 0;
diff --git a/src/Vulkan/VkImageView.cpp b/src/Vulkan/VkImageView.cpp
index 367c602..34e4f93 100644
--- a/src/Vulkan/VkImageView.cpp
+++ b/src/Vulkan/VkImageView.cpp
@@ -119,17 +119,11 @@
image->clear(clearValue, renderArea.rect, sr);
}
-void *ImageView::getPointer() const
-{
- VkOffset3D noOffset = { 0, 0, 0 };
- return getOffsetPointer(noOffset);
-}
-
-void *ImageView::getOffsetPointer(const VkOffset3D& offset) const
+void *ImageView::getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect) const
{
VkImageSubresourceLayers imageSubresourceLayers =
{
- subresourceRange.aspectMask,
+ aspect,
subresourceRange.baseMipLevel,
subresourceRange.baseArrayLayer,
subresourceRange.layerCount
@@ -137,4 +131,4 @@
return image->getTexelPointer(offset, imageSubresourceLayers);
}
-}
\ No newline at end of file
+}
diff --git a/src/Vulkan/VkImageView.hpp b/src/Vulkan/VkImageView.hpp
index 83fb289..89cc7a1 100644
--- a/src/Vulkan/VkImageView.hpp
+++ b/src/Vulkan/VkImageView.hpp
@@ -31,16 +31,17 @@
static size_t ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo);
- void clear(const VkClearValue& clearValues, const VkImageAspectFlags aspectMask, const VkRect2D& renderArea);
- void clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkClearRect& renderArea);
+ void clear(const VkClearValue& clearValues, VkImageAspectFlags aspectMask, const VkRect2D& renderArea);
+ void clear(const VkClearValue& clearValue, VkImageAspectFlags aspectMask, const VkClearRect& renderArea);
VkFormat getFormat() const { return format; }
- int rowPitchBytes() const { return image->rowPitchBytes(subresourceRange.aspectMask, subresourceRange.baseMipLevel); }
- int slicePitchBytes() const { return image->slicePitchBytes(subresourceRange.aspectMask, subresourceRange.baseMipLevel); }
int getSampleCount() const { return image->getSampleCountFlagBits(); }
+ int rowPitchBytes(VkImageAspectFlagBits aspect) const { return image->rowPitchBytes(aspect, subresourceRange.baseMipLevel); }
+ int slicePitchBytes(VkImageAspectFlagBits aspect) const { return image->slicePitchBytes(aspect, subresourceRange.baseMipLevel); }
- void *getPointer() const;
- void *getOffsetPointer(const VkOffset3D& offset) const;
+ void *getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect) const;
+ bool hasDepthAspect() const { return (subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; }
+ bool hasStencilAspect() const { return (subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; }
private:
bool imageTypesMatch(VkImageType imageType) const;
@@ -59,4 +60,4 @@
} // namespace vk
-#endif // VK_IMAGE_VIEW_HPP_
\ No newline at end of file
+#endif // VK_IMAGE_VIEW_HPP_