blob: c50d69d8c0bf17d8fcee5313be38cf4a8268b273 [file] [log] [blame]
/*
* Copyright (c) 2024 The Khronos Group Inc.
* Copyright (c) 2024 Valve Corporation
* Copyright (c) 2024 LunarG, 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"
class NegativeDebugPrintfShaderDebugInfo : public DebugPrintfTests {};
// These tests print out the verbose info to make sure that info is correct
static const VkBool32 verbose_value = true;
static const VkLayerSettingEXT layer_setting = {OBJECT_LAYER_NAME, "printf_verbose", VK_LAYER_SETTING_TYPE_BOOL32_EXT, 1,
&verbose_value};
static VkLayerSettingsCreateInfoEXT layer_settings_create_info = {VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT, nullptr, 1,
&layer_setting};
TEST_F(NegativeDebugPrintfShaderDebugInfo, PipelineHandle) {
TEST_DESCRIPTION("Make sure we are printing out which pipeline the error is from");
AddRequiredExtensions(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
char const *shader_source = R"glsl(
#version 450
#extension GL_EXT_debug_printf : enable
void main() {
float myfloat = 3.1415f;
debugPrintfEXT("float == %f", myfloat);
}
)glsl";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = std::make_unique<VkShaderObj>(this, shader_source, VK_SHADER_STAGE_COMPUTE_BIT);
pipe.CreateComputePipeline();
const char *object_name = "bad_pipeline";
VkDebugUtilsObjectNameInfoEXT name_info = vku::InitStructHelper();
name_info.objectType = VK_OBJECT_TYPE_PIPELINE;
name_info.objectHandle = (uint64_t)pipe.Handle();
name_info.pObjectName = object_name;
vk::SetDebugUtilsObjectNameEXT(device(), &name_info);
m_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.Handle());
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
m_command_buffer.End();
m_errorMonitor->SetDesiredInfo("Pipeline (bad_pipeline)");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeDebugPrintfShaderDebugInfo, ShaderObjectHandle) {
TEST_DESCRIPTION("Make sure we are printing out which shader object the error is from");
AddRequiredExtensions(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
AddRequiredExtensions(VK_EXT_SHADER_OBJECT_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::shaderObject);
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
char const *shader_source = R"glsl(
#version 450
#extension GL_EXT_debug_printf : enable
void main() {
float myfloat = 3.1415f;
debugPrintfEXT("float == %f", myfloat);
}
)glsl";
VkShaderStageFlagBits shader_stages[] = {VK_SHADER_STAGE_COMPUTE_BIT};
const vkt::Shader comp_shader(*m_device, shader_stages[0], GLSLToSPV(shader_stages[0], shader_source));
const char *object_name = "bad_shader_object";
VkDebugUtilsObjectNameInfoEXT name_info = vku::InitStructHelper();
name_info.objectType = VK_OBJECT_TYPE_SHADER_EXT;
name_info.objectHandle = (uint64_t)comp_shader.handle();
name_info.pObjectName = object_name;
vk::SetDebugUtilsObjectNameEXT(device(), &name_info);
m_command_buffer.Begin();
vk::CmdBindShadersEXT(m_command_buffer.handle(), 1, shader_stages, &comp_shader.handle());
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
m_command_buffer.End();
m_errorMonitor->SetDesiredInfo("Shader Object (bad_shader_object)");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeDebugPrintfShaderDebugInfo, OpLine) {
TEST_DESCRIPTION("Make sure OpLine works");
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
char const *shader_source = R"(
OpCapability Shader
OpExtension "SPV_KHR_non_semantic_info"
%2 = OpExtInstImport "GLSL.std.450"
%13 = OpExtInstImport "NonSemantic.DebugPrintf"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%1 = OpString "a.comp"
%11 = OpString "float == %f"
OpSource GLSL 450 %1 "// OpModuleProcessed client vulkan100
// OpModuleProcessed target-env vulkan1.0
// OpModuleProcessed entry-point main
#line 1
#version 450
#extension GL_EXT_debug_printf : enable
void main() {
float myfloat = 3.1415f;
debugPrintfEXT(\"float == %f\", myfloat);
}"
%void = OpTypeVoid
%4 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Function_float = OpTypePointer Function %float
%float_3_1415 = OpConstant %float 3.1415
OpLine %1 3 11
%main = OpFunction %void None %4
%6 = OpLabel
%myfloat = OpVariable %_ptr_Function_float Function
OpLine %1 4 0
OpStore %myfloat %float_3_1415
OpLine %1 5 0
%12 = OpLoad %float %myfloat
%14 = OpExtInst %void %13 1 %11 %12
OpReturn
OpFunctionEnd
)";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = std::make_unique<VkShaderObj>(this, shader_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);
pipe.CreateComputePipeline();
m_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.Handle());
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
m_command_buffer.End();
m_errorMonitor->SetDesiredFailureMsg(
kInformationBit,
"Debug shader printf message generated in file a.comp at line 5\n\n5: debugPrintfEXT(\"float == %f\", myfloat);");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeDebugPrintfShaderDebugInfo, ShaderDebugInfoDebugLine) {
TEST_DESCRIPTION("Make sure DebugLine works");
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
// Manually ran:
// glslangValidator -V -gVS in.comp -o out.spv --target-env vulkan1.0
char const *shader_source = R"(
OpCapability Shader
OpExtension "SPV_KHR_non_semantic_info"
%1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
%3 = OpExtInstImport "GLSL.std.450"
%44 = OpExtInstImport "NonSemantic.DebugPrintf"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%2 = OpString "a.comp"
%8 = OpString "uint"
%16 = OpString "main"
%19 = OpString "#version 450
#extension GL_EXT_debug_printf : enable
void main() {
float myfloat = 3.1415f;
debugPrintfEXT(\"float == %f\", myfloat);
}"
%28 = OpString "float"
%35 = OpString "myfloat"
%40 = OpString "float == %f"
OpSourceExtension "GL_EXT_debug_printf"
OpName %main "main"
OpName %myfloat "myfloat"
%void = OpTypeVoid
%5 = OpTypeFunction %void
%uint = OpTypeInt 32 0
%uint_32 = OpConstant %uint 32
%uint_6 = OpConstant %uint 6
%uint_0 = OpConstant %uint 0
%9 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 %uint_6 %uint_0
%uint_3 = OpConstant %uint 3
%6 = OpExtInst %void %1 DebugTypeFunction %uint_3 %void
%18 = OpExtInst %void %1 DebugSource %2 %19
%uint_1 = OpConstant %uint 1
%uint_4 = OpConstant %uint 4
%uint_2 = OpConstant %uint 2
%20 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %18 %uint_2
%17 = OpExtInst %void %1 DebugFunction %16 %6 %18 %uint_3 %uint_0 %20 %16 %uint_3 %uint_3
%float = OpTypeFloat 32
%29 = OpExtInst %void %1 DebugTypeBasic %28 %uint_32 %uint_3 %uint_0
%_ptr_Function_float = OpTypePointer Function %float
%uint_7 = OpConstant %uint 7
%32 = OpExtInst %void %1 DebugTypePointer %29 %uint_7 %uint_0
%34 = OpExtInst %void %1 DebugLocalVariable %35 %29 %18 %uint_4 %uint_0 %17 %uint_4
%37 = OpExtInst %void %1 DebugExpression
%float_3_1415 = OpConstant %float 3.1415
%uint_5 = OpConstant %uint 5
%main = OpFunction %void None %5
%15 = OpLabel
%myfloat = OpVariable %_ptr_Function_float Function
%25 = OpExtInst %void %1 DebugScope %17
%26 = OpExtInst %void %1 DebugLine %18 %uint_3 %uint_3 %uint_0 %uint_0
%24 = OpExtInst %void %1 DebugFunctionDefinition %17 %main
%38 = OpExtInst %void %1 DebugLine %18 %uint_4 %uint_4 %uint_0 %uint_0
%36 = OpExtInst %void %1 DebugDeclare %34 %myfloat %37
OpStore %myfloat %float_3_1415
%42 = OpExtInst %void %1 DebugLine %18 %uint_5 %uint_5 %uint_0 %uint_0
%41 = OpLoad %float %myfloat
%45 = OpExtInst %void %44 1 %40 %41
%46 = OpExtInst %void %1 DebugLine %18 %uint_6 %uint_6 %uint_0 %uint_0
OpReturn
OpFunctionEnd
)";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = std::make_unique<VkShaderObj>(this, shader_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);
pipe.CreateComputePipeline();
m_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.Handle());
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
m_command_buffer.End();
m_errorMonitor->SetDesiredFailureMsg(
kInformationBit,
"Debug shader printf message generated in file a.comp at line 5\n\n5: debugPrintfEXT(\"float == %f\", myfloat);");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeDebugPrintfShaderDebugInfo, CommandBufferCommandIndex) {
TEST_DESCRIPTION("Make sure we print which index in the command buffer the issue occured");
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
char const *shader_source = R"glsl(
#version 450
#extension GL_EXT_debug_printf : enable
void main() {
float myfloat = 3.1415f;
debugPrintfEXT("float == %f", myfloat);
}
)glsl";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = std::make_unique<VkShaderObj>(this, shader_source, VK_SHADER_STAGE_COMPUTE_BIT);
pipe.CreateComputePipeline();
CreateComputePipelineHelper empty_pipe(*this);
empty_pipe.CreateComputePipeline();
m_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, empty_pipe.Handle());
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.Handle());
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
m_command_buffer.End();
m_errorMonitor->SetDesiredInfo("Compute Dispatch Index 3");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeDebugPrintfShaderDebugInfo, CommandBufferCommandIndexMulti) {
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
char const *shader_source = R"glsl(
#version 450
#extension GL_EXT_debug_printf : enable
layout(push_constant) uniform PushConstants { int x; } pc;
void main() {
if (pc.x > 0) {
debugPrintfEXT("int == %u", pc.x);
}
}
)glsl";
VkPushConstantRange pc_range = {VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t)};
VkPipelineLayoutCreateInfo pipe_layout_ci = vku::InitStructHelper();
pipe_layout_ci.pushConstantRangeCount = 1;
pipe_layout_ci.pPushConstantRanges = &pc_range;
vkt::PipelineLayout pipeline_layout(*m_device, pipe_layout_ci);
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = std::make_unique<VkShaderObj>(this, shader_source, VK_SHADER_STAGE_COMPUTE_BIT);
pipe.cp_ci_.layout = pipeline_layout.handle();
pipe.CreateComputePipeline();
vkt::CommandBuffer cb0(*m_device, m_command_pool);
vkt::CommandBuffer cb1(*m_device, m_command_pool);
uint32_t skip = 0;
uint32_t good = 4;
cb0.Begin();
vk::CmdBindPipeline(cb0.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.Handle());
vk::CmdPushConstants(cb0.handle(), pipeline_layout.handle(), VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &skip);
vk::CmdDispatch(cb0.handle(), 1, 1, 1);
vk::CmdDispatch(cb0.handle(), 1, 1, 1);
vk::CmdDispatch(cb0.handle(), 1, 1, 1);
vk::CmdPushConstants(cb0.handle(), pipeline_layout.handle(), VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &good);
vk::CmdDispatch(cb0.handle(), 1, 1, 1);
vk::CmdPushConstants(cb0.handle(), pipeline_layout.handle(), VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &skip);
vk::CmdDispatch(cb0.handle(), 1, 1, 1);
cb0.End();
cb1.Begin();
vk::CmdBindPipeline(cb1.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.Handle());
vk::CmdPushConstants(cb1.handle(), pipeline_layout.handle(), VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &good);
vk::CmdDispatch(cb1.handle(), 1, 1, 1);
vk::CmdPushConstants(cb1.handle(), pipeline_layout.handle(), VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &skip);
vk::CmdDispatch(cb1.handle(), 1, 1, 1);
cb1.End();
m_errorMonitor->SetDesiredInfo("Compute Dispatch Index 3"); // cb0
m_errorMonitor->SetDesiredInfo("Compute Dispatch Index 0"); // cb1
VkCommandBuffer cbs[2] = {cb0.handle(), cb1.handle()};
VkSubmitInfo submit = vku::InitStructHelper();
submit.commandBufferCount = 2;
submit.pCommandBuffers = cbs;
vk::QueueSubmit(m_default_queue->handle(), 1, &submit, VK_NULL_HANDLE);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeDebugPrintfShaderDebugInfo, StageInfo) {
TEST_DESCRIPTION("Make sure we print the stage info correctly");
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
char const *shader_source = R"glsl(
#version 450
#extension GL_EXT_debug_printf : enable
void main() {
float myfloat = 3.1415f;
if (gl_GlobalInvocationID.x == 3 && gl_GlobalInvocationID.y == 1) {
debugPrintfEXT("float == %f", myfloat);
}
}
)glsl";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = std::make_unique<VkShaderObj>(this, shader_source, VK_SHADER_STAGE_COMPUTE_BIT);
pipe.CreateComputePipeline();
CreateComputePipelineHelper empty_pipe(*this);
empty_pipe.CreateComputePipeline();
m_command_buffer.Begin();
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.Handle());
vk::CmdDispatch(m_command_buffer.handle(), 4, 4, 1);
m_command_buffer.End();
m_errorMonitor->SetDesiredInfo("Global invocation ID (x, y, z) = (3, 1, 0)");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeDebugPrintfShaderDebugInfo, Fragment) {
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
InitRenderTarget();
char const *shader_source = R"glsl(
#version 450
#extension GL_EXT_debug_printf : enable
layout(location = 0) out vec4 outColor;
void main() {
if (gl_FragCoord.x > 10 && gl_FragCoord.x < 11) {
if (gl_FragCoord.y > 10 && gl_FragCoord.y < 12) {
debugPrintfEXT("gl_FragCoord.xy %1.2f, %1.2f\n", gl_FragCoord.x, gl_FragCoord.y);
}
}
outColor = gl_FragCoord;
}
)glsl";
VkShaderObj vs(this, kVertexDrawPassthroughGlsl, VK_SHADER_STAGE_VERTEX_BIT);
VkShaderObj fs(this, shader_source, VK_SHADER_STAGE_FRAGMENT_BIT);
CreatePipelineHelper pipe(*this);
pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
pipe.CreateGraphicsPipeline();
m_command_buffer.Begin();
m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.Handle());
vk::CmdDraw(m_command_buffer.handle(), 3, 1, 0, 0);
m_command_buffer.EndRenderPass();
m_command_buffer.End();
m_errorMonitor->SetDesiredInfo("Stage = Fragment. Fragment coord (x,y) = (10.5, 10.5)");
m_errorMonitor->SetDesiredInfo("Stage = Fragment. Fragment coord (x,y) = (10.5, 11.5)");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
TEST_F(NegativeDebugPrintfShaderDebugInfo, VertexFragmentMultiEntrypoint) {
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
InitRenderTarget();
// void vert_main() {
// gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);
// }
// layout(location = 0) out vec4 c_out;
// void frag_main() {
// debugPrintfEXT("Fragment value is %i", 8);
// c_out = vec4(0.0);
// }
const char *shader_source = R"(
OpCapability Shader
OpExtension "SPV_KHR_non_semantic_info"
%9 = OpExtInstImport "NonSemantic.DebugPrintf"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %frag_main "frag_main" %c_out
OpEntryPoint Vertex %vert_main "vert_main" %_ %gl_VertexIndex
OpExecutionMode %frag_main OriginUpperLeft
%frag_str = OpString "Fragment value is %i"
OpDecorate %c_out Location 0
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
OpDecorate %gl_PerVertex Block
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
%void = OpTypeVoid
%3 = OpTypeFunction %void
%int = OpTypeInt 32 1
%int_8 = OpConstant %int 8
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
%_arr_float_uint_1 = OpTypeArray %float %uint_1
%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
%_ = OpVariable %_ptr_Output_gl_PerVertex Output
%int_0 = OpConstant %int 0
%v2float = OpTypeVector %float 2
%uint_3 = OpConstant %uint 3
%_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3
%float_n1 = OpConstant %float -1
%24 = OpConstantComposite %v2float %float_n1 %float_n1
%float_1 = OpConstant %float 1
%26 = OpConstantComposite %v2float %float_1 %float_n1
%float_0 = OpConstant %float 0
%28 = OpConstantComposite %v2float %float_0 %float_1
%29 = OpConstantComposite %_arr_v2float_uint_3 %24 %26 %28
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
%int_3 = OpConstant %int 3
%_ptr_Function__arr_v2float_uint_3 = OpTypePointer Function %_arr_v2float_uint_3
%_ptr_Function_v2float = OpTypePointer Function %v2float
%_ptr_Output_v4float = OpTypePointer Output %v4float
%c_out = OpVariable %_ptr_Output_v4float Output
%16 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
%vert_main = OpFunction %void None %3
%5 = OpLabel
%indexable = OpVariable %_ptr_Function__arr_v2float_uint_3 Function
%32 = OpLoad %int %gl_VertexIndex
%34 = OpSMod %int %32 %int_3
OpStore %indexable %29
%38 = OpAccessChain %_ptr_Function_v2float %indexable %34
%39 = OpLoad %v2float %38
%40 = OpCompositeExtract %float %39 0
%41 = OpCompositeExtract %float %39 1
%42 = OpCompositeConstruct %v4float %40 %41 %float_0 %float_1
%44 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %44 %42
OpReturn
OpFunctionEnd
%frag_main = OpFunction %void None %3
%f5 = OpLabel
%f10 = OpExtInst %void %9 1 %frag_str %int_8
OpStore %c_out %16
OpReturn
OpFunctionEnd
)";
VkShaderObj vs(this, shader_source, VK_SHADER_STAGE_VERTEX_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM, nullptr, "vert_main");
VkShaderObj fs(this, shader_source, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM, nullptr, "frag_main");
VkViewport viewport = {0, 0, 1, 1, 0, 1};
VkRect2D scissor = {{0, 0}, {1, 1}};
CreatePipelineHelper pipe(*this);
pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
pipe.vp_state_ci_.pViewports = &viewport;
pipe.vp_state_ci_.pScissors = &scissor;
pipe.CreateGraphicsPipeline();
m_command_buffer.Begin();
m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.Handle());
vk::CmdDraw(m_command_buffer.handle(), 3, 1, 0, 0);
m_command_buffer.EndRenderPass();
m_command_buffer.End();
m_errorMonitor->SetDesiredFailureMsg(kInformationBit,
"Stage has multiple OpEntryPoint (Fragment, Vertex) and could not detect stage");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8924
TEST_F(NegativeDebugPrintfShaderDebugInfo, DISABLED_DebugLabelRegion1) {
TEST_DESCRIPTION("Print debug label regions in a Debug PrintF message");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
char const *shader_source = R"glsl(
#version 450
#extension GL_EXT_debug_printf : enable
void main() {
debugPrintfEXT("printf");
}
)glsl";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = std::make_unique<VkShaderObj>(this, shader_source, VK_SHADER_STAGE_COMPUTE_BIT);
pipe.CreateComputePipeline();
m_command_buffer.Begin();
VkDebugUtilsLabelEXT region_0_label = vku::InitStructHelper();
region_0_label.pLabelName = "region_0";
vk::CmdBeginDebugUtilsLabelEXT(m_command_buffer.handle(), &region_0_label);
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.Handle());
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
m_command_buffer.End();
m_errorMonitor->SetDesiredInfo("region_0");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}
// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8924
TEST_F(NegativeDebugPrintfShaderDebugInfo, DISABLED_DebugLabelRegion2) {
TEST_DESCRIPTION("Print debug label regions in a Debug PrintF message");
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
RETURN_IF_SKIP(InitDebugPrintfFramework(&layer_settings_create_info));
RETURN_IF_SKIP(InitState());
char const *shader_source = R"glsl(
#version 450
#extension GL_EXT_debug_printf : enable
void main() {
debugPrintfEXT("printf");
}
)glsl";
CreateComputePipelineHelper pipe(*this);
pipe.cs_ = std::make_unique<VkShaderObj>(this, shader_source, VK_SHADER_STAGE_COMPUTE_BIT);
pipe.CreateComputePipeline();
m_command_buffer.Begin();
VkDebugUtilsLabelEXT region_0_label = vku::InitStructHelper();
region_0_label.pLabelName = "region_0";
vk::CmdBeginDebugUtilsLabelEXT(m_command_buffer.handle(), &region_0_label);
VkDebugUtilsLabelEXT region_1_label = vku::InitStructHelper();
region_1_label.pLabelName = "region_1";
vk::CmdBeginDebugUtilsLabelEXT(m_command_buffer.handle(), &region_1_label);
vk::CmdBindPipeline(m_command_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.Handle());
vk::CmdDispatch(m_command_buffer.handle(), 1, 1, 1);
m_command_buffer.End();
m_errorMonitor->SetDesiredInfo("region_0::region_1");
m_default_queue->Submit(m_command_buffer);
m_default_queue->Wait();
m_errorMonitor->VerifyFound();
}