blob: 9728448ff3cf7bb6c686c766e82ad4dd93f0a322 [file] [log] [blame]
/*
* Copyright (c) 2015-2022 The Khronos Group Inc.
* Copyright (c) 2015-2022 Valve Corporation
* Copyright (c) 2015-2022 LunarG, Inc.
* Copyright (c) 2015-2022 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
*
* Author: Chia-I Wu <olvaffe@gmail.com>
* Author: Chris Forbes <chrisf@ijw.co.nz>
* Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
* Author: Mark Lobodzinski <mark@lunarg.com>
* Author: Mike Stroyan <mike@LunarG.com>
* Author: Tobin Ehlis <tobine@google.com>
* Author: Tony Barbour <tony@LunarG.com>
* Author: Cody Northrop <cnorthrop@google.com>
* Author: Dave Houlton <daveh@lunarg.com>
* Author: Jeremy Kniager <jeremyk@lunarg.com>
* Author: Shannon McPherson <shannon@lunarg.com>
* Author: John Zulauf <jzulauf@lunarg.com>
*/
#include "../layer_validation_tests.h"
#include "vk_extension_helper.h"
#include <algorithm>
#include <array>
#include <chrono>
#include <memory>
#include <mutex>
#include <thread>
#include "cast_utils.h"
TEST_F(VkPositiveLayerTest, DynamicRenderingDraw) {
TEST_DESCRIPTION("Draw with Dynamic Rendering.");
m_errorMonitor->ExpectSuccess();
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
ASSERT_NO_FATAL_FAILURE(InitFramework());
if (!AreRequestedExtensionsEnabled()) {
printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
return;
}
if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
printf("%s Tests requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
return;
}
auto dynamic_rendering_features = LvlInitStruct<VkPhysicalDeviceDynamicRenderingFeaturesKHR>();
auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&dynamic_rendering_features);
vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
if (!dynamic_rendering_features.dynamicRendering) {
printf("%s Test requires (unsupported) dynamicRendering , skipping\n", kSkipPrefix);
return;
}
ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
char const* fsSource = R"glsl(
#version 450
layout(location=0) out vec4 color;
void main() {
color = vec4(1.0f);
}
)glsl";
VkShaderObj vs(this, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT);
VkShaderObj fs(this, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);
VkPipelineObj pipe(m_device);
pipe.AddShader(&vs);
pipe.AddShader(&fs);
pipe.AddDefaultColorAttachment();
VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
const VkPipelineLayoutObj pl(m_device, {&dsl});
VkFormat color_formats = {VK_FORMAT_R8G8B8A8_UNORM};
auto pipeline_rendering_info = LvlInitStruct<VkPipelineRenderingCreateInfoKHR>();
pipeline_rendering_info.colorAttachmentCount = 1;
pipeline_rendering_info.pColorAttachmentFormats = &color_formats;
auto create_info = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
pipe.InitGraphicsPipelineCreateInfo(&create_info);
create_info.pNext = &pipeline_rendering_info;
pipe.CreateVKPipeline(pl.handle(), VK_NULL_HANDLE, &create_info);
m_errorMonitor->VerifyNotFound();
m_errorMonitor->ExpectSuccess();
VkViewport viewport = {0, 0, 16, 16, 0, 1};
VkRect2D scissor = {{0, 0}, {16, 16}};
VkRenderingAttachmentInfoKHR color_attachment = LvlInitStruct<VkRenderingAttachmentInfoKHR>();
color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkRenderingInfoKHR begin_rendering_info = LvlInitStruct<VkRenderingInfoKHR>();
begin_rendering_info.colorAttachmentCount = 1;
begin_rendering_info.pColorAttachments = &color_attachment;
begin_rendering_info.layerCount = 1;
m_commandBuffer->begin();
m_commandBuffer->BeginRendering(begin_rendering_info);
vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
m_commandBuffer->EndRendering();
m_commandBuffer->end();
m_errorMonitor->VerifyNotFound();
}
TEST_F(VkPositiveLayerTest, CmdClearAttachmentTestsDynamicRendering) {
TEST_DESCRIPTION("Various tests for validating usage of vkCmdClearAttachments with Dynamic Rendering");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
ASSERT_NO_FATAL_FAILURE(InitFramework());
if (!AreRequestedExtensionsEnabled()) {
printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
return;
}
if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
printf("%s Tests requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
return;
}
m_errorMonitor->ExpectSuccess();
auto dynamic_rendering_features = LvlInitStruct<VkPhysicalDeviceDynamicRenderingFeaturesKHR>();
auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&dynamic_rendering_features);
vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
if (!dynamic_rendering_features.dynamicRendering) {
printf("%s Test requires (unsupported) dynamicRendering , skipping\n", kSkipPrefix);
return;
}
ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
m_commandBuffer->begin();
// Main thing we care about for this test is that the VkImage obj we're
// clearing matches Color Attachment of FB
// Also pass down other dummy params to keep driver and paramchecker happy
VkClearAttachment color_attachment;
color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
color_attachment.clearValue.color.float32[0] = 1.0;
color_attachment.clearValue.color.float32[1] = 1.0;
color_attachment.clearValue.color.float32[2] = 1.0;
color_attachment.clearValue.color.float32[3] = 1.0;
color_attachment.colorAttachment = 0;
VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
clear_rect.rect.extent.width = renderPassBeginInfo().renderArea.extent.width + 4;
clear_rect.rect.extent.height = clear_rect.rect.extent.height / 2;
VkRenderingInfoKHR begin_rendering_info = LvlInitStruct<VkRenderingInfoKHR>();
begin_rendering_info.renderArea = clear_rect.rect;
begin_rendering_info.layerCount = 1;
m_commandBuffer->BeginRendering(begin_rendering_info);
vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
// baseLayer >= view layers
clear_rect.rect.extent.width = (uint32_t)m_width;
clear_rect.baseArrayLayer = 1;
clear_rect.layerCount = 1;
vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
// baseLayer + layerCount > view layers
clear_rect.rect.extent.width = (uint32_t)m_width;
clear_rect.baseArrayLayer = 0;
clear_rect.layerCount = 2;
vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
m_commandBuffer->EndRendering();
m_commandBuffer->end();
m_errorMonitor->VerifyNotFound();
}
TEST_F(VkPositiveLayerTest, TestBeginQueryInDynamicRendering) {
TEST_DESCRIPTION("Test calling vkCmdBeginQuery with a dynamic render pass.");
SetTargetApiVersion(VK_API_VERSION_1_3);
ASSERT_NO_FATAL_FAILURE(InitFramework());
if (DeviceValidationVersion() < VK_API_VERSION_1_3) {
printf("%s Tests requires Vulkan 1.3+, skipping test\n", kSkipPrefix);
return;
}
auto vk13features = LvlInitStruct<VkPhysicalDeviceVulkan13Features>();
auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&vk13features);
vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
if (!vk13features.dynamicRendering) {
printf("%s Test requires (unsupported) dynamicRendering, skipping\n", kSkipPrefix);
return;
}
if (!vk13features.synchronization2) {
printf("%s Test requires (unsupported) synchronization2, skipping\n", kSkipPrefix);
return;
}
ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
PFN_vkCmdBeginRendering vkCmdBeginRendering =
reinterpret_cast<PFN_vkCmdBeginRendering>(vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginRendering"));
assert(vkCmdBeginRendering != nullptr);
PFN_vkCmdEndRendering vkCmdEndRendering =
reinterpret_cast<PFN_vkCmdEndRendering>(vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndRendering"));
assert(vkCmdEndRendering != nullptr);
m_errorMonitor->ExpectSuccess();
VkRenderingInfoKHR begin_rendering_info = LvlInitStruct<VkRenderingInfoKHR>();
begin_rendering_info.layerCount = 1;
VkQueryPoolCreateInfo qpci = LvlInitStruct<VkQueryPoolCreateInfo>();
qpci.queryType = VK_QUERY_TYPE_OCCLUSION;
qpci.queryCount = 2;
vk_testing::QueryPool query_pool;
query_pool.init(*m_device, qpci);
m_commandBuffer->begin();
vkCmdBeginRendering(m_commandBuffer->handle(), &begin_rendering_info);
vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool.handle(), 0, 0);
vk::CmdEndQuery(m_commandBuffer->handle(), query_pool.handle(), 0);
vkCmdEndRendering(m_commandBuffer->handle());
m_commandBuffer->end();
m_errorMonitor->VerifyNotFound();
}
TEST_F(VkPositiveLayerTest, DynamicRenderingPipeWithDiscard) {
TEST_DESCRIPTION("Create dynamic rendering pipeline with rasterizer discard.");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
ASSERT_NO_FATAL_FAILURE(InitFramework());
if (!AreRequestedExtensionsEnabled()) {
printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
return;
}
if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
printf("%s Tests requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
return;
}
m_errorMonitor->ExpectSuccess();
auto dynamic_rendering_features = LvlInitStruct<VkPhysicalDeviceDynamicRenderingFeaturesKHR>();
auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&dynamic_rendering_features);
vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
if (!dynamic_rendering_features.dynamicRendering) {
printf("%s Test requires (unsupported) dynamicRendering , skipping\n", kSkipPrefix);
return;
}
ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
VkShaderObj vs(this, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT);
VkShaderObj fs(this, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT);
VkPipelineRasterizationStateCreateInfo rs_ci = LvlInitStruct<VkPipelineRasterizationStateCreateInfo>();
rs_ci.rasterizerDiscardEnable = VK_TRUE;
rs_ci.lineWidth = 1.0f;
VkPipelineDepthStencilStateCreateInfo ds_ci = LvlInitStruct<VkPipelineDepthStencilStateCreateInfo>();
ds_ci.depthTestEnable = VK_TRUE;
ds_ci.depthWriteEnable = VK_TRUE;
VkPipelineObj pipe(m_device);
pipe.AddShader(&vs);
pipe.AddShader(&fs);
pipe.AddDefaultColorAttachment();
pipe.SetDepthStencil(&ds_ci);
pipe.SetRasterization(&rs_ci);
VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
const VkPipelineLayoutObj pl(m_device, {&dsl});
auto create_info = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
pipe.InitGraphicsPipelineCreateInfo(&create_info);
create_info.layout = pl.handle();
create_info.renderPass = VK_NULL_HANDLE;
VkFormat color_formats = {VK_FORMAT_R8G8B8A8_UNORM};
auto pipeline_rendering_info = LvlInitStruct<VkPipelineRenderingCreateInfoKHR>();
pipeline_rendering_info.colorAttachmentCount = 1;
pipeline_rendering_info.pColorAttachmentFormats = &color_formats;
pipeline_rendering_info.depthAttachmentFormat = VK_FORMAT_D16_UNORM; // D16_UNORM has guaranteed support
pipeline_rendering_info.pNext = create_info.pNext;
create_info.pNext = &pipeline_rendering_info;
const VkRenderPass render_pass = VK_NULL_HANDLE;
pipe.CreateVKPipeline(pl.handle(), render_pass, &create_info);
m_errorMonitor->VerifyNotFound();
}