blob: c5ac794ac38ad04fc4906da02c6a1d0c8cca9b85 [file] [log] [blame]
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RenderbufferVk.cpp:
// Implements the class methods for RenderbufferVk.
//
#include "libANGLE/renderer/vulkan/RenderbufferVk.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
namespace rx
{
namespace
{
constexpr VkClearDepthStencilValue kDefaultClearDepthStencilValue = {0.0f, 1};
constexpr VkClearColorValue kBlackClearColorValue = {{0}};
} // anonymous namespace
RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
: RenderbufferImpl(state), mRenderTarget(&mImage, &mImageView, 0, nullptr)
{}
RenderbufferVk::~RenderbufferVk() {}
void RenderbufferVk::onDestroy(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
mImage.release(renderer);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
}
angle::Result RenderbufferVk::setStorage(const gl::Context *context,
GLenum internalformat,
size_t width,
size_t height)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
const vk::Format &vkFormat = renderer->getFormat(internalformat);
if (mImage.valid())
{
// Check against the state if we need to recreate the storage.
if (internalformat != mState.getFormat().info->internalFormat ||
static_cast<GLsizei>(width) != mState.getWidth() ||
static_cast<GLsizei>(height) != mState.getHeight())
{
mImage.release(renderer);
renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
}
}
if (!mImage.valid() && (width != 0 && height != 0))
{
const angle::Format &textureFormat = vkFormat.textureFormat();
bool isDepthOrStencilFormat = textureFormat.depthBits > 0 || textureFormat.stencilBits > 0;
const VkImageUsageFlags usage =
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT |
(textureFormat.redBits > 0 ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : 0) |
(isDepthOrStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
ANGLE_TRY(mImage.init(contextVk, gl::TextureType::_2D, extents, vkFormat, 1, usage, 1, 1));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(contextVk, renderer->getMemoryProperties(), flags));
VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
// Note that LUMA textures are not color-renderable, so a read-view with swizzle is not
// needed.
ANGLE_TRY(mImage.initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
&mImageView, 1));
// TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mImage.recordCommands(contextVk, &commandBuffer));
if (isDepthOrStencilFormat)
{
mImage.clearDepthStencil(aspect, aspect, kDefaultClearDepthStencilValue, commandBuffer);
}
else
{
mImage.clearColor(kBlackClearColorValue, 0, 1, commandBuffer);
}
}
return angle::Result::Continue;
}
angle::Result RenderbufferVk::setStorageMultisample(const gl::Context *context,
size_t samples,
GLenum internalformat,
size_t width,
size_t height)
{
ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
return angle::Result::Stop;
}
angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *context,
egl::Image *image)
{
ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
return angle::Result::Stop;
}
angle::Result RenderbufferVk::getAttachmentRenderTarget(const gl::Context *context,
GLenum binding,
const gl::ImageIndex &imageIndex,
FramebufferAttachmentRenderTarget **rtOut)
{
ASSERT(mImage.valid());
*rtOut = &mRenderTarget;
return angle::Result::Continue;
}
angle::Result RenderbufferVk::initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex)
{
UNIMPLEMENTED();
return angle::Result::Continue;
}
} // namespace rx