blob: 55e602ee513641a5e0495b303293e013b0977085 [file] [log] [blame]
/*
* Copyright (c) 2015-2025 The Khronos Group Inc.
* Copyright (c) 2015-2025 Valve Corporation
* Copyright (c) 2015-2025 LunarG, Inc.
* Copyright (c) 2015-2025 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"
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());
}
class PositiveDynamicRenderingLocalRead : public DynamicRenderingTest {};
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, 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, 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};
VkRenderingInputAttachmentIndexInfo inputs_info = vku::InitStructHelper();
inputs_info.colorAttachmentCount = 2;
inputs_info.pColorAttachmentInputIndices = inputs;
VkRenderingAttachmentLocationInfo locations_info = vku::InitStructHelper(&inputs_info);
locations_info.colorAttachmentCount = 2;
locations_info.pColorAttachmentLocations = locations;
VkPipelineRenderingCreateInfo 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();
}
VkRenderingAttachmentInfo color_attachments[2] = {vku::InitStructHelper(), vku::InitStructHelper()};
color_attachments[0].imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ;
color_attachments[1].imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ;
VkRenderingInfo 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_command_buffer.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;
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;
pre_barriers[1].image = image2;
VkImageMemoryBarrier post_barriers[2] = {pre_barriers[0], pre_barriers[1]};
post_barriers[0].oldLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ;
post_barriers[0].newLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ;
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;
post_barriers[1].newLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ;
post_barriers[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
post_barriers[1].dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
vk::CmdPipelineBarrier(m_command_buffer, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0,
nullptr, 0, nullptr, 2, &pre_barriers[0]);
m_command_buffer.BeginRendering(begin_rendering_info);
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1);
vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
vk::CmdPipelineBarrier(m_command_buffer, 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_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2);
uint32_t locations[] = {1, 0};
VkRenderingAttachmentLocationInfo location_info = vku::InitStructHelper();
location_info.colorAttachmentCount = 2;
location_info.pColorAttachmentLocations = locations;
vk::CmdSetRenderingAttachmentLocationsKHR(m_command_buffer, &location_info);
VkRenderingInputAttachmentIndexInfo input_info = vku::InitStructHelper();
input_info.colorAttachmentCount = 2;
input_info.pColorAttachmentInputIndices = locations;
vk::CmdSetRenderingInputAttachmentIndicesKHR(m_command_buffer, &input_info);
vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
m_command_buffer.EndRendering();
m_command_buffer.End();
}
TEST_F(PositiveDynamicRenderingLocalRead, CmdClearAttachments) {
TEST_DESCRIPTION("Clear color attachment");
RETURN_IF_SKIP(InitBasicDynamicRenderingLocalRead());
VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM;
VkPipelineRenderingCreateInfo 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();
VkRenderingAttachmentInfo 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_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
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_command_buffer.BeginRendering(rendering_info);
uint32_t locations[2] = {0, VK_ATTACHMENT_UNUSED};
VkRenderingAttachmentLocationInfo location_info = vku::InitStructHelper();
location_info.colorAttachmentCount = 2;
location_info.pColorAttachmentLocations = locations;
vk::CmdSetRenderingAttachmentLocationsKHR(m_command_buffer, &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_command_buffer, 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, 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;
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;
VkRenderingAttachmentLocationInfo 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_command_buffer.Begin();
m_command_buffer.BeginRendering(renderingInfo);
vk::CmdSetRenderingAttachmentLocationsKHR(m_command_buffer, &locationInfo);
vk::CmdClearAttachments(m_command_buffer, 1u, &attachment, 1u, &rect);
m_command_buffer.EndRendering();
m_command_buffer.End();
}
TEST_F(PositiveDynamicRenderingLocalRead, PipelineBarrierAllowedImageLayouts) {
TEST_DESCRIPTION("Test restriction on image layouts when using image barrier inside dynamic render pass instance");
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredFeature(vkt::Feature::synchronization2);
RETURN_IF_SKIP(InitBasicDynamicRenderingLocalRead());
vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
vkt::ImageView image_view = image.CreateView();
VkImageMemoryBarrier2 layout_transition = vku::InitStructHelper();
layout_transition.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
layout_transition.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
layout_transition.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
layout_transition.newLayout = VK_IMAGE_LAYOUT_GENERAL; // GENERAL is one of the allowed layouts
layout_transition.image = image;
layout_transition.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper();
color_attachment.imageView = image_view;
color_attachment.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
VkRenderingInfo rendering_info = vku::InitStructHelper();
rendering_info.renderArea = {{0, 0}, {32, 32}};
rendering_info.layerCount = 1;
rendering_info.colorAttachmentCount = 1;
rendering_info.pColorAttachments = &color_attachment;
VkImageMemoryBarrier2 local_read_barrier = vku::InitStructHelper();
local_read_barrier.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
local_read_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
local_read_barrier.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
local_read_barrier.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
local_read_barrier.image = image;
local_read_barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
m_command_buffer.Begin();
// Transition attachment to GENERAL layout
m_command_buffer.Barrier(layout_transition);
m_command_buffer.BeginRendering(rendering_info);
// Image barrier inside dynamic render pass instance
m_command_buffer.Barrier(local_read_barrier);
m_command_buffer.EndRendering();
m_command_buffer.End();
}
TEST_F(PositiveDynamicRenderingLocalRead, PipelineBarrierAllowedImageLayouts2) {
TEST_DESCRIPTION("Test restriction on image layouts when using image barrier inside dynamic render pass instance");
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredFeature(vkt::Feature::synchronization2);
RETURN_IF_SKIP(InitBasicDynamicRenderingLocalRead());
vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
vkt::ImageView image_view = image.CreateView();
VkImageMemoryBarrier2 layout_transition = vku::InitStructHelper();
layout_transition.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
layout_transition.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
layout_transition.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
layout_transition.newLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ; // LOCAL_READ is one of the allowed layouts
layout_transition.image = image;
layout_transition.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper();
color_attachment.imageView = image_view;
color_attachment.imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ;
color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
VkRenderingInfo rendering_info = vku::InitStructHelper();
rendering_info.renderArea = {{0, 0}, {32, 32}};
rendering_info.layerCount = 1;
rendering_info.colorAttachmentCount = 1;
rendering_info.pColorAttachments = &color_attachment;
VkImageMemoryBarrier2 local_read_barrier = vku::InitStructHelper();
local_read_barrier.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
local_read_barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
local_read_barrier.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
local_read_barrier.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
// Layout transition is not allowed inside render pass instance.
// Set old and new layout to be equal to disable layout transition.
// Additionally use very spefic values (COLOR_ATTACHMENT_OPTIMAL) to test they are ignored.
local_read_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
local_read_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
local_read_barrier.image = image;
local_read_barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
m_command_buffer.Begin();
// Transition attachment to LOCAL_READ layout
m_command_buffer.Barrier(layout_transition);
m_command_buffer.BeginRendering(rendering_info);
// Image barrier inside dynamic render pass instance
m_command_buffer.Barrier(local_read_barrier);
m_command_buffer.EndRendering();
m_command_buffer.End();
}
TEST_F(PositiveDynamicRenderingLocalRead, NullColorAttachmentInputIndices) {
RETURN_IF_SKIP(InitBasicDynamicRenderingLocalRead());
InitDynamicRenderTarget();
m_command_buffer.Begin();
m_command_buffer.BeginRenderingColor(GetDynamicRenderTarget(), GetRenderTargetArea());
VkRenderingInputAttachmentIndexInfo input_info = vku::InitStructHelper();
input_info.colorAttachmentCount = 1u;
vk::CmdSetRenderingInputAttachmentIndicesKHR(m_command_buffer, &input_info);
m_command_buffer.EndRendering();
m_command_buffer.End();
}
TEST_F(PositiveDynamicRenderingLocalRead, LocationsInfoNullAttachments) {
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::dynamicRenderingLocalRead);
RETURN_IF_SKIP(InitBasicDynamicRendering());
InitRenderTarget();
vkt::Image image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
vkt::ImageView image_view = image.CreateView();
VkRenderingAttachmentInfo attachment;
attachment = vku::InitStructHelper();
attachment.imageView = image_view;
attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
VkRenderingInfo rendering_info = vku::InitStructHelper();
rendering_info.renderArea = {{0, 0}, {32u, 32u}};
rendering_info.layerCount = 1u;
rendering_info.colorAttachmentCount = 1u;
rendering_info.pColorAttachments = &attachment;
m_command_buffer.Begin();
vk::CmdBeginRenderingKHR(m_command_buffer, &rendering_info);
VkRenderingAttachmentLocationInfo location_info = vku::InitStructHelper();
location_info.colorAttachmentCount = 1u;
vk::CmdSetRenderingAttachmentLocationsKHR(m_command_buffer, &location_info);
vk::CmdEndRenderingKHR(m_command_buffer);
m_command_buffer.End();
}
TEST_F(PositiveDynamicRenderingLocalRead, GPL) {
AddRequiredExtensions(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::graphicsPipelineLibrary);
RETURN_IF_SKIP(InitBasicDynamicRenderingLocalRead());
VkFormat color_formats[] = {VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED};
uint32_t locations[] = {1, 0};
uint32_t inputs[] = {1, 0};
VkRenderingInputAttachmentIndexInfo inputs_info = vku::InitStructHelper();
inputs_info.colorAttachmentCount = 2;
inputs_info.pColorAttachmentInputIndices = inputs;
VkRenderingAttachmentLocationInfo locations_info = vku::InitStructHelper();
locations_info.colorAttachmentCount = 2;
locations_info.pColorAttachmentLocations = locations;
VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper(&locations_info);
pipeline_rendering_info.colorAttachmentCount = 2;
pipeline_rendering_info.pColorAttachmentFormats = color_formats;
std::vector<VkPipelineColorBlendAttachmentState> color_blend_attachments(2);
VkPipelineColorBlendStateCreateInfo cbi = vku::InitStructHelper();
cbi.attachmentCount = 2u;
cbi.pAttachments = color_blend_attachments.data();
vkt::PipelineLayout pipeline_layout(*m_device);
CreatePipelineHelper vertex_input_lib(*this);
vertex_input_lib.InitVertexInputLibInfo();
vertex_input_lib.CreateGraphicsPipeline(false);
CreatePipelineHelper pre_raster_lib(*this);
{
const auto vs_spv = GLSLToSPV(VK_SHADER_STAGE_VERTEX_BIT, kVertexMinimalGlsl);
vkt::GraphicsPipelineLibraryStage vs_stage(vs_spv, VK_SHADER_STAGE_VERTEX_BIT);
pre_raster_lib.InitPreRasterLibInfo(&vs_stage.stage_ci);
pre_raster_lib.gp_ci_.layout = pipeline_layout;
pre_raster_lib.CreateGraphicsPipeline(false);
}
CreatePipelineHelper frag_shader_lib(*this);
{
VkStencilOpState stencil = {};
stencil.failOp = VK_STENCIL_OP_KEEP;
stencil.passOp = VK_STENCIL_OP_KEEP;
stencil.depthFailOp = VK_STENCIL_OP_KEEP;
stencil.compareOp = VK_COMPARE_OP_NEVER;
VkPipelineDepthStencilStateCreateInfo ds_ci = vku::InitStructHelper();
ds_ci.depthTestEnable = VK_FALSE;
ds_ci.depthWriteEnable = VK_TRUE;
ds_ci.depthCompareOp = VK_COMPARE_OP_NEVER;
ds_ci.depthBoundsTestEnable = VK_FALSE;
ds_ci.stencilTestEnable = VK_TRUE;
ds_ci.front = stencil;
ds_ci.back = stencil;
const auto fs_spv = GLSLToSPV(VK_SHADER_STAGE_FRAGMENT_BIT, kFragmentMinimalGlsl);
vkt::GraphicsPipelineLibraryStage fs_stage(fs_spv, VK_SHADER_STAGE_FRAGMENT_BIT);
frag_shader_lib.InitFragmentLibInfo(&fs_stage.stage_ci, &inputs_info);
frag_shader_lib.gp_ci_.layout = pipeline_layout;
frag_shader_lib.gp_ci_.pDepthStencilState = &ds_ci;
frag_shader_lib.CreateGraphicsPipeline(false);
}
CreatePipelineHelper frag_out_lib(*this);
frag_out_lib.InitFragmentOutputLibInfo(&pipeline_rendering_info);
frag_out_lib.gp_ci_.pColorBlendState = &cbi;
frag_out_lib.CreateGraphicsPipeline(false);
VkPipeline libraries[4] = {
vertex_input_lib,
pre_raster_lib,
frag_shader_lib,
frag_out_lib,
};
VkPipelineLibraryCreateInfoKHR link_info = vku::InitStructHelper();
link_info.libraryCount = size32(libraries);
link_info.pLibraries = libraries;
VkGraphicsPipelineCreateInfo exe_pipe_ci = vku::InitStructHelper(&link_info);
exe_pipe_ci.layout = pipeline_layout;
vkt::Pipeline exe_pipe(*m_device, exe_pipe_ci);
VkRenderingAttachmentInfo color_attachment[2] = {vku::InitStructHelper(), vku::InitStructHelper()};
color_attachment[0].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
color_attachment[1].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
m_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, exe_pipe);
VkRenderingInfo rendering_info = vku::InitStructHelper();
rendering_info.renderArea = {{0, 0}, {32, 32}};
rendering_info.layerCount = 1;
rendering_info.colorAttachmentCount = 2;
rendering_info.pColorAttachments = &color_attachment[0];
m_command_buffer.BeginRendering(rendering_info);
vk::CmdSetRenderingAttachmentLocationsKHR(m_command_buffer, &locations_info);
vk::CmdSetRenderingInputAttachmentIndicesKHR(m_command_buffer, &inputs_info);
vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
}
TEST_F(PositiveDynamicRenderingLocalRead, CmdDrawColorIndexUnusedAttachment) {
TEST_DESCRIPTION("Validate that mapping is not applied in CmdDraw call if rendering is not started by vkCmdBeginRendering");
RETURN_IF_SKIP(InitBasicDynamicRenderingLocalRead());
VkFormat color_formats[] = {VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED};
VkPipelineRenderingCreateInfo pipeline_rendering_info = vku::InitStructHelper();
pipeline_rendering_info.colorAttachmentCount = 2;
pipeline_rendering_info.pColorAttachmentFormats = color_formats;
std::vector<VkPipelineColorBlendAttachmentState> color_blend_attachments(2);
VkPipelineColorBlendStateCreateInfo cbi = vku::InitStructHelper();
cbi.attachmentCount = 2u;
cbi.pAttachments = color_blend_attachments.data();
CreatePipelineHelper pipe(*this, &pipeline_rendering_info);
pipe.gp_ci_.renderPass = VK_NULL_HANDLE;
pipe.gp_ci_.pColorBlendState = &cbi;
pipe.CreateGraphicsPipeline();
VkRenderingAttachmentInfo color_attachment[2] = {vku::InitStructHelper(), vku::InitStructHelper()};
color_attachment[0].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
color_attachment[1].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
m_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
VkRenderingInfo rendering_info = vku::InitStructHelper();
rendering_info.renderArea = {{0, 0}, {32, 32}};
rendering_info.layerCount = 1;
rendering_info.colorAttachmentCount = 2;
rendering_info.pColorAttachments = &color_attachment[0];
m_command_buffer.BeginRendering(rendering_info);
uint32_t input_indices[] = {VK_ATTACHMENT_UNUSED, VK_ATTACHMENT_UNUSED};
VkRenderingInputAttachmentIndexInfo input_attachment_index_info = vku::InitStructHelper();
input_attachment_index_info.colorAttachmentCount = 2u;
input_attachment_index_info.pColorAttachmentInputIndices = input_indices;
vk::CmdSetRenderingInputAttachmentIndicesKHR(m_command_buffer, &input_attachment_index_info);
vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
m_command_buffer.EndRendering();
m_command_buffer.End();
}