Commit 7b21381e by Jamie Madill Committed by Commit Bot

Vulkan: Support changing in-flight Renderbuffers.

Bug: angleproject:2347 Change-Id: I9bb1494a960969bb6e7c8656c27c7c180ddba069 Reviewed-on: https://chromium-review.googlesource.com/922458Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent d2cb7cec
......@@ -17,8 +17,11 @@ namespace rx
{
RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
: RenderbufferImpl(state), mRequiredSize(0)
: RenderbufferImpl(state), mAllocatedMemorySize(0)
{
mRenderTarget.image = &mImage;
mRenderTarget.imageView = &mImageView;
mRenderTarget.resource = this;
}
RenderbufferVk::~RenderbufferVk()
......@@ -33,6 +36,9 @@ gl::Error RenderbufferVk::onDestroy(const gl::Context *context)
renderer->releaseResource(*this, &mImage);
renderer->releaseResource(*this, &mDeviceMemory);
renderer->releaseResource(*this, &mImageView);
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
return gl::NoError();
}
......@@ -46,66 +52,83 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context,
const vk::Format &vkFormat = renderer->getFormat(internalformat);
VkDevice device = renderer->getDevice();
VkImageUsageFlags usage =
(VK_IMAGE_USAGE_COLOR_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 = vkFormat.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(mImage.init(device, imageInfo));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(vk::AllocateImageMemory(renderer, flags, &mImage, &mDeviceMemory, &mRequiredSize));
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
// Allocate ImageView.
VkImageViewCreateInfo viewInfo;
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.pNext = nullptr;
viewInfo.flags = 0;
viewInfo.image = mImage.getHandle();
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = vkFormat.vkTextureFormat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = aspect;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
ANGLE_TRY(mImageView.init(device, viewInfo));
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())
{
ASSERT(mImageView.valid());
renderer->releaseResource(*this, &mImage);
renderer->releaseResource(*this, &mDeviceMemory);
renderer->releaseResource(*this, &mImageView);
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
}
}
// Init RenderTarget.
mRenderTarget.extents.width = static_cast<int>(width);
mRenderTarget.extents.height = static_cast<int>(height);
mRenderTarget.extents.depth = 1;
mRenderTarget.format = &vkFormat;
mRenderTarget.image = &mImage;
mRenderTarget.imageView = &mImageView;
mRenderTarget.resource = this;
mRenderTarget.samples = VK_SAMPLE_COUNT_1_BIT; // TODO(jmadill): Multisample bits.
if (!mImage.valid() && (width != 0 || height != 0))
{
const VkImageUsageFlags usage =
(VK_IMAGE_USAGE_COLOR_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 = vkFormat.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(mImage.init(device, imageInfo));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(vk::AllocateImageMemory(renderer, flags, &mImage, &mDeviceMemory,
&mAllocatedMemorySize));
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
// Allocate ImageView.
VkImageViewCreateInfo viewInfo;
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.pNext = nullptr;
viewInfo.flags = 0;
viewInfo.image = mImage.getHandle();
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = vkFormat.vkTextureFormat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = aspect;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
ANGLE_TRY(mImageView.init(device, viewInfo));
}
return gl::NoError();
}
......
......@@ -48,7 +48,7 @@ class RenderbufferVk : public RenderbufferImpl, public ResourceVk
vk::Image mImage;
vk::DeviceMemory mDeviceMemory;
vk::ImageView mImageView;
size_t mRequiredSize;
size_t mAllocatedMemorySize;
RenderTargetVk mRenderTarget;
};
......
......@@ -31,13 +31,13 @@ gl::Error TextureVk::onDestroy(const gl::Context *context)
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
renderer->releaseResource(*this, &mImage);
renderer->releaseResource(*this, &mDeviceMemory);
renderer->releaseResource(*this, &mImageView);
renderer->releaseResource(*this, &mSampler);
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
return gl::NoError();
}
......@@ -66,11 +66,11 @@ gl::Error TextureVk::setImage(const gl::Context *context,
if (desc.size != size ||
!gl::Format::SameSized(desc.format, gl::Format(internalFormat, type)))
{
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
renderer->releaseResource(*this, &mImage);
renderer->releaseResource(*this, &mDeviceMemory);
renderer->releaseResource(*this, &mImageView);
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
}
}
......
......@@ -1162,6 +1162,54 @@ TEST_P(SimpleStateChangeTest, ScissorTest)
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
}
// Tests that changing the storage of a Renderbuffer currently in use by GL works as expected.
TEST_P(SimpleStateChangeTest, RedefineRenderbufferInUse)
{
GLRenderbuffer renderbuffer;
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
ASSERT_GL_NO_ERROR();
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
ANGLE_GL_PROGRAM(program, kSimpleVertexShader, kSimpleFragmentShader);
GLint colorLoc = glGetAttribLocation(program, "color");
ASSERT_NE(-1, colorLoc);
// Set up and draw red to the left half the screen.
std::vector<GLColor> redData(6, GLColor::red);
GLBuffer vertexBufferRed;
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferRed);
glBufferData(GL_ARRAY_BUFFER, redData.size() * sizeof(GLColor), redData.data(), GL_STATIC_DRAW);
glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
glEnableVertexAttribArray(colorLoc);
glViewport(0, 0, 16, 16);
drawQuad(program, "position", 0.5f, 1.0f, true);
// Immediately redefine the Renderbuffer.
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 64, 64);
// Set up and draw green to the right half of the screen.
std::vector<GLColor> greenData(6, GLColor::green);
GLBuffer vertexBufferGreen;
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferGreen);
glBufferData(GL_ARRAY_BUFFER, greenData.size() * sizeof(GLColor), greenData.data(),
GL_STATIC_DRAW);
glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
glEnableVertexAttribArray(colorLoc);
glViewport(0, 0, 64, 64);
drawQuad(program, "position", 0.5f, 1.0f, true);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
} // anonymous namespace
ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());
......
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