Commit 3364227f by Alexis Hetu Committed by Alexis Hétu

Allow the Blitter to clear and blit vk::Image objects directly

The sw::Surface object was the intermediate representation of an image used between the vk::Image and the Blitter. This cl removes the need for an intermediate representation by having the Blitter use the vk::Image directly. There should be no regression for the clear and blit tests. Bug b/126883332 Change-Id: Icbc15470e3ad112ed78f4f62d6d82c66e3e37a20 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/25928Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Presubmit-Ready: Alexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com>
parent 654540e8
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "Reactor/Reactor.hpp" #include "Reactor/Reactor.hpp"
#include "System/Memory.hpp" #include "System/Memory.hpp"
#include "Vulkan/VkDebug.hpp" #include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkImage.hpp"
namespace sw namespace sw
{ {
...@@ -44,6 +45,203 @@ namespace sw ...@@ -44,6 +45,203 @@ namespace sw
delete color; delete color;
} }
void Blitter::clear(void *pixel, VkFormat format, vk::Image *dest, const VkImageSubresourceRange& subresourceRange, const VkRect2D* renderArea)
{
VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask);
if(dest->getFormat(aspect) == VK_FORMAT_UNDEFINED)
{
return;
}
if(fastClear(pixel, format, dest, subresourceRange, renderArea))
{
return;
}
State state(format, dest->getFormat(aspect), dest->getSampleCountFlagBits(), { 0xF });
Routine *blitRoutine = getRoutine(state);
if(!blitRoutine)
{
return;
}
void(*blitFunction)(const BlitData *data) = (void(*)(const BlitData*))blitRoutine->getEntry();
VkImageSubresourceLayers subresLayers =
{
subresourceRange.aspectMask,
subresourceRange.baseMipLevel,
subresourceRange.baseArrayLayer,
1
};
uint32_t lastMipLevel = dest->getLastMipLevel(subresourceRange);
uint32_t lastLayer = dest->getLastLayerIndex(subresourceRange);
VkRect2D area = { { 0, 0 }, { 0, 0 } };
if(renderArea)
{
ASSERT(subresourceRange.levelCount == 1);
area = *renderArea;
}
for(; subresLayers.mipLevel <= lastMipLevel; subresLayers.mipLevel++)
{
VkExtent3D extent = dest->getMipLevelExtent(subresLayers.mipLevel);
if(!renderArea)
{
area.extent.width = extent.width;
area.extent.height = extent.height;
}
BlitData data =
{
pixel, nullptr, // source, dest
sw::Surface::bytes(format), // sPitchB
dest->rowPitchBytes(aspect, subresLayers.mipLevel), // dPitchB
dest->slicePitchBytes(aspect, subresLayers.mipLevel), // dSliceB
0.5f, 0.5f, 0.0f, 0.0f, // x0, y0, w, h
area.offset.y, static_cast<int>(area.offset.y + area.extent.height), // y0d, y1d
area.offset.x, static_cast<int>(area.offset.x + area.extent.width), // x0d, x1d
0, 0, // sWidth, sHeight
};
for(subresLayers.baseArrayLayer = subresourceRange.baseArrayLayer; subresLayers.baseArrayLayer <= lastLayer; subresLayers.baseArrayLayer++)
{
for(uint32_t depth = 0; depth < extent.depth; depth++)
{
data.dest = dest->getTexelPointer({ 0, 0, static_cast<int32_t>(depth) }, subresLayers);
blitFunction(&data);
}
}
}
}
bool Blitter::fastClear(void *pixel, VkFormat format, vk::Image *dest, const VkImageSubresourceRange& subresourceRange, const VkRect2D* renderArea)
{
if(format != VK_FORMAT_R32G32B32A32_SFLOAT)
{
return false;
}
float *color = (float*)pixel;
float r = color[0];
float g = color[1];
float b = color[2];
float a = color[3];
uint32_t packed;
VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(subresourceRange.aspectMask);
switch(dest->getFormat(aspect))
{
case VK_FORMAT_R5G6B5_UNORM_PACK16:
packed = ((uint16_t)(31 * b + 0.5f) << 0) |
((uint16_t)(63 * g + 0.5f) << 5) |
((uint16_t)(31 * r + 0.5f) << 11);
break;
case VK_FORMAT_B5G6R5_UNORM_PACK16:
packed = ((uint16_t)(31 * r + 0.5f) << 0) |
((uint16_t)(63 * g + 0.5f) << 5) |
((uint16_t)(31 * b + 0.5f) << 11);
break;
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
case VK_FORMAT_R8G8B8A8_UNORM:
packed = ((uint32_t)(255 * a + 0.5f) << 24) |
((uint32_t)(255 * b + 0.5f) << 16) |
((uint32_t)(255 * g + 0.5f) << 8) |
((uint32_t)(255 * r + 0.5f) << 0);
break;
case VK_FORMAT_B8G8R8A8_UNORM:
packed = ((uint32_t)(255 * a + 0.5f) << 24) |
((uint32_t)(255 * r + 0.5f) << 16) |
((uint32_t)(255 * g + 0.5f) << 8) |
((uint32_t)(255 * b + 0.5f) << 0);
break;
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
packed = R11G11B10F(color);
break;
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
packed = RGB9E5(color);
break;
default:
return false;
}
VkImageSubresourceLayers subresLayers =
{
subresourceRange.aspectMask,
subresourceRange.baseMipLevel,
subresourceRange.baseArrayLayer,
1
};
uint32_t lastMipLevel = dest->getLastMipLevel(subresourceRange);
uint32_t lastLayer = dest->getLastLayerIndex(subresourceRange);
VkRect2D area = { { 0, 0 }, { 0, 0 } };
if(renderArea)
{
ASSERT(subresourceRange.levelCount == 1);
area = *renderArea;
}
for(; subresLayers.mipLevel <= lastMipLevel; subresLayers.mipLevel++)
{
int rowPitchBytes = dest->rowPitchBytes(aspect, subresLayers.mipLevel);
int slicePitchBytes = dest->slicePitchBytes(aspect, subresLayers.mipLevel);
VkExtent3D extent = dest->getMipLevelExtent(subresLayers.mipLevel);
if(!renderArea)
{
area.extent.width = extent.width;
area.extent.height = extent.height;
}
for(subresLayers.baseArrayLayer = subresourceRange.baseArrayLayer; subresLayers.baseArrayLayer <= lastLayer; subresLayers.baseArrayLayer++)
{
for(uint32_t depth = 0; depth < extent.depth; depth++)
{
uint8_t *slice = (uint8_t*)dest->getTexelPointer(
{ area.offset.x, area.offset.y, static_cast<int32_t>(depth) }, subresLayers);
for(int j = 0; j < dest->getSampleCountFlagBits(); j++)
{
uint8_t *d = slice;
switch(Surface::bytes(dest->getFormat(aspect)))
{
case 2:
for(uint32_t i = 0; i < area.extent.height; i++)
{
sw::clear((uint16_t*)d, packed, area.extent.width);
d += rowPitchBytes;
}
break;
case 4:
for(uint32_t i = 0; i < area.extent.height; i++)
{
sw::clear((uint32_t*)d, packed, area.extent.width);
d += rowPitchBytes;
}
break;
default:
assert(false);
}
slice += slicePitchBytes;
}
}
}
}
return true;
}
bool Blitter::fastClear(void *pixel, VkFormat format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask) bool Blitter::fastClear(void *pixel, VkFormat format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask)
{ {
if(format != VK_FORMAT_R32G32B32A32_SFLOAT) if(format != VK_FORMAT_R32G32B32A32_SFLOAT)
...@@ -1628,6 +1826,30 @@ namespace sw ...@@ -1628,6 +1826,30 @@ namespace sw
return function("BlitRoutine"); return function("BlitRoutine");
} }
Routine *Blitter::getRoutine(const State &state)
{
criticalSection.lock();
Routine *blitRoutine = blitCache->query(state);
if(!blitRoutine)
{
blitRoutine = generate(state);
if(!blitRoutine)
{
criticalSection.unlock();
UNIMPLEMENTED();
return nullptr;
}
blitCache->add(state, blitRoutine);
}
criticalSection.unlock();
return blitRoutine;
}
bool Blitter::blitReactor(Surface *source, const SliceRectF &sourceRect, Surface *dest, const SliceRect &destRect, const Blitter::Options &options) bool Blitter::blitReactor(Surface *source, const SliceRectF &sourceRect, Surface *dest, const SliceRect &destRect, const Blitter::Options &options)
{ {
ASSERT(!options.clearOperation || ((source->getWidth() == 1) && (source->getHeight() == 1) && (source->getDepth() == 1))); ASSERT(!options.clearOperation || ((source->getWidth() == 1) && (source->getHeight() == 1) && (source->getDepth() == 1)));
...@@ -1659,24 +1881,12 @@ namespace sw ...@@ -1659,24 +1881,12 @@ namespace sw
state.destFormat = isStencil ? dest->getStencilFormat() : dest->getFormat(useDestInternal); state.destFormat = isStencil ? dest->getStencilFormat() : dest->getFormat(useDestInternal);
state.destSamples = dest->getSamples(); state.destSamples = dest->getSamples();
criticalSection.lock(); Routine *blitRoutine = getRoutine(state);
Routine *blitRoutine = blitCache->query(state);
if(!blitRoutine) if(!blitRoutine)
{ {
blitRoutine = generate(state); return false;
if(!blitRoutine)
{
criticalSection.unlock();
return false;
}
blitCache->add(state, blitRoutine);
} }
criticalSection.unlock();
void (*blitFunction)(const BlitData *data) = (void(*)(const BlitData*))blitRoutine->getEntry(); void (*blitFunction)(const BlitData *data) = (void(*)(const BlitData*))blitRoutine->getEntry();
BlitData data; BlitData data;
...@@ -1720,4 +1930,90 @@ namespace sw ...@@ -1720,4 +1930,90 @@ namespace sw
return true; return true;
} }
void Blitter::blit(vk::Image *src, vk::Image *dst, VkImageBlit region, VkFilter filter)
{
if(dst->getFormat() == VK_FORMAT_UNDEFINED)
{
return;
}
if((region.srcSubresource.baseArrayLayer != 0) ||
(region.dstSubresource.baseArrayLayer != 0) ||
(region.srcSubresource.layerCount != 1) ||
(region.dstSubresource.layerCount != 1) ||
(region.srcSubresource.aspectMask != region.dstSubresource.aspectMask))
{
UNIMPLEMENTED();
}
if(region.dstOffsets[0].x > region.dstOffsets[1].x)
{
swap(region.srcOffsets[0].x, region.srcOffsets[1].x);
swap(region.dstOffsets[0].x, region.dstOffsets[1].x);
}
if(region.dstOffsets[0].y > region.dstOffsets[1].y)
{
swap(region.srcOffsets[0].y, region.srcOffsets[1].y);
swap(region.dstOffsets[0].y, region.dstOffsets[1].y);
}
VkExtent3D srcExtent = src->getMipLevelExtent(region.srcSubresource.mipLevel);
VkExtent3D dstExtent = dst->getMipLevelExtent(region.dstSubresource.mipLevel);
int32_t numSlices = (region.srcOffsets[1].z - region.srcOffsets[0].z);
ASSERT(numSlices == (region.dstOffsets[1].z - region.dstOffsets[0].z));
VkImageAspectFlagBits srcAspect = static_cast<VkImageAspectFlagBits>(region.srcSubresource.aspectMask);
VkImageAspectFlagBits dstAspect = static_cast<VkImageAspectFlagBits>(region.dstSubresource.aspectMask);
State state(src->getFormat(srcAspect), dst->getFormat(dstAspect), dst->getSampleCountFlagBits(),
{ filter != VK_FILTER_NEAREST, region.srcSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT, false });
state.clampToEdge = (region.srcOffsets[0].x < 0) ||
(region.srcOffsets[0].y < 0) ||
(static_cast<uint32_t>(region.srcOffsets[1].x) > srcExtent.width) ||
(static_cast<uint32_t>(region.srcOffsets[1].y) > srcExtent.height);
Routine *blitRoutine = getRoutine(state);
if(!blitRoutine)
{
return;
}
void(*blitFunction)(const BlitData *data) = (void(*)(const BlitData*))blitRoutine->getEntry();
BlitData data;
data.sPitchB = src->rowPitchBytes(srcAspect, region.srcSubresource.mipLevel);
data.dPitchB = dst->rowPitchBytes(dstAspect, region.dstSubresource.mipLevel);
data.dSliceB = dst->slicePitchBytes(dstAspect, region.dstSubresource.mipLevel);
data.w = static_cast<float>(region.srcOffsets[1].x - region.srcOffsets[0].x) /
static_cast<float>(region.dstOffsets[1].x - region.dstOffsets[0].x);
data.h = static_cast<float>(region.srcOffsets[1].y - region.srcOffsets[0].y) /
static_cast<float>(region.dstOffsets[1].y - region.dstOffsets[0].y);
data.x0 = region.srcOffsets[0].x + (0.5f - region.dstOffsets[0].x) * data.w;
data.y0 = region.srcOffsets[0].y + (0.5f - region.dstOffsets[0].y) * data.h;
data.x0d = region.dstOffsets[0].x;
data.x1d = region.dstOffsets[1].x;
data.y0d = region.dstOffsets[0].y;
data.y1d = region.dstOffsets[1].y;
data.sWidth = srcExtent.width;
data.sHeight = srcExtent.height;
VkOffset3D srcOffset = { 0, 0, region.srcOffsets[0].z };
VkOffset3D dstOffset = { 0, 0, region.dstOffsets[0].z };
for(int i = 0; i < numSlices; i++)
{
data.source = src->getTexelPointer(srcOffset, region.srcSubresource);
data.dest = dst->getTexelPointer(dstOffset, region.dstSubresource);
blitFunction(&data);
srcOffset.z++;
dstOffset.z++;
}
}
} }
...@@ -21,6 +21,11 @@ ...@@ -21,6 +21,11 @@
#include <string.h> #include <string.h>
namespace vk
{
class Image;
}
namespace sw namespace sw
{ {
class Blitter class Blitter
...@@ -57,6 +62,8 @@ namespace sw ...@@ -57,6 +62,8 @@ namespace sw
{ {
State() = default; State() = default;
State(const Options &options) : Options(options) {} State(const Options &options) : Options(options) {}
State(VkFormat sourceFormat, VkFormat destFormat, int destSamples, const Options &options) :
Options(options), sourceFormat(sourceFormat), destFormat(destFormat), destSamples(destSamples) {}
bool operator==(const State &state) const bool operator==(const State &state) const
{ {
...@@ -95,11 +102,15 @@ namespace sw ...@@ -95,11 +102,15 @@ namespace sw
virtual ~Blitter(); virtual ~Blitter();
void clear(void *pixel, VkFormat format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask); void clear(void *pixel, VkFormat format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
void clear(void *pixel, VkFormat format, vk::Image *dest, const VkImageSubresourceRange& subresourceRange, const VkRect2D* renderArea = nullptr);
void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, const Options &options); void blit(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, const Options &options);
void blit(vk::Image *src, vk::Image *dst, VkImageBlit region, VkFilter filter);
void blit3D(Surface *source, Surface *dest); void blit3D(Surface *source, Surface *dest);
private: private:
bool fastClear(void *pixel, VkFormat format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask); bool fastClear(void *pixel, VkFormat format, Surface *dest, const SliceRect &dRect, unsigned int rgbaMask);
bool fastClear(void *pixel, VkFormat format, vk::Image *dest, const VkImageSubresourceRange& subresourceRange, const VkRect2D* renderArea);
bool read(Float4 &color, Pointer<Byte> element, const State &state); bool read(Float4 &color, Pointer<Byte> element, const State &state);
bool write(Float4 &color, Pointer<Byte> element, const State &state); bool write(Float4 &color, Pointer<Byte> element, const State &state);
...@@ -111,6 +122,7 @@ namespace sw ...@@ -111,6 +122,7 @@ namespace sw
static Float4 LinearToSRGB(Float4 &color); static Float4 LinearToSRGB(Float4 &color);
static Float4 sRGBtoLinear(Float4 &color); static Float4 sRGBtoLinear(Float4 &color);
bool blitReactor(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, const Options &options); bool blitReactor(Surface *source, const SliceRectF &sRect, Surface *dest, const SliceRect &dRect, const Options &options);
Routine *getRoutine(const State &state);
Routine *generate(const State &state); Routine *generate(const State &state);
RoutineCache<State> *blitCache; RoutineCache<State> *blitCache;
......
...@@ -458,50 +458,9 @@ VkDeviceSize Image::getStorageSize(VkImageAspectFlags aspectMask) const ...@@ -458,50 +458,9 @@ VkDeviceSize Image::getStorageSize(VkImageAspectFlags aspectMask) const
return arrayLayers * getLayerSize(static_cast<VkImageAspectFlagBits>(aspectMask)); return arrayLayers * getLayerSize(static_cast<VkImageAspectFlagBits>(aspectMask));
} }
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(aspect),
deviceMemory->getOffsetPointer(getMemoryOffset(aspect, mipLevel, layer)),
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)
{ {
VkImageAspectFlagBits srcAspect = static_cast<VkImageAspectFlagBits>(region.srcSubresource.aspectMask); device->getBlitter()->blit(this, Cast(dstImage), region, filter);
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) ||
(srcAspect != dstAspect))
{
UNIMPLEMENTED();
}
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(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),
region.srcOffsets[0].z);
sw::SliceRect dRect(region.dstOffsets[0].x, region.dstOffsets[0].y,
region.dstOffsets[1].x, region.dstOffsets[1].y, region.dstOffsets[0].z);
for(int i = 0; i < numSlices; i++)
{
device->getBlitter()->blit(srcSurface, sRect, dstSurface, dRect,
{filter != VK_FILTER_NEAREST, srcAspect == VK_IMAGE_ASPECT_STENCIL_BIT, false});
sRect.slice++;
dRect.slice++;
}
delete srcSurface;
delete dstSurface;
} }
VkFormat Image::getClearFormat() const VkFormat Image::getClearFormat() const
...@@ -532,28 +491,7 @@ uint32_t Image::getLastMipLevel(const VkImageSubresourceRange& subresourceRange) ...@@ -532,28 +491,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, VkImageAspectFlagBits aspect) void Image::clear(void* pixelData, VkFormat format, const VkImageSubresourceRange& subresourceRange, const VkRect2D& renderArea)
{
uint32_t firstLayer = subresourceRange.baseArrayLayer;
uint32_t lastLayer = getLastLayerIndex(subresourceRange);
for(uint32_t layer = firstLayer; layer <= lastLayer; ++layer)
{
uint32_t lastLevel = getLastMipLevel(subresourceRange);
for(uint32_t mipLevel = subresourceRange.baseMipLevel; mipLevel <= lastLevel; ++mipLevel)
{
VkExtent3D mipLevelExtent = getMipLevelExtent(mipLevel);
for(uint32_t s = 0; s < mipLevelExtent.depth; ++s)
{
const sw::SliceRect dRect(0, 0, mipLevelExtent.width, mipLevelExtent.height, s);
sw::Surface* surface = asSurface(aspect, mipLevel, layer);
device->getBlitter()->clear(pixelData, format, surface, dRect, 0xF);
delete surface;
}
}
}
}
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))
...@@ -561,22 +499,7 @@ void Image::clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, ...@@ -561,22 +499,7 @@ void Image::clear(void* pixelData, VkFormat format, const VkRect2D& renderArea,
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
sw::SliceRect dRect(renderArea.offset.x, renderArea.offset.y, device->getBlitter()->clear(pixelData, format, this, subresourceRange, &renderArea);
renderArea.offset.x + renderArea.extent.width,
renderArea.offset.y + renderArea.extent.height, 0);
uint32_t firstLayer = subresourceRange.baseArrayLayer;
uint32_t lastLayer = getLastLayerIndex(subresourceRange);
for(uint32_t layer = firstLayer; layer <= lastLayer; ++layer)
{
for(uint32_t s = 0; s < extent.depth; ++s)
{
dRect.slice = s;
sw::Surface* surface = asSurface(aspect, 0, layer);
device->getBlitter()->clear(pixelData, format, surface, dRect, 0xF);
delete surface;
}
}
} }
void Image::clear(const VkClearColorValue& color, const VkImageSubresourceRange& subresourceRange) void Image::clear(const VkClearColorValue& color, const VkImageSubresourceRange& subresourceRange)
...@@ -586,7 +509,7 @@ void Image::clear(const VkClearColorValue& color, const VkImageSubresourceRange& ...@@ -586,7 +509,7 @@ void Image::clear(const VkClearColorValue& color, const VkImageSubresourceRange&
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
clear((void*)color.float32, getClearFormat(), subresourceRange, VK_IMAGE_ASPECT_COLOR_BIT); device->getBlitter()->clear((void*)color.float32, getClearFormat(), this, subresourceRange);
} }
void Image::clear(const VkClearDepthStencilValue& color, const VkImageSubresourceRange& subresourceRange) void Image::clear(const VkClearDepthStencilValue& color, const VkImageSubresourceRange& subresourceRange)
...@@ -599,12 +522,16 @@ void Image::clear(const VkClearDepthStencilValue& color, const VkImageSubresourc ...@@ -599,12 +522,16 @@ void Image::clear(const VkClearDepthStencilValue& color, const VkImageSubresourc
if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
{ {
clear((void*)(&color.depth), VK_FORMAT_D32_SFLOAT, subresourceRange, VK_IMAGE_ASPECT_DEPTH_BIT); VkImageSubresourceRange depthSubresourceRange = subresourceRange;
depthSubresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
device->getBlitter()->clear((void*)(&color.depth), VK_FORMAT_D32_SFLOAT, this, depthSubresourceRange);
} }
if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
{ {
clear((void*)(&color.stencil), VK_FORMAT_S8_UINT, subresourceRange, VK_IMAGE_ASPECT_STENCIL_BIT); VkImageSubresourceRange stencilSubresourceRange = subresourceRange;
stencilSubresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
device->getBlitter()->clear((void*)(&color.stencil), VK_FORMAT_S8_UINT, this, stencilSubresourceRange);
} }
} }
...@@ -621,18 +548,22 @@ void Image::clear(const VkClearValue& clearValue, const VkRect2D& renderArea, co ...@@ -621,18 +548,22 @@ void Image::clear(const VkClearValue& clearValue, const VkRect2D& renderArea, co
if(subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) if(subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
{ {
clear((void*)(clearValue.color.float32), getClearFormat(), renderArea, subresourceRange, VK_IMAGE_ASPECT_COLOR_BIT); clear((void*)(clearValue.color.float32), getClearFormat(), subresourceRange, renderArea);
} }
else else
{ {
if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
{ {
clear((void*)(&clearValue.depthStencil.depth), VK_FORMAT_D32_SFLOAT, renderArea, subresourceRange, VK_IMAGE_ASPECT_DEPTH_BIT); VkImageSubresourceRange depthSubresourceRange = subresourceRange;
depthSubresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
clear((void*)(&clearValue.depthStencil.depth), VK_FORMAT_D32_SFLOAT, depthSubresourceRange, renderArea);
} }
if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) if(subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
{ {
clear((void*)(&clearValue.depthStencil.stencil), VK_FORMAT_S8_UINT, renderArea, subresourceRange, VK_IMAGE_ASPECT_STENCIL_BIT); VkImageSubresourceRange stencilSubresourceRange = subresourceRange;
stencilSubresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
clear((void*)(&clearValue.depthStencil.stencil), VK_FORMAT_S8_UINT, stencilSubresourceRange, renderArea);
} }
} }
} }
......
...@@ -17,11 +17,6 @@ ...@@ -17,11 +17,6 @@
#include "VkObject.hpp" #include "VkObject.hpp"
namespace sw
{
class Surface;
};
namespace vk namespace vk
{ {
...@@ -57,15 +52,19 @@ public: ...@@ -57,15 +52,19 @@ public:
VkImageType getImageType() const { return imageType; } VkImageType getImageType() const { return imageType; }
VkFormat getFormat() const { return format; } VkFormat getFormat() const { return format; }
VkFormat getFormat(VkImageAspectFlagBits aspect) const;
uint32_t getArrayLayers() const { return arrayLayers; } uint32_t getArrayLayers() const { return arrayLayers; }
uint32_t getMipLevels() const { return mipLevels; }
uint32_t getLastLayerIndex(const VkImageSubresourceRange& subresourceRange) const;
uint32_t getLastMipLevel(const VkImageSubresourceRange& subresourceRange) const;
VkSampleCountFlagBits getSampleCountFlagBits() const { return samples; } VkSampleCountFlagBits getSampleCountFlagBits() const { return samples; }
VkExtent3D getMipLevelExtent(uint32_t mipLevel) const;
int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
int slicePitchBytes(VkImageAspectFlagBits aspect, 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(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(VkImageAspectFlags flags) const; VkDeviceSize getStorageSize(VkImageAspectFlags flags) const;
VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
...@@ -75,13 +74,8 @@ private: ...@@ -75,13 +74,8 @@ private:
VkDeviceSize texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const; VkDeviceSize texelOffsetBytesInStorage(const VkOffset3D& offset, const VkImageSubresourceLayers& subresource) const;
VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect) const; VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect) const;
int bytesPerTexel(VkImageAspectFlagBits flags) const; int bytesPerTexel(VkImageAspectFlagBits flags) const;
VkExtent3D getMipLevelExtent(uint32_t mipLevel) const;
VkFormat getFormat(VkImageAspectFlagBits flags) const;
uint32_t getLastLayerIndex(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, VkImageAspectFlagBits aspect); void clear(void* pixelData, VkFormat format, const VkImageSubresourceRange& subresourceRange, const VkRect2D& renderArea);
void clear(void* pixelData, VkFormat format, const VkRect2D& renderArea, const VkImageSubresourceRange& subresourceRange, VkImageAspectFlagBits aspect);
const Device *const device = nullptr; const Device *const device = nullptr;
DeviceMemory* deviceMemory = nullptr; DeviceMemory* deviceMemory = nullptr;
......
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