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
rasterizerDiscard = false;
depthCompareMode = VK_COMPARE_OP_LESS;
depthBufferEnable = true;
depthWriteEnable = true;
depthBufferEnable = false;
depthWriteEnable = false;
alphaBlendEnable = false;
sourceBlendFactorState = VK_BLEND_FACTOR_ONE;
......
......@@ -419,9 +419,9 @@ namespace sw
if(draw->renderTarget[index])
{
VkOffset3D offset = { 0, 0, static_cast<int32_t>(context->renderTargetLayer[index]) };
data->colorBuffer[index] = (unsigned int*)context->renderTarget[index]->getOffsetPointer(offset);
data->colorPitchB[index] = context->renderTarget[index]->rowPitchBytes();
data->colorSliceB[index] = context->renderTarget[index]->slicePitchBytes();
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->colorSliceB[index] = context->renderTarget[index]->slicePitchBytes(VK_IMAGE_ASPECT_COLOR_BIT);
}
}
......@@ -431,17 +431,17 @@ namespace sw
if(draw->depthBuffer)
{
VkOffset3D offset = { 0, 0, static_cast<int32_t>(context->depthBufferLayer) };
data->depthBuffer = (float*)context->depthBuffer->getOffsetPointer(offset);
data->depthPitchB = context->depthBuffer->rowPitchBytes();
data->depthSliceB = context->depthBuffer->slicePitchBytes();
data->depthBuffer = (float*)context->depthBuffer->getOffsetPointer(offset, VK_IMAGE_ASPECT_DEPTH_BIT);
data->depthPitchB = context->depthBuffer->rowPitchBytes(VK_IMAGE_ASPECT_DEPTH_BIT);
data->depthSliceB = context->depthBuffer->slicePitchBytes(VK_IMAGE_ASPECT_DEPTH_BIT);
}
if(draw->stencilBuffer)
{
VkOffset3D offset = { 0, 0, static_cast<int32_t>(context->stencilBufferLayer) };
data->stencilBuffer = (unsigned char*)context->stencilBuffer->getOffsetPointer(offset);
data->stencilPitchB = context->stencilBuffer->rowPitchBytes();
data->stencilSliceB = context->stencilBuffer->slicePitchBytes();
data->stencilBuffer = (unsigned char*)context->stencilBuffer->getOffsetPointer(offset, VK_IMAGE_ASPECT_STENCIL_BIT);
data->stencilPitchB = context->stencilBuffer->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT);
data->stencilSliceB = context->stencilBuffer->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT);
}
}
......
......@@ -159,6 +159,38 @@ struct IndexBufferBind : public CommandBuffer::Command
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 @@ struct Draw : public CommandBuffer::Command
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 @@ struct DrawIndexed : public CommandBuffer::Command
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);
......
......@@ -135,6 +135,8 @@ public:
VertexInputBinding vertexInputBindings[MAX_VERTEX_INPUT_BINDINGS] = {};
VertexInputBinding indexBufferBinding;
VkIndexType indexType;
void bindAttachments();
};
void submit(CommandBuffer::ExecutionState& executionState);
......
......@@ -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 @@ const VkMemoryRequirements Image::getMemoryRequirements() const
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::bind(VkDeviceMemory pDeviceMemory, VkDeviceSize pMemoryOffset)
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 @@ void Image::copyTo(VkImage dstImage, const VkImageCopy& pRegion)
// 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 @@ void Image::copyTo(VkImage dstImage, const VkImageCopy& pRegion)
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 @@ void Image::copy(VkBuffer buffer, const VkBufferImageCopy& region, bool bufferIs
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 @@ void Image::copy(VkBuffer buffer, const VkBufferImageCopy& region, bool bufferIs
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::copyFrom(VkBuffer srcBuffer, const VkBufferImageCopy& region)
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 @@ VkExtent3D Image::getMipLevelExtent(uint32_t mipLevel) const
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 @@ bool Image::isCube() const
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 @@ VkDeviceSize Image::getMemoryOffset(const VkImageAspectFlags& flags) const
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 @@ void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter)
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 @@ void Image::blit(VkImage dstImage, const VkImageBlit& region, VkFilter filter)
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 @@ uint32_t Image::getLastMipLevel(const VkImageSubresourceRange& subresourceRange)
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 @@ void Image::clear(void* pixelData, VkFormat format, const VkImageSubresourceRang
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 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) ||
(subresourceRange.levelCount != 1))
......@@ -555,7 +573,7 @@ void Image::clear(void* pixelData, VkFormat format, const VkRect2D& renderArea,
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 @@ void Image::clear(const VkClearValue& clearValue, const VkRect2D& renderArea, co
}
}
} // namespace vk
\ No newline at end of file
} // namespace vk
......@@ -53,29 +53,29 @@ public:
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;
......
......@@ -119,17 +119,11 @@ void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags a
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 @@ void *ImageView::getOffsetPointer(const VkOffset3D& offset) const
return image->getTexelPointer(offset, imageSubresourceLayers);
}
}
\ No newline at end of file
}
......@@ -31,16 +31,17 @@ public:
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 @@ static inline ImageView* Cast(VkImageView object)
} // namespace vk
#endif // VK_IMAGE_VIEW_HPP_
\ No newline at end of file
#endif // VK_IMAGE_VIEW_HPP_
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