Commit bc54342b by Jamie Madill Committed by Commit Bot

Vulkan: Make RenderTargetVk use ImageHelper.

Bug: angleproject:2318 Change-Id: I9bc4bb7f5bcd3029a31c8570809f253cf5e4b12a Reviewed-on: https://chromium-review.googlesource.com/980773 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarLuc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent 62059a55
......@@ -140,17 +140,14 @@ void CommandGraphNode::storeRenderPassInfo(const Framebuffer &framebuffer,
void CommandGraphNode::appendColorRenderTarget(Serial serial, RenderTargetVk *colorRenderTarget)
{
// TODO(jmadill): Layout transition?
mRenderPassDesc.packColorAttachment(*colorRenderTarget->format, colorRenderTarget->samples);
mRenderPassDesc.packColorAttachment(*colorRenderTarget->image);
colorRenderTarget->resource->onWriteResource(this, serial);
}
void CommandGraphNode::appendDepthStencilRenderTarget(Serial serial,
RenderTargetVk *depthStencilRenderTarget)
{
// TODO(jmadill): Layout transition?
mRenderPassDesc.packDepthStencilAttachment(*depthStencilRenderTarget->format,
depthStencilRenderTarget->samples);
mRenderPassDesc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
depthStencilRenderTarget->resource->onWriteResource(this, serial);
}
......
......@@ -34,7 +34,8 @@ namespace
const gl::InternalFormat &GetReadAttachmentInfo(const gl::Context *context,
RenderTargetVk *renderTarget)
{
GLenum implFormat = renderTarget->format->textureFormat().fboImplementationInternalFormat;
GLenum implFormat =
renderTarget->image->getFormat().textureFormat().fboImplementationInternalFormat;
return gl::GetSizedInternalFormatInfo(implFormat);
}
} // anonymous namespace
......@@ -149,11 +150,11 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
RenderTargetVk *renderTarget = mRenderTargetCache.getDepthStencil();
renderTarget->resource->onWriteResource(writingNode, currentSerial);
renderTarget->image->changeLayoutWithStages(
renderTarget->image->getImage().changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleDepthStencilImage(*renderTarget->image, aspectFlags,
commandBuffer->clearSingleDepthStencilImage(renderTarget->image->getImage(), aspectFlags,
clearDepthStencilValue);
if ((mask & GL_COLOR_BUFFER_BIT) == 0)
......@@ -188,11 +189,11 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
ASSERT(colorRenderTarget);
colorRenderTarget->resource->onWriteResource(writingNode, currentSerial);
colorRenderTarget->image->changeLayoutWithStages(
colorRenderTarget->image->getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleColorImage(*colorRenderTarget->image,
commandBuffer->clearSingleColorImage(colorRenderTarget->image->getImage(),
contextVk->getClearColorValue().color);
}
......@@ -260,10 +261,10 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
ASSERT(renderTarget);
vk::Image *readImage = renderTarget->image;
vk::Image &readImage = renderTarget->image->getImage();
vk::ImageHelper stagingImage;
ANGLE_TRY(stagingImage.init2DStaging(
device, renderer->getMemoryProperties(), *renderTarget->format,
device, renderer->getMemoryProperties(), renderTarget->image->getFormat(),
gl::Extents(area.width, area.height, 1), vk::StagingUsage::Read));
vk::CommandBuffer *commandBuffer = nullptr;
......@@ -272,7 +273,7 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
stagingImage.getImage().changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
commandBuffer);
readImage->changeLayoutWithStages(
readImage.changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
......@@ -295,7 +296,7 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
region.extent.height = area.height;
region.extent.depth = 1;
commandBuffer->copyImage(*readImage, stagingImage.getImage(), 1, &region);
commandBuffer->copyImage(readImage, stagingImage.getImage(), 1, &region);
// Triggers a full finish.
// TODO(jmadill): Don't block on asynchronous readback.
......@@ -306,7 +307,7 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, stagingImage.getAllocatedMemorySize(),
0, &mapPointer));
const angle::Format &angleFormat = renderTarget->format->textureFormat();
const angle::Format &angleFormat = renderTarget->image->getFormat().textureFormat();
// TODO(jmadill): Use pixel bytes from the ANGLE format directly.
const auto &glFormat = gl::GetSizedInternalFormatInfo(angleFormat.glInternalFormat);
......@@ -384,14 +385,13 @@ const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc(const gl::Context *co
{
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget);
desc.packColorAttachment(*colorRenderTarget->format, colorRenderTarget->samples);
desc.packColorAttachment(*colorRenderTarget->image);
}
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
desc.packDepthStencilAttachment(*depthStencilRenderTarget->format,
depthStencilRenderTarget->samples);
desc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
}
mRenderPassDesc = desc;
......@@ -431,8 +431,9 @@ gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(const gl::Con
ASSERT(colorRenderTarget);
attachments.push_back(colorRenderTarget->imageView->getHandle());
ASSERT(attachmentsSize.empty() || attachmentsSize == colorRenderTarget->extents);
attachmentsSize = colorRenderTarget->extents;
ASSERT(attachmentsSize.empty() ||
attachmentsSize == colorRenderTarget->image->getExtents());
attachmentsSize = colorRenderTarget->image->getExtents();
}
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
......@@ -440,8 +441,9 @@ gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(const gl::Con
{
attachments.push_back(depthStencilRenderTarget->imageView->getHandle());
ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilRenderTarget->extents);
attachmentsSize = depthStencilRenderTarget->extents;
ASSERT(attachmentsSize.empty() ||
attachmentsSize == depthStencilRenderTarget->image->getExtents());
attachmentsSize = depthStencilRenderTarget->image->getExtents();
}
ASSERT(!attachments.empty());
......@@ -547,7 +549,7 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
ASSERT(colorRenderTarget);
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
colorRenderTarget->image->changeLayoutWithStages(
colorRenderTarget->image->getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
commandBuffer);
......@@ -559,11 +561,11 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
if (depthStencilRenderTarget)
{
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
const angle::Format &format = depthStencilRenderTarget->format->textureFormat();
const angle::Format &format = depthStencilRenderTarget->image->getFormat().textureFormat();
VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
(format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
depthStencilRenderTarget->image->changeLayoutWithStages(
depthStencilRenderTarget->image->getImage().changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
commandBuffer);
......
......@@ -11,20 +11,7 @@
namespace rx
{
RenderTargetVk::RenderTargetVk()
RenderTargetVk::RenderTargetVk() : image(nullptr), imageView(nullptr), resource(nullptr)
{
reset();
}
void RenderTargetVk::reset()
{
format = nullptr;
image = nullptr;
imageView = nullptr;
extents = gl::Extents();
samples = VK_SAMPLE_COUNT_1_BIT;
resource = nullptr;
}
} // namespace rx
......@@ -20,10 +20,9 @@ class ResourceVk;
namespace vk
{
struct Format;
class Image;
class ImageHelper;
class ImageView;
}
} // namespace vk
// This is a very light-weight class that does not own to the resources it points to.
// It's meant only to copy across some information from a FramebufferAttachment to the
......@@ -33,13 +32,8 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
public:
RenderTargetVk();
void reset();
const vk::Format *format;
vk::Image *image;
vk::ImageHelper *image;
vk::ImageView *imageView;
gl::Extents extents;
VkSampleCountFlagBits samples;
ResourceVk *resource;
};
......
......@@ -25,7 +25,7 @@ constexpr VkClearColorValue kBlackClearColorValue = {{0}};
RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state) : RenderbufferImpl(state)
{
mRenderTarget.image = &mImage.getImage();
mRenderTarget.image = &mImage;
mRenderTarget.imageView = &mImageView;
mRenderTarget.resource = this;
}
......@@ -70,13 +70,6 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context,
}
}
// Init RenderTarget.
mRenderTarget.extents.width = static_cast<int>(width);
mRenderTarget.extents.height = static_cast<int>(height);
mRenderTarget.extents.depth = 1;
mRenderTarget.format = &vkFormat;
mRenderTarget.samples = VK_SAMPLE_COUNT_1_BIT; // TODO(jmadill): Multisample bits.
if (!mImage.valid() && (width != 0 || height != 0))
{
const angle::Format &textureFormat = vkFormat.textureFormat();
......@@ -87,7 +80,8 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context,
(textureFormat.redBits > 0 ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : 0) |
(isDepthOrStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
ANGLE_TRY(mImage.init2D(device, mRenderTarget.extents, vkFormat, 1, usage));
gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
ANGLE_TRY(mImage.init2D(device, extents, vkFormat, 1, usage));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(device, renderer->getMemoryProperties(), flags));
......
......@@ -35,7 +35,7 @@ VkPresentModeKHR GetDesiredPresentMode(const std::vector<VkPresentModeKHR> &pres
// TODO(jmadill): Properly select present mode and re-create display if changed.
VkPresentModeKHR bestChoice = VK_PRESENT_MODE_MAILBOX_KHR;
for (auto presentMode : presentModes)
for (VkPresentModeKHR presentMode : presentModes)
{
if (presentMode == bestChoice)
{
......@@ -151,9 +151,17 @@ gl::Error OffscreenSurfaceVk::initializeContents(const gl::Context *context,
return gl::NoError();
}
WindowSurfaceVk::SwapchainImage::SwapchainImage() = default;
WindowSurfaceVk::SwapchainImage::SwapchainImage(WindowSurfaceVk::SwapchainImage &&other) = default;
WindowSurfaceVk::SwapchainImage::~SwapchainImage() = default;
WindowSurfaceVk::SwapchainImage::SwapchainImage() = default;
WindowSurfaceVk::SwapchainImage::~SwapchainImage() = default;
WindowSurfaceVk::SwapchainImage::SwapchainImage(SwapchainImage &&other)
: image(std::move(other.image)),
imageView(std::move(other.imageView)),
framebuffer(std::move(other.framebuffer)),
imageAcquiredSemaphore(std::move(other.imageAcquiredSemaphore)),
commandsCompleteSemaphore(std::move(other.commandsCompleteSemaphore))
{
}
WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState,
EGLNativeWindowType window,
......@@ -168,10 +176,7 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState,
mDepthStencilRenderTarget(),
mCurrentSwapchainImageIndex(0)
{
mColorRenderTarget.extents.width = static_cast<GLint>(width);
mColorRenderTarget.extents.height = static_cast<GLint>(height);
mColorRenderTarget.extents.depth = 1;
mColorRenderTarget.resource = this;
mColorRenderTarget.resource = this;
}
WindowSurfaceVk::~WindowSurfaceVk()
......@@ -192,15 +197,14 @@ void WindowSurfaceVk::destroy(const egl::Display *display)
mAcquireNextImageSemaphore.destroy(device);
renderer->releaseResource(*this, &mDepthStencilImage);
renderer->releaseResource(*this, &mDepthStencilDeviceMemory);
renderer->releaseResource(*this, &mDepthStencilImageView);
mDepthStencilImage.release(renderer->getCurrentQueueSerial(), renderer);
mDepthStencilImageView.destroy(device);
for (auto &swapchainImage : mSwapchainImages)
for (SwapchainImage &swapchainImage : mSwapchainImages)
{
// Although we don't own the swapchain image handles, we need to keep our shutdown clean.
swapchainImage.image.reset();
swapchainImage.image.getImage().reset();
swapchainImage.image.destroy(device);
swapchainImage.imageView.destroy(device);
swapchainImage.framebuffer.destroy(device);
swapchainImage.imageAcquiredSemaphore.destroy(device);
......@@ -248,22 +252,24 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
ANGLE_VK_CHECK((surfaceCaps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0,
VK_ERROR_INITIALIZATION_FAILED);
EGLAttrib attribWidth = mState.attributes.get(EGL_WIDTH, 0);
EGLAttrib attribHeight = mState.attributes.get(EGL_HEIGHT, 0);
if (surfaceCaps.currentExtent.width == 0xFFFFFFFFu)
{
ASSERT(surfaceCaps.currentExtent.height == 0xFFFFFFFFu);
if (mColorRenderTarget.extents.width == 0)
if (attribWidth == 0)
{
width = windowSize.width;
}
if (mColorRenderTarget.extents.height == 0)
if (attribHeight == 0)
{
height = windowSize.height;
}
}
mColorRenderTarget.extents.width = static_cast<int>(width);
mColorRenderTarget.extents.height = static_cast<int>(height);
gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
uint32_t presentModeCount = 0;
ANGLE_VK_TRY(vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, mSurface,
......@@ -306,8 +312,8 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
ANGLE_VK_TRY(vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, mSurface, &surfaceFormatCount,
surfaceFormats.data()));
mColorRenderTarget.format = &renderer->getFormat(mState.config->renderTargetFormat);
VkFormat nativeFormat = mColorRenderTarget.format->vkTextureFormat;
const vk::Format &format = renderer->getFormat(mState.config->renderTargetFormat);
VkFormat nativeFormat = format.vkTextureFormat;
if (surfaceFormatCount == 1u && surfaceFormats[0].format == VK_FORMAT_UNDEFINED)
{
......@@ -316,7 +322,7 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
else
{
bool foundFormat = false;
for (const auto &surfaceFormat : surfaceFormats)
for (const VkSurfaceFormatKHR &surfaceFormat : surfaceFormats)
{
if (surfaceFormat.format == nativeFormat)
{
......@@ -388,35 +394,16 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
for (uint32_t imageIndex = 0; imageIndex < imageCount; ++imageIndex)
{
VkImage swapchainImage = swapchainImages[imageIndex];
VkImageViewCreateInfo imageViewInfo;
imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewInfo.pNext = nullptr;
imageViewInfo.flags = 0;
imageViewInfo.image = swapchainImage;
imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewInfo.format = nativeFormat;
imageViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
imageViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
imageViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageViewInfo.subresourceRange.baseMipLevel = 0;
imageViewInfo.subresourceRange.levelCount = 1;
imageViewInfo.subresourceRange.baseArrayLayer = 0;
imageViewInfo.subresourceRange.layerCount = 1;
auto &member = mSwapchainImages[imageIndex];
member.image.setHandle(swapchainImage);
ANGLE_TRY(member.imageView.init(device, imageViewInfo));
SwapchainImage &member = mSwapchainImages[imageIndex];
member.image.init2DWeakReference(swapchainImages[imageIndex], extents, format, 1);
member.image.initImageView(device, VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(),
&member.imageView);
// Set transfer dest layout, and clear the image to black.
member.image.changeLayoutWithStages(
member.image.getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleColorImage(member.image, transparentBlack);
commandBuffer->clearSingleColorImage(member.image.getImage(), transparentBlack);
ANGLE_TRY(member.imageAcquiredSemaphore.init(device));
ANGLE_TRY(member.commandsCompleteSemaphore.init(device));
......@@ -434,32 +421,9 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
VkImageCreateInfo imageInfo;
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.pNext = nullptr;
imageInfo.flags = 0;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.format = dsFormat.vkTextureFormat;
imageInfo.extent.width = static_cast<uint32_t>(width);
imageInfo.extent.height = static_cast<uint32_t>(height);
imageInfo.extent.depth = 1;
imageInfo.mipLevels = 1;
imageInfo.arrayLayers = 1;
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.usage = usage;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageInfo.queueFamilyIndexCount = 0;
imageInfo.pQueueFamilyIndices = nullptr;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
ANGLE_TRY(mDepthStencilImage.init(device, imageInfo));
// TODO(jmadill): Memory sub-allocation. http://anglebug.com/2162
size_t requiredSize;
ANGLE_TRY(vk::AllocateImageMemory(renderer, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
&mDepthStencilImage, &mDepthStencilDeviceMemory,
&requiredSize));
ANGLE_TRY(mDepthStencilImage.init2D(device, extents, dsFormat, 1, usage));
ANGLE_TRY(mDepthStencilImage.initMemory(device, renderer->getMemoryProperties(),
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
const VkImageAspectFlags aspect =
(dsFormat.textureFormat().depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
......@@ -468,38 +432,18 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
VkClearDepthStencilValue depthStencilClearValue = {1.0f, 0};
// Set transfer dest layout, and clear the image.
mDepthStencilImage.changeLayoutWithStages(aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleDepthStencilImage(mDepthStencilImage, aspect,
mDepthStencilImage.getImage().changeLayoutWithStages(
aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleDepthStencilImage(mDepthStencilImage.getImage(), aspect,
depthStencilClearValue);
// Depth/Stencil image views.
VkImageViewCreateInfo imageViewInfo;
imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewInfo.pNext = nullptr;
imageViewInfo.flags = 0;
imageViewInfo.image = mDepthStencilImage.getHandle();
imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewInfo.format = dsFormat.vkTextureFormat;
imageViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
imageViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
imageViewInfo.subresourceRange.aspectMask = aspect;
imageViewInfo.subresourceRange.baseMipLevel = 0;
imageViewInfo.subresourceRange.levelCount = 1;
imageViewInfo.subresourceRange.baseArrayLayer = 0;
imageViewInfo.subresourceRange.layerCount = 1;
ANGLE_TRY(mDepthStencilImageView.init(device, imageViewInfo));
mDepthStencilRenderTarget.extents.width = static_cast<GLint>(width);
mDepthStencilRenderTarget.extents.height = static_cast<GLint>(height);
mDepthStencilRenderTarget.extents.depth = 1;
mDepthStencilRenderTarget.resource = this;
mDepthStencilRenderTarget.image = &mDepthStencilImage;
mDepthStencilRenderTarget.format = &dsFormat;
ANGLE_TRY(mDepthStencilImage.initImageView(device, aspect, gl::SwizzleState(),
&mDepthStencilImageView));
mDepthStencilRenderTarget.resource = this;
mDepthStencilRenderTarget.image = &mDepthStencilImage;
mDepthStencilRenderTarget.imageView = &mDepthStencilImageView;
// TODO(jmadill): Figure out how to pass depth/stencil image views to the RenderTargetVk.
}
......@@ -520,11 +464,11 @@ egl::Error WindowSurfaceVk::swap(const gl::Context *context)
vk::CommandBuffer *swapCommands = nullptr;
ANGLE_TRY(beginWriteResource(renderer, &swapCommands));
auto &image = mSwapchainImages[mCurrentSwapchainImageIndex];
SwapchainImage &image = mSwapchainImages[mCurrentSwapchainImageIndex];
image.image.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, swapCommands);
image.image.getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, swapCommands);
ANGLE_TRY(
renderer->flush(context, image.imageAcquiredSemaphore, image.commandsCompleteSemaphore));
......@@ -555,7 +499,7 @@ vk::Error WindowSurfaceVk::nextSwapchainImage(RendererVk *renderer)
mAcquireNextImageSemaphore.getHandle(), VK_NULL_HANDLE,
&mCurrentSwapchainImageIndex));
auto &image = mSwapchainImages[mCurrentSwapchainImageIndex];
SwapchainImage &image = mSwapchainImages[mCurrentSwapchainImageIndex];
// Swap the unused swapchain semaphore and the now active spare semaphore.
std::swap(image.imageAcquiredSemaphore, mAcquireNextImageSemaphore);
......@@ -607,12 +551,12 @@ void WindowSurfaceVk::setSwapInterval(EGLint interval)
EGLint WindowSurfaceVk::getWidth() const
{
return static_cast<EGLint>(mColorRenderTarget.extents.width);
return static_cast<EGLint>(mColorRenderTarget.image->getExtents().width);
}
EGLint WindowSurfaceVk::getHeight() const
{
return static_cast<EGLint>(mColorRenderTarget.extents.height);
return static_cast<EGLint>(mColorRenderTarget.image->getExtents().height);
}
EGLint WindowSurfaceVk::isPostSubBufferSupported() const
......@@ -649,7 +593,7 @@ gl::ErrorOrResult<vk::Framebuffer *> WindowSurfaceVk::getCurrentFramebuffer(
VkDevice device,
const vk::RenderPass &compatibleRenderPass)
{
auto &currentFramebuffer = mSwapchainImages[mCurrentSwapchainImageIndex].framebuffer;
vk::Framebuffer &currentFramebuffer = mSwapchainImages[mCurrentSwapchainImageIndex].framebuffer;
if (currentFramebuffer.valid())
{
......@@ -659,19 +603,20 @@ gl::ErrorOrResult<vk::Framebuffer *> WindowSurfaceVk::getCurrentFramebuffer(
VkFramebufferCreateInfo framebufferInfo;
const gl::Extents &extents = mColorRenderTarget.image->getExtents();
std::array<VkImageView, 2> imageViews = {{VK_NULL_HANDLE, mDepthStencilImageView.getHandle()}};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.pNext = nullptr;
framebufferInfo.flags = 0;
framebufferInfo.renderPass = compatibleRenderPass.getHandle();
framebufferInfo.attachmentCount = (mDepthStencilImageView.valid() ? 2u : 1u);
framebufferInfo.attachmentCount = (mDepthStencilImage.valid() ? 2u : 1u);
framebufferInfo.pAttachments = imageViews.data();
framebufferInfo.width = static_cast<uint32_t>(mColorRenderTarget.extents.width);
framebufferInfo.height = static_cast<uint32_t>(mColorRenderTarget.extents.height);
framebufferInfo.width = static_cast<uint32_t>(extents.width);
framebufferInfo.height = static_cast<uint32_t>(extents.height);
framebufferInfo.layers = 1;
for (auto &swapchainImage : mSwapchainImages)
for (SwapchainImage &swapchainImage : mSwapchainImages)
{
imageViews[0] = swapchainImage.imageView.getHandle();
ANGLE_TRY(swapchainImage.framebuffer.init(device, framebufferInfo));
......
......@@ -128,13 +128,13 @@ class WindowSurfaceVk : public SurfaceImpl, public ResourceVk
// problem with needing to know the next available image index before we acquire it.
vk::Semaphore mAcquireNextImageSemaphore;
struct SwapchainImage
struct SwapchainImage : angle::NonCopyable
{
SwapchainImage();
SwapchainImage(SwapchainImage &&other);
~SwapchainImage();
vk::Image image;
vk::ImageHelper image;
vk::ImageView imageView;
vk::Framebuffer framebuffer;
vk::Semaphore imageAcquiredSemaphore;
......@@ -143,8 +143,7 @@ class WindowSurfaceVk : public SurfaceImpl, public ResourceVk
std::vector<SwapchainImage> mSwapchainImages;
vk::Image mDepthStencilImage;
vk::DeviceMemory mDepthStencilDeviceMemory;
vk::ImageHelper mDepthStencilImage;
vk::ImageView mDepthStencilImageView;
};
......
......@@ -52,6 +52,9 @@ void MapSwizzleState(GLenum internalFormat,
TextureVk::TextureVk(const gl::TextureState &state) : TextureImpl(state)
{
mRenderTarget.image = &mImage;
mRenderTarget.imageView = &mImageView;
mRenderTarget.resource = this;
}
TextureVk::~TextureVk()
......@@ -105,8 +108,6 @@ gl::Error TextureVk::setImage(const gl::Context *context,
}
}
mRenderTarget.reset();
// Early-out on empty textures, don't create a zero-sized storage.
if (size.width == 0 || size.height == 0 || size.depth == 0)
{
......@@ -173,13 +174,6 @@ gl::Error TextureVk::setImage(const gl::Context *context,
ANGLE_TRY(mSampler.init(device, samplerInfo));
}
mRenderTarget.image = &mImage.getImage();
mRenderTarget.imageView = &mImageView;
mRenderTarget.format = &vkFormat;
mRenderTarget.extents = size;
mRenderTarget.samples = VK_SAMPLE_COUNT_1_BIT;
mRenderTarget.resource = this;
// Handle initial data.
if (pixels)
{
......@@ -212,8 +206,8 @@ gl::Error TextureVk::setSubImageImpl(ContextVk *contextVk,
{
RendererVk *renderer = contextVk->getRenderer();
VkDevice device = renderer->getDevice();
const gl::Extents &size = mRenderTarget.extents;
const vk::Format &vkFormat = *mRenderTarget.format;
const gl::Extents &size = mImage.getExtents();
const vk::Format &vkFormat = mImage.getFormat();
vk::ImageHelper stagingImage;
ANGLE_TRY(stagingImage.init2DStaging(device, renderer->getMemoryProperties(), vkFormat, size,
......
......@@ -232,29 +232,30 @@ RenderPassDesc::RenderPassDesc(const RenderPassDesc &other)
memcpy(this, &other, sizeof(RenderPassDesc));
}
void RenderPassDesc::packAttachment(uint32_t index, const vk::Format &format, GLsizei samples)
void RenderPassDesc::packAttachment(uint32_t index, const ImageHelper &imageHelper)
{
PackedAttachmentDesc &desc = mAttachmentDescs[index];
// TODO(jmadill): We would only need this flag for duplicated attachments.
desc.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
ASSERT(desc.samples < std::numeric_limits<uint8_t>::max());
desc.samples = static_cast<uint8_t>(samples);
ASSERT(imageHelper.getSamples() < std::numeric_limits<uint8_t>::max());
desc.samples = static_cast<uint8_t>(imageHelper.getSamples());
const Format &format = imageHelper.getFormat();
ASSERT(format.vkTextureFormat < std::numeric_limits<uint16_t>::max());
desc.format = static_cast<uint16_t>(format.vkTextureFormat);
}
void RenderPassDesc::packColorAttachment(const vk::Format &format, GLsizei samples)
void RenderPassDesc::packColorAttachment(const ImageHelper &imageHelper)
{
ASSERT(mDepthStencilAttachmentCount == 0);
ASSERT(mColorAttachmentCount < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
packAttachment(mColorAttachmentCount++, format, samples);
packAttachment(mColorAttachmentCount++, imageHelper);
}
void RenderPassDesc::packDepthStencilAttachment(const vk::Format &format, GLsizei samples)
void RenderPassDesc::packDepthStencilAttachment(const ImageHelper &imageHelper)
{
ASSERT(mDepthStencilAttachmentCount == 0);
packAttachment(mColorAttachmentCount + mDepthStencilAttachmentCount++, format, samples);
packAttachment(mColorAttachmentCount + mDepthStencilAttachmentCount++, imageHelper);
}
RenderPassDesc &RenderPassDesc::operator=(const RenderPassDesc &other)
......
......@@ -54,8 +54,8 @@ class RenderPassDesc final
RenderPassDesc &operator=(const RenderPassDesc &other);
// Depth stencil attachments must be packed after color attachments.
void packColorAttachment(const Format &format, GLsizei samples);
void packDepthStencilAttachment(const Format &format, GLsizei samples);
void packColorAttachment(const ImageHelper &imageHelper);
void packDepthStencilAttachment(const ImageHelper &imageHelper);
size_t hash() const;
......@@ -65,7 +65,7 @@ class RenderPassDesc final
const PackedAttachmentDesc &operator[](size_t index) const;
private:
void packAttachment(uint32_t index, const vk::Format &format, GLsizei samples);
void packAttachment(uint32_t index, const ImageHelper &imageHelper);
uint32_t mColorAttachmentCount;
uint32_t mDepthStencilAttachmentCount;
......
......@@ -1425,6 +1425,16 @@ ImageHelper::ImageHelper() : mFormat(nullptr), mSamples(0), mAllocatedMemorySize
{
}
ImageHelper::ImageHelper(ImageHelper &&other)
: mImage(std::move(other.mImage)),
mDeviceMemory(std::move(other.mDeviceMemory)),
mExtents(other.mExtents),
mFormat(other.mFormat),
mSamples(other.mSamples),
mAllocatedMemorySize(other.mAllocatedMemorySize)
{
}
ImageHelper::~ImageHelper()
{
ASSERT(!valid());
......@@ -1480,6 +1490,7 @@ Error ImageHelper::initMemory(VkDevice device,
const MemoryProperties &memoryProperties,
VkMemoryPropertyFlags flags)
{
// TODO(jmadill): Memory sub-allocation. http://anglebug.com/2162
ANGLE_TRY(AllocateBufferOrImageMemory(device, memoryProperties, flags, &mImage, &mDeviceMemory,
&mAllocatedMemorySize));
return NoError();
......@@ -1517,6 +1528,20 @@ void ImageHelper::destroy(VkDevice device)
mDeviceMemory.destroy(device);
}
void ImageHelper::init2DWeakReference(VkImage handle,
const gl::Extents &extents,
const Format &format,
GLint samples)
{
ASSERT(!valid());
mExtents = extents;
mFormat = &format;
mSamples = samples;
mImage.setHandle(handle);
}
Error ImageHelper::init2DStaging(VkDevice device,
const MemoryProperties &memoryProperties,
const Format &format,
......
......@@ -707,6 +707,7 @@ class ImageHelper final : angle::NonCopyable
{
public:
ImageHelper();
ImageHelper(ImageHelper &&other);
~ImageHelper();
bool valid() const;
......@@ -716,6 +717,10 @@ class ImageHelper final : angle::NonCopyable
const Format &format,
GLint samples,
VkImageUsageFlags usage);
void init2DWeakReference(VkImage handle,
const gl::Extents &extents,
const Format &format,
GLint samples);
Error initMemory(VkDevice device,
const MemoryProperties &memoryProperties,
VkMemoryPropertyFlags flags);
......
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