blob: a2ede5a1eb581dff78f237b611662a8a259de9a7 [file] [log] [blame]
/*
* Copyright (c) 2015-2024 The Khronos Group Inc.
* Copyright (c) 2015-2024 Valve Corporation
* Copyright (c) 2015-2024 LunarG, Inc.
* Copyright (c) 2015-2024 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
#include "../framework/render_pass_helper.h"
#include "generated/vk_extension_helper.h"
void DynamicRenderingTest::InitBasicDynamicRenderingLocalRead() {
SetTargetApiVersion(VK_API_VERSION_1_2);
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::dynamicRendering);
AddRequiredFeature(vkt::Feature::dynamicRenderingLocalRead);
RETURN_IF_SKIP(Init());
}
TEST_F(PositiveDynamicRenderingLocalRead, BasicUsage) {
TEST_DESCRIPTION("Most simple way to use dynamic rendering local read");
AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::synchronization2);
RETURN_IF_SKIP(InitBasicDynamicRenderingLocalRead());
vkt::Image image1(*m_device, 32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
vkt::Image image2(*m_device, 32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
CreatePipelineHelper pipe1(*this);
CreatePipelineHelper pipe2(*this);
for (uint32_t i = 0; i < 2; i++)
{
CreatePipelineHelper* pipe = (i == 0) ? &pipe1 : &pipe2;
VkFormat color_formats[] = {VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED};
// Images mapped differently in pipe1 and pipe2
uint32_t locations[] = {i, 1 - i};
uint32_t inputs[] = {i, 1 - i};
VkRenderingInputAttachmentIndexInfoKHR inputs_info = vku::InitStructHelper();
inputs_info.colorAttachmentCount = 2;
inputs_info.pColorAttachmentInputIndices = inputs;
VkRenderingAttachmentLocationInfoKHR locations_info = vku::InitStructHelper(&inputs_info);
locations_info.colorAttachmentCount = 2;
locations_info.pColorAttachmentLocations = locations;
VkPipelineRenderingCreateInfoKHR pipeline_rendering_info = vku::InitStructHelper(&locations_info);
pipeline_rendering_info.colorAttachmentCount = 2;
pipeline_rendering_info.pColorAttachmentFormats = color_formats;
VkPipelineColorBlendAttachmentState cb_attachments[2];
memset(cb_attachments, 0, sizeof(VkPipelineColorBlendAttachmentState) * 2);
pipe->ds_ci_ = vku::InitStructHelper();
pipe->gp_ci_.pNext = &pipeline_rendering_info;
pipe->cb_ci_.attachmentCount = 2;
pipe->cb_ci_.pAttachments = cb_attachments;
pipe->CreateGraphicsPipeline();
}
VkRenderingAttachmentInfoKHR color_attachments[2] = {vku::InitStructHelper(), vku::InitStructHelper()};
color_attachments[0].imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
color_attachments[1].imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
VkRenderingInfoKHR begin_rendering_info = vku::InitStructHelper();
begin_rendering_info.colorAttachmentCount = 2;
begin_rendering_info.pColorAttachments = &color_attachments[0];
begin_rendering_info.layerCount = 1;
begin_rendering_info.renderArea = {{0, 0}, {1, 1}};
m_commandBuffer->begin();
VkImageMemoryBarrier pre_barriers[2] = {vku::InitStructHelper(), vku::InitStructHelper()};
pre_barriers[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
pre_barriers[0].srcAccessMask = 0;
pre_barriers[0].newLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
pre_barriers[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
pre_barriers[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
pre_barriers[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
pre_barriers[0].subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
pre_barriers[1] = pre_barriers[0];
pre_barriers[0].image = image1.handle();
pre_barriers[1].image = image2.handle();
VkImageMemoryBarrier post_barriers[2] = {pre_barriers[0], pre_barriers[1]};
post_barriers[0].oldLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
post_barriers[0].newLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
post_barriers[0].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
post_barriers[0].dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
post_barriers[1].oldLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
post_barriers[1].newLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
post_barriers[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
post_barriers[1].dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
vk::CmdPipelineBarrier(*m_commandBuffer, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 2, &pre_barriers[0]);
m_commandBuffer->BeginRendering(begin_rendering_info);
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1.Handle());
vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
vk::CmdPipelineBarrier(*m_commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 2, &post_barriers[0]);
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2.Handle());
uint32_t locations[] = {1, 0};
VkRenderingAttachmentLocationInfoKHR location_info = vku::InitStructHelper();
location_info.colorAttachmentCount = 2;
location_info.pColorAttachmentLocations = locations;
vk::CmdSetRenderingAttachmentLocationsKHR(m_commandBuffer->handle(), &location_info);
VkRenderingInputAttachmentIndexInfoKHR input_info = vku::InitStructHelper();
input_info.colorAttachmentCount = 2;
input_info.pColorAttachmentInputIndices = locations;
vk::CmdSetRenderingInputAttachmentIndicesKHR(m_commandBuffer->handle(), &input_info);
vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
m_commandBuffer->EndRendering();
m_commandBuffer->end();
}
TEST_F(PositiveDynamicRenderingLocalRead, CmdClearAttachments) {
TEST_DESCRIPTION("Clear color attachment");
RETURN_IF_SKIP(InitBasicDynamicRenderingLocalRead());
VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM;
VkPipelineRenderingCreateInfoKHR pipeline_rendering_info = vku::InitStructHelper();
pipeline_rendering_info.colorAttachmentCount = 1;
pipeline_rendering_info.pColorAttachmentFormats = &color_format;
CreatePipelineHelper pipe(*this, &pipeline_rendering_info);
pipe.gp_ci_.renderPass = VK_NULL_HANDLE;
pipe.CreateGraphicsPipeline();
VkRenderingAttachmentInfoKHR color_attachments[2];
color_attachments[0] = vku::InitStructHelper();
color_attachments[0].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
color_attachments[1] = vku::InitStructHelper();
color_attachments[1].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
m_commandBuffer->begin();
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.Handle());
VkRenderingInfo rendering_info = vku::InitStructHelper();
rendering_info.renderArea = {{0, 0}, {m_width, m_height}};
rendering_info.layerCount = 1;
rendering_info.colorAttachmentCount = 2;
rendering_info.pColorAttachments = color_attachments;
m_commandBuffer->BeginRendering(rendering_info);
uint32_t locations[2] = {0, VK_ATTACHMENT_UNUSED};
VkRenderingAttachmentLocationInfoKHR location_info = vku::InitStructHelper();
location_info.colorAttachmentCount = 2;
location_info.pColorAttachmentLocations = locations;
vk::CmdSetRenderingAttachmentLocationsKHR(m_commandBuffer->handle(), &location_info);
VkClearAttachment clear_attachment;
clear_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
clear_attachment.clearValue.color.float32[0] = 1.0;
clear_attachment.clearValue.color.float32[1] = 1.0;
clear_attachment.clearValue.color.float32[2] = 1.0;
clear_attachment.clearValue.color.float32[3] = 1.0;
clear_attachment.colorAttachment = 0;
VkClearRect clear_rect = {{{0, 0}, {m_width, m_height}}, 0, 1};
vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &clear_attachment, 1, &clear_rect);
}
TEST_F(PositiveDynamicRenderingLocalRead, CmdClearDepthAttachment) {
TEST_DESCRIPTION("Clear depth attachment.");
RETURN_IF_SKIP(InitBasicDynamicRenderingLocalRead());
const VkFormat ds_format = FindSupportedDepthStencilFormat(gpu());
vkt::Image depthImage(*m_device, 32, 32, 1, ds_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
vkt::ImageView depthImageView = depthImage.CreateView(VK_IMAGE_ASPECT_DEPTH_BIT);
VkClearValue clearValue;
clearValue.depthStencil.depth = 1.0f;
clearValue.depthStencil.stencil = 0u;
VkRenderingAttachmentInfo depthAttachment = vku::InitStructHelper();
depthAttachment.imageView = depthImageView;
depthAttachment.imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
depthAttachment.clearValue = clearValue;
VkRenderingInfo renderingInfo = vku::InitStructHelper();
renderingInfo.renderArea = {{0, 0}, {32u, 32u}};
renderingInfo.layerCount = 1u;
renderingInfo.pDepthAttachment = &depthAttachment;
VkRenderingAttachmentLocationInfoKHR locationInfo = vku::InitStructHelper();
locationInfo.colorAttachmentCount = 0u;
locationInfo.pColorAttachmentLocations = nullptr;
VkClearAttachment attachment;
attachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
attachment.colorAttachment = 0u;
attachment.clearValue = clearValue;
VkClearRect rect;
rect.rect = {{0, 0}, {32u, 32u}};
rect.baseArrayLayer = 0u;
rect.layerCount = 1u;
m_commandBuffer->begin();
m_commandBuffer->BeginRendering(renderingInfo);
vk::CmdSetRenderingAttachmentLocationsKHR(m_commandBuffer->handle(), &locationInfo);
vk::CmdClearAttachments(m_commandBuffer->handle(), 1u, &attachment, 1u, &rect);
m_commandBuffer->EndRendering();
m_commandBuffer->end();
}