Commit 2995dc2a by Chris Forbes

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/+/26011Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Presubmit-Ready: Chris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent b69078e2
...@@ -193,8 +193,8 @@ namespace sw ...@@ -193,8 +193,8 @@ namespace sw
rasterizerDiscard = false; rasterizerDiscard = false;
depthCompareMode = VK_COMPARE_OP_LESS; depthCompareMode = VK_COMPARE_OP_LESS;
depthBufferEnable = true; depthBufferEnable = false;
depthWriteEnable = true; depthWriteEnable = false;
alphaBlendEnable = false; alphaBlendEnable = false;
sourceBlendFactorState = VK_BLEND_FACTOR_ONE; sourceBlendFactorState = VK_BLEND_FACTOR_ONE;
......
...@@ -419,9 +419,9 @@ namespace sw ...@@ -419,9 +419,9 @@ namespace sw
if(draw->renderTarget[index]) if(draw->renderTarget[index])
{ {
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); data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->getOffsetPointer(offset, VK_IMAGE_ASPECT_COLOR_BIT);
data->colorPitchB[index] = context->renderTarget[index]->rowPitchBytes(); data->colorPitchB[index] = context->renderTarget[index]->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT);
data->colorSliceB[index] = context->renderTarget[index]->slicePitchBytes(); data->colorSliceB[index] = context->renderTarget[index]->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT);
} }
} }
...@@ -431,17 +431,17 @@ namespace sw ...@@ -431,17 +431,17 @@ namespace sw
if(draw->depthBuffer) if(draw->depthBuffer)
{ {
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); data->depthBuffer = (float*)context->depthBuffer->getOffsetPointer(offset, VK_IMAGE_ASPECT_DEPTH_BIT);
data->depthPitchB = context->depthBuffer->rowPitchBytes(); data->depthPitchB = context->depthBuffer->rowPitchBytes(VK_IMAGE_ASPECT_DEPTH_BIT);
data->depthSliceB = context->depthBuffer->slicePitchBytes(); data->depthSliceB = context->depthBuffer->slicePitchBytes(VK_IMAGE_ASPECT_DEPTH_BIT);
} }
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); data->stencilBuffer = (unsigned char*)context->stencilBuffer->getOffsetPointer(offset, VK_IMAGE_ASPECT_STENCIL_BIT);
data->stencilPitchB = context->stencilBuffer->rowPitchBytes(); data->stencilPitchB = context->stencilBuffer->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT);
data->stencilSliceB = context->stencilBuffer->slicePitchBytes(); data->stencilSliceB = context->stencilBuffer->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT);
} }
} }
......
...@@ -159,6 +159,38 @@ struct IndexBufferBind : public CommandBuffer::Command ...@@ -159,6 +159,38 @@ struct IndexBufferBind : public CommandBuffer::Command
const VkIndexType indexType; 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 struct Draw : public CommandBuffer::Command
{ {
Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) Draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
...@@ -189,15 +221,7 @@ struct Draw : public CommandBuffer::Command ...@@ -189,15 +221,7 @@ struct Draw : public CommandBuffer::Command
executionState.renderer->setViewport(pipeline->getViewport()); executionState.renderer->setViewport(pipeline->getViewport());
executionState.renderer->setBlendConstant(pipeline->getBlendConstants()); executionState.renderer->setBlendConstant(pipeline->getBlendConstants());
for (auto i = 0u; i < executionState.renderPass->getCurrentSubpass().colorAttachmentCount; i++) executionState.bindAttachments();
{
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);
}
}
const uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount); const uint32_t primitiveCount = pipeline->computePrimitiveCount(vertexCount);
const uint32_t lastInstance = firstInstance + instanceCount - 1; const uint32_t lastInstance = firstInstance + instanceCount - 1;
...@@ -247,15 +271,7 @@ struct DrawIndexed : public CommandBuffer::Command ...@@ -247,15 +271,7 @@ struct DrawIndexed : public CommandBuffer::Command
executionState.renderer->setViewport(pipeline->getViewport()); executionState.renderer->setViewport(pipeline->getViewport());
executionState.renderer->setBlendConstant(pipeline->getBlendConstants()); executionState.renderer->setBlendConstant(pipeline->getBlendConstants());
for (auto i = 0u; i < executionState.renderPass->getCurrentSubpass().colorAttachmentCount; i++) executionState.bindAttachments();
{
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);
}
}
auto drawType = executionState.indexType == VK_INDEX_TYPE_UINT16 auto drawType = executionState.indexType == VK_INDEX_TYPE_UINT16
? (context.drawType | sw::DRAW_INDEXED16) : (context.drawType | sw::DRAW_INDEXED32); ? (context.drawType | sw::DRAW_INDEXED16) : (context.drawType | sw::DRAW_INDEXED32);
......
...@@ -135,6 +135,8 @@ public: ...@@ -135,6 +135,8 @@ public:
VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {}; VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
VertexInputBinding indexBufferBinding; VertexInputBinding indexBufferBinding;
VkIndexType indexType; VkIndexType indexType;
void bindAttachments();
}; };
void submit(CommandBuffer::ExecutionState& executionState); void submit(CommandBuffer::ExecutionState& executionState);
......
...@@ -19,6 +19,25 @@ ...@@ -19,6 +19,25 @@
#include "Device/Surface.hpp" #include "Device/Surface.hpp"
#include <cstring> #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 namespace vk
{ {
...@@ -55,7 +74,7 @@ const VkMemoryRequirements Image::getMemoryRequirements() const ...@@ -55,7 +74,7 @@ const VkMemoryRequirements Image::getMemoryRequirements() const
VkMemoryRequirements memoryRequirements; VkMemoryRequirements memoryRequirements;
memoryRequirements.alignment = vk::REQUIRED_MEMORY_ALIGNMENT; memoryRequirements.alignment = vk::REQUIRED_MEMORY_ALIGNMENT;
memoryRequirements.memoryTypeBits = vk::MEMORY_TYPE_GENERIC_BIT; memoryRequirements.memoryTypeBits = vk::MEMORY_TYPE_GENERIC_BIT;
memoryRequirements.size = getStorageSize(flags); memoryRequirements.size = getStorageSize(GetAspects(format));
return memoryRequirements; return memoryRequirements;
} }
...@@ -67,11 +86,19 @@ void Image::bind(VkDeviceMemory pDeviceMemory, VkDeviceSize pMemoryOffset) ...@@ -67,11 +86,19 @@ void Image::bind(VkDeviceMemory pDeviceMemory, VkDeviceSize pMemoryOffset)
void Image::getSubresourceLayout(const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout) const void Image::getSubresourceLayout(const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout) const
{ {
pLayout->offset = getMemoryOffset(flags, pSubresource->mipLevel, pSubresource->arrayLayer); // By spec, aspectMask has a single bit set.
pLayout->size = getMipLevelSize(flags, pSubresource->mipLevel); if (!((pSubresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
pLayout->rowPitch = rowPitchBytes(flags, pSubresource->mipLevel); (pSubresource->aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
pLayout->depthPitch = slicePitchBytes(flags, pSubresource->mipLevel); (pSubresource->aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)))
pLayout->arrayPitch = getLayerSize(flags); {
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) void Image::copyTo(VkImage dstImage, const VkImageCopy& pRegion)
...@@ -79,8 +106,6 @@ void Image::copyTo(VkImage dstImage, const VkImageCopy& pRegion) ...@@ -79,8 +106,6 @@ void Image::copyTo(VkImage dstImage, const VkImageCopy& pRegion)
// Image copy does not perform any conversion, it simply copies memory from // 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. // an image to another image that has the same number of bytes per pixel.
Image* dst = Cast(dstImage); 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) || if(!((pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) ||
(pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) || (pRegion.srcSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) ||
...@@ -100,13 +125,19 @@ void Image::copyTo(VkImage dstImage, const VkImageCopy& pRegion) ...@@ -100,13 +125,19 @@ void Image::copyTo(VkImage dstImage, const VkImageCopy& pRegion)
UNIMPLEMENTED(); 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)); const char* srcMem = static_cast<const char*>(getTexelPointer(pRegion.srcOffset, pRegion.srcSubresource));
char* dstMem = static_cast<char*>(dst->getTexelPointer(pRegion.dstOffset, pRegion.dstSubresource)); char* dstMem = static_cast<char*>(dst->getTexelPointer(pRegion.dstOffset, pRegion.dstSubresource));
int srcRowPitchBytes = rowPitchBytes(pRegion.srcSubresource.aspectMask, pRegion.srcSubresource.mipLevel); int srcRowPitchBytes = rowPitchBytes(srcAspect, pRegion.srcSubresource.mipLevel);
int srcSlicePitchBytes = slicePitchBytes(pRegion.srcSubresource.aspectMask, pRegion.srcSubresource.mipLevel); int srcSlicePitchBytes = slicePitchBytes(srcAspect, pRegion.srcSubresource.mipLevel);
int dstRowPitchBytes = dst->rowPitchBytes(pRegion.dstSubresource.aspectMask, pRegion.dstSubresource.mipLevel); int dstRowPitchBytes = dst->rowPitchBytes(dstAspect, pRegion.dstSubresource.mipLevel);
int dstSlicePitchBytes = dst->slicePitchBytes(pRegion.dstSubresource.aspectMask, pRegion.dstSubresource.mipLevel); int dstSlicePitchBytes = dst->slicePitchBytes(dstAspect, pRegion.dstSubresource.mipLevel);
VkExtent3D srcExtent = getMipLevelExtent(pRegion.srcSubresource.mipLevel); VkExtent3D srcExtent = getMipLevelExtent(pRegion.srcSubresource.mipLevel);
VkExtent3D dstExtent = dst->getMipLevelExtent(pRegion.dstSubresource.mipLevel); VkExtent3D dstExtent = dst->getMipLevelExtent(pRegion.dstSubresource.mipLevel);
...@@ -167,10 +198,12 @@ void Image::copy(VkBuffer buffer, const VkBufferImageCopy& region, bool bufferIs ...@@ -167,10 +198,12 @@ void Image::copy(VkBuffer buffer, const VkBufferImageCopy& region, bool bufferIs
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(region.imageSubresource.aspectMask);
VkExtent3D mipLevelExtent = getMipLevelExtent(region.imageSubresource.mipLevel); VkExtent3D mipLevelExtent = getMipLevelExtent(region.imageSubresource.mipLevel);
int imageBytesPerTexel = bytesPerTexel(region.imageSubresource.aspectMask); int imageBytesPerTexel = bytesPerTexel(aspect);
int imageRowPitchBytes = rowPitchBytes(region.imageSubresource.aspectMask, region.imageSubresource.mipLevel); int imageRowPitchBytes = rowPitchBytes(aspect, region.imageSubresource.mipLevel);
int imageSlicePitchBytes = slicePitchBytes(region.imageSubresource.aspectMask, region.imageSubresource.mipLevel); int imageSlicePitchBytes = slicePitchBytes(aspect, region.imageSubresource.mipLevel);
int bufferRowPitchBytes = ((region.bufferRowLength == 0) ? region.imageExtent.width : region.bufferRowLength) * int bufferRowPitchBytes = ((region.bufferRowLength == 0) ? region.imageExtent.width : region.bufferRowLength) *
imageBytesPerTexel; imageBytesPerTexel;
int bufferSlicePitchBytes = (((region.bufferImageHeight == 0) || (region.bufferRowLength == 0))) ? int bufferSlicePitchBytes = (((region.bufferImageHeight == 0) || (region.bufferRowLength == 0))) ?
...@@ -189,10 +222,10 @@ void Image::copy(VkBuffer buffer, const VkBufferImageCopy& region, bool bufferIs ...@@ -189,10 +222,10 @@ void Image::copy(VkBuffer buffer, const VkBufferImageCopy& region, bool bufferIs
bool isEntirePlane = isEntireLine && (region.imageExtent.height == mipLevelExtent.height) && bool isEntirePlane = isEntireLine && (region.imageExtent.height == mipLevelExtent.height) &&
(imageSlicePitchBytes == bufferSlicePitchBytes); (imageSlicePitchBytes == bufferSlicePitchBytes);
VkDeviceSize layerSize = getLayerSize(flags); VkDeviceSize layerSize = getLayerSize(aspect);
char* bufferMemory = static_cast<char*>(Cast(buffer)->getOffsetPointer(region.bufferOffset)); char* bufferMemory = static_cast<char*>(Cast(buffer)->getOffsetPointer(region.bufferOffset));
char* imageMemory = static_cast<char*>(deviceMemory->getOffsetPointer( char* imageMemory = static_cast<char*>(deviceMemory->getOffsetPointer(
getMemoryOffset(region.imageSubresource.aspectMask, region.imageSubresource.mipLevel, getMemoryOffset(aspect, region.imageSubresource.mipLevel,
region.imageSubresource.baseArrayLayer) + region.imageSubresource.baseArrayLayer) +
texelOffsetBytesInStorage(region.imageOffset, region.imageSubresource))); texelOffsetBytesInStorage(region.imageOffset, region.imageSubresource)));
char* srcMemory = bufferIsSource ? bufferMemory : imageMemory; char* srcMemory = bufferIsSource ? bufferMemory : imageMemory;
...@@ -265,15 +298,17 @@ void Image::copyFrom(VkBuffer srcBuffer, const VkBufferImageCopy& region) ...@@ -265,15 +298,17 @@ void Image::copyFrom(VkBuffer srcBuffer, const VkBufferImageCopy& region)
void* Image::getTexelPointer(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const void* Image::getTexelPointer(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const
{ {
VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(subresource.aspectMask);
return deviceMemory->getOffsetPointer(texelOffsetBytesInStorage(offset, subresource) + 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 VkDeviceSize Image::texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const
{ {
return offset.z * slicePitchBytes(flags, subresource.mipLevel) + VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(subresource.aspectMask);
offset.y * rowPitchBytes(flags, subresource.mipLevel) + return offset.z * slicePitchBytes(aspect, subresource.mipLevel) +
offset.x * bytesPerTexel(flags); offset.y * rowPitchBytes(aspect, subresource.mipLevel) +
offset.x * bytesPerTexel(aspect);
} }
VkExtent3D Image::getMipLevelExtent(uint32_t mipLevel) const VkExtent3D Image::getMipLevelExtent(uint32_t mipLevel) const
...@@ -298,34 +333,34 @@ VkExtent3D Image::getMipLevelExtent(uint32_t mipLevel) const ...@@ -298,34 +333,34 @@ VkExtent3D Image::getMipLevelExtent(uint32_t mipLevel) const
return mipLevelExtent; 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 // 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)); (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 // 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)); (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
VkExtent3D mipLevelExtent = getMipLevelExtent(mipLevel); 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 // 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)); (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: case VK_IMAGE_ASPECT_DEPTH_BIT:
switch(format) switch(format)
...@@ -363,14 +398,14 @@ bool Image::isCube() const ...@@ -363,14 +398,14 @@ bool Image::isCube() const
return (flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && (imageType == VK_IMAGE_TYPE_2D); 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) switch(format)
{ {
case VK_FORMAT_D16_UNORM_S8_UINT: case VK_FORMAT_D16_UNORM_S8_UINT:
case VK_FORMAT_D24_UNORM_S8_UINT: case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_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 // Offset by depth buffer to get to stencil buffer
return memoryOffset + getStorageSize(VK_IMAGE_ASPECT_DEPTH_BIT); return memoryOffset + getStorageSize(VK_IMAGE_ASPECT_DEPTH_BIT);
...@@ -383,81 +418,64 @@ VkDeviceSize Image::getMemoryOffset(const VkImageAspectFlags& flags) const ...@@ -383,81 +418,64 @@ VkDeviceSize Image::getMemoryOffset(const VkImageAspectFlags& flags) const
return memoryOffset; 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) for(uint32_t i = 0; i < mipLevel; ++i)
{ {
offset += getMipLevelSize(flags, i); offset += getMipLevelSize(aspect, i);
} }
return offset; 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; return getMipLevelExtent(mipLevel).depth * slicePitchBytes(aspect, mipLevel);
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;
} }
VkDeviceSize Image::getLayerSize(const VkImageAspectFlags& flags) const VkDeviceSize Image::getLayerSize(VkImageAspectFlagBits aspect) const
{ {
VkDeviceSize layerSize = 0; VkDeviceSize layerSize = 0;
for(uint32_t mipLevel = 0; mipLevel < mipLevels; ++mipLevel) for(uint32_t mipLevel = 0; mipLevel < mipLevels; ++mipLevel)
{ {
layerSize += getMipLevelSize(flags, mipLevel); layerSize += getMipLevelSize(aspect, mipLevel);
} }
return layerSize; 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); VkExtent3D mipLevelExtent = getMipLevelExtent(mipLevel);
return sw::Surface::create(mipLevelExtent.width, mipLevelExtent.height, mipLevelExtent.depth, getFormat(flags), return sw::Surface::create(mipLevelExtent.width, mipLevelExtent.height, mipLevelExtent.depth, getFormat(aspect),
deviceMemory->getOffsetPointer(getMemoryOffset(flags, mipLevel, layer)), deviceMemory->getOffsetPointer(getMemoryOffset(aspect, mipLevel, layer)),
rowPitchBytes(flags, mipLevel), slicePitchBytes(flags, mipLevel)); rowPitchBytes(aspect, mipLevel), slicePitchBytes(aspect, mipLevel));
} }
void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter) void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter)
{ {
VkImageAspectFlags srcFlags = region.srcSubresource.aspectMask; VkImageAspectFlagBits srcAspect = static_cast<VkImageAspectFlagBits>(region.srcSubresource.aspectMask);
VkImageAspectFlags dstFlags = region.dstSubresource.aspectMask; VkImageAspectFlagBits dstAspect = static_cast<VkImageAspectFlagBits>(region.dstSubresource.aspectMask);
if((region.srcSubresource.baseArrayLayer != 0) || if((region.srcSubresource.baseArrayLayer != 0) ||
(region.dstSubresource.baseArrayLayer != 0) || (region.dstSubresource.baseArrayLayer != 0) ||
(region.srcSubresource.layerCount != 1) || (region.srcSubresource.layerCount != 1) ||
(region.dstSubresource.layerCount != 1) || (region.dstSubresource.layerCount != 1) ||
(srcFlags != dstFlags)) (srcAspect != dstAspect))
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
...@@ -465,8 +483,8 @@ void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter) ...@@ -465,8 +483,8 @@ void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter)
int32_t numSlices = (region.srcOffsets[1].z - region.srcOffsets[0].z); int32_t numSlices = (region.srcOffsets[1].z - region.srcOffsets[0].z);
ASSERT(numSlices == (region.dstOffsets[1].z - region.dstOffsets[0].z)); ASSERT(numSlices == (region.dstOffsets[1].z - region.dstOffsets[0].z));
sw::Surface* srcSurface = asSurface(srcFlags, region.srcSubresource.mipLevel, 0); sw::Surface* srcSurface = asSurface(srcAspect, region.srcSubresource.mipLevel, 0);
sw::Surface* dstSurface = Cast(dstImage)->asSurface(dstFlags, region.dstSubresource.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), 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), static_cast<float>(region.srcOffsets[1].x), static_cast<float>(region.srcOffsets[1].y),
...@@ -478,7 +496,7 @@ void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter) ...@@ -478,7 +496,7 @@ void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter)
for(int i = 0; i < numSlices; i++) for(int i = 0; i < numSlices; i++)
{ {
blitter->blit(srcSurface, sRect, dstSurface, dRect, 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++; sRect.slice++;
dRect.slice++; dRect.slice++;
} }
...@@ -515,7 +533,7 @@ uint32_t Image::getLastMipLevel(const VkImageSubresourceRange& subresourceRange) ...@@ -515,7 +533,7 @@ uint32_t Image::getLastMipLevel(const VkImageSubresourceRange& subresourceRange)
mipLevels : (subresourceRange.baseMipLevel + subresourceRange.levelCount)) - 1; 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 firstLayer = subresourceRange.baseArrayLayer;
uint32_t lastLayer = getLastLayerIndex(subresourceRange); uint32_t lastLayer = getLastLayerIndex(subresourceRange);
...@@ -528,7 +546,7 @@ void Image::clear(void* pixelData, VkFormat format, const VkImageSubresourceRang ...@@ -528,7 +546,7 @@ void Image::clear(void* pixelData, VkFormat format, const VkImageSubresourceRang
for(uint32_t s = 0; s < mipLevelExtent.depth; ++s) for(uint32_t s = 0; s < mipLevelExtent.depth; ++s)
{ {
const sw::SliceRect dRect(0, 0, mipLevelExtent.width, mipLevelExtent.height, 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); blitter->clear(pixelData, format, surface, dRect, 0xF);
delete surface; delete surface;
} }
...@@ -536,7 +554,7 @@ void Image::clear(void* pixelData, VkFormat format, const VkImageSubresourceRang ...@@ -536,7 +554,7 @@ void Image::clear(void* pixelData, VkFormat format, const VkImageSubresourceRang
} }
} }
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) || if((subresourceRange.baseMipLevel != 0) ||
(subresourceRange.levelCount != 1)) (subresourceRange.levelCount != 1))
...@@ -555,7 +573,7 @@ void Image::clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, ...@@ -555,7 +573,7 @@ void Image::clear(void* pixelData, VkFormat format, const VkRect2D& renderArea,
for(uint32_t s = 0; s < extent.depth; ++s) for(uint32_t s = 0; s < extent.depth; ++s)
{ {
dRect.slice = 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); blitter->clear(pixelData, format, surface, dRect, 0xF);
delete surface; delete surface;
} }
...@@ -620,4 +638,4 @@ void Image::clear(const VkClearValue& clearValue, const VkRect2D& renderArea, co ...@@ -620,4 +638,4 @@ void Image::clear(const VkClearValue& clearValue, const VkRect2D& renderArea, co
} }
} }
} // namespace vk } // namespace vk
\ No newline at end of file
...@@ -53,29 +53,29 @@ public: ...@@ -53,29 +53,29 @@ public:
VkFormat getFormat() const { return format; } VkFormat getFormat() const { return format; }
uint32_t getArrayLayers() const { return arrayLayers; } uint32_t getArrayLayers() const { return arrayLayers; }
VkSampleCountFlagBits getSampleCountFlagBits() const { return samples; } VkSampleCountFlagBits getSampleCountFlagBits() const { return samples; }
int rowPitchBytes(const VkImageAspectFlags& flags, uint32_t mipLevel) const; int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
int slicePitchBytes(const VkImageAspectFlags& flags, uint32_t mipLevel) const; int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
void* getTexelPointer(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const; void* getTexelPointer(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const;
bool isCube() const; bool isCube() const;
private: 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); void copy(VkBuffer buffer, const VkBufferImageCopy& region, bool bufferIsSource);
VkDeviceSize getStorageSize(const VkImageAspectFlags& flags) const; VkDeviceSize getStorageSize(VkImageAspectFlags flags) const;
VkDeviceSize getMipLevelSize(const VkImageAspectFlags& flags, uint32_t mipLevel) const; VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
VkDeviceSize getLayerSize(const VkImageAspectFlags& flags) const; VkDeviceSize getLayerSize(VkImageAspectFlagBits aspect) const;
VkDeviceSize getMemoryOffset(const VkImageAspectFlags& flags, uint32_t mipLevel) const; VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
VkDeviceSize getMemoryOffset(const VkImageAspectFlags& flags, uint32_t mipLevel, uint32_t layer) const; VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel, uint32_t layer) const;
VkDeviceSize texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const; VkDeviceSize texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const;
VkDeviceSize getMemoryOffset(const VkImageAspectFlags& flags) const; VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect) const;
int bytesPerTexel(const VkImageAspectFlags& flags) const; int bytesPerTexel(VkImageAspectFlagBits flags) const;
VkExtent3D getMipLevelExtent(uint32_t mipLevel) 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 getLastLayerIndex(const VkImageSubresourceRange& subresourceRange) const;
uint32_t getLastMipLevel(const VkImageSubresourceRange& subresourceRange) const; uint32_t getLastMipLevel(const VkImageSubresourceRange& subresourceRange) const;
VkFormat getClearFormat() const; VkFormat getClearFormat() const;
void clear(void* pixelData, VkFormat format, 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, VkImageAspectFlags aspectMask); void clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlagBits aspect);
DeviceMemory* deviceMemory = nullptr; DeviceMemory* deviceMemory = nullptr;
VkDeviceSize memoryOffset = 0; VkDeviceSize memoryOffset = 0;
......
...@@ -119,17 +119,11 @@ void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags a ...@@ -119,17 +119,11 @@ void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags a
image->clear(clearValue, renderArea.rect, sr); image->clear(clearValue, renderArea.rect, sr);
} }
void *ImageView::getPointer() const void *ImageView::getOffsetPointer(const VkOffset3D& offset, VkImageAspectFlagBits aspect) const
{
VkOffset3D noOffset = { 0, 0, 0 };
return getOffsetPointer(noOffset);
}
void *ImageView::getOffsetPointer(const VkOffset3D& offset) const
{ {
VkImageSubresourceLayers imageSubresourceLayers = VkImageSubresourceLayers imageSubresourceLayers =
{ {
subresourceRange.aspectMask, aspect,
subresourceRange.baseMipLevel, subresourceRange.baseMipLevel,
subresourceRange.baseArrayLayer, subresourceRange.baseArrayLayer,
subresourceRange.layerCount subresourceRange.layerCount
...@@ -137,4 +131,4 @@ void *ImageView::getOffsetPointer(const VkOffset3D& offset) const ...@@ -137,4 +131,4 @@ void *ImageView::getOffsetPointer(const VkOffset3D& offset) const
return image->getTexelPointer(offset, imageSubresourceLayers); return image->getTexelPointer(offset, imageSubresourceLayers);
} }
} }
\ No newline at end of file
...@@ -31,16 +31,17 @@ public: ...@@ -31,16 +31,17 @@ public:
static size_t ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo); static size_t ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo);
void clear(const VkClearValue& clearValues, const VkImageAspectFlags aspectMask, const VkRect2D& renderArea); void clear(const VkClearValue& clearValues, VkImageAspectFlags aspectMask, const VkRect2D& renderArea);
void clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkClearRect& renderArea); void clear(const VkClearValue& clearValue, VkImageAspectFlags aspectMask, const VkClearRect& renderArea);
VkFormat getFormat() const { return format; } 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 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, VkImageAspectFlagBits aspect) const;
void *getOffsetPointer(const VkOffset3D& offset) 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: private:
bool imageTypesMatch(VkImageType imageType) const; bool imageTypesMatch(VkImageType imageType) const;
...@@ -59,4 +60,4 @@ static inline ImageView* Cast(VkImageView object) ...@@ -59,4 +60,4 @@ static inline ImageView* Cast(VkImageView object)
} // namespace vk } // namespace vk
#endif // VK_IMAGE_VIEW_HPP_ #endif // VK_IMAGE_VIEW_HPP_
\ No newline at end of file
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