如何解决从Vulkan中的附件读取当前样本
我有一个全屏效果通道,该通道已多次采样。 如果我从输入附件(也是多次采样)中读取。我似乎只看过同一样本。
管道示例设置:
VkPipelineMultisampleStateCreateInfo multisampling_info = {};
multisampling_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampling_info.rasterizationSamples = static_cast<VkSampleCountFlagBits>(samples);
multisampling_info.sampleShadingEnable = samples > 1 ? VK_TRUE : VK_FALSE;
multisampling_info.minSampleShading = 1.0;
multisampling_info.pSampleMask = nullptr;
multisampling_info.alphaToCoverageEnable = VK_FALSE;
multisampling_info.alphaToOneEnable = VK_FALSE;
在着色器中,我使用以下图像类型:
%28 = OpTypeImage %float SubpassData 0 0 1 2 UnkNown
并以(0,0)的坐标读取它
%34 = OpImageRead %v4float %30 %36
似乎每个样本都调用了着色器,因为我正确获取了SampleId。
Spir-v规范说:
当Image Dim操作数为SubpassData时,坐标相对于当前片段位置。也就是说,将当前片段的窗口相对(x,y)坐标的整数值(向下舍入)加到(u,v)。
如果我正确地理解了这一点,那么在坐标为(0,0)的情况下,我应该总是得到相应的样本吗?
我误解了吗?还是不可能?
这是我正在使用的完整spirv着色器:
OpCapability Shader
OpCapability InputAttachment
OpCapability SampleRateShading
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %44 "main" %41 %gl_SampleID
OpExecutionMode %44 OriginUpperLeft
OpDecorate %_struct_3 Block
OpMemberDecorate %_struct_3 0 Offset 0
OpDecorate %gl_SampleID BuiltIn SampleId
OpDecorate %32 DescriptorSet 0
OpDecorate %32 Binding 0
OpDecorate %32 InputAttachmentIndex 0
OpDecorate %41 Location 0
%int = OpTypeInt 32 1
%_struct_3 = OpTypestruct %int
%_ptr_PushConstant__struct_3 = OpTypePointer PushConstant %_struct_3
%5 = OpVariable %_ptr_PushConstant__struct_3 PushConstant
%_ptr_PushConstant_int = OpTypePointer PushConstant %int
%bool = OpTypeBool
%_ptr_Input_int = OpTypePointer Input %int
%gl_SampleID = OpVariable %_ptr_Input_int Input
%float = OpTypeFloat 32
%28 = OpTypeImage %float SubpassData 0 0 1 2 UnkNown
%_ptr_UniformConstant_28 = OpTypePointer UniformConstant %28
%32 = OpVariable %_ptr_UniformConstant_28 UniformConstant
%v4float = OpTypeVector %float 4
%v2int = OpTypeVector %int 2
%_ptr_Output_v4float = OpTypePointer Output %v4float
%41 = OpVariable %_ptr_Output_v4float Output
%void = OpTypeVoid
%42 = OpTypeFunction %void
%int_0 = OpConstant %int 0
%int_3 = OpConstant %int 3
%int_1 = OpConstant %int 1
%int_5 = OpConstant %int 5
%int_16 = OpConstant %int 16
%36 = OpConstantComposite %v2int %int_16 %int_0
%39 = OpConstantNull %v4float
%44 = OpFunction %void None %42
%1 = OpLabel
%7 = OpAccessChain %_ptr_PushConstant_int %5 %int_0
%9 = OpLoad %int %7
%10 = OpShiftRightArithmetic %int %9 %int_3
%13 = OpSLessthan %bool %10 %int_0
%14 = OpSelect %int %13 %int_1 %int_0
%16 = OpBitwiseAnd %int %9 %int_5
%18 = OpINotEqual %bool %16 %int_0
%19 = OpSelect %int %18 %int_1 %int_0
%20 = OpBitwiSEOr %int %19 %14
%21 = OpIAdd %int %10 %20
%22 = OpLoad %int %gl_SampleID
%25 = OpSLessthan %bool %22 %21
OpSelectionMerge %26 None
OpBranchConditional %25 %27 %26
%27 = OpLabel
%30 = OpLoad %28 %32
%34 = OpImageRead %v4float %30 %36
OpBranch %26
%26 = OpLabel
%38 = OpPhi %v4float %34 %27 %39 %1
OpStore %41 %38
OpReturn
OpFunctionEnd
解决方法
最后,它非常简单。 OpImageRead可能具有可选的图像操作数,其中之一可以是Sample,它获取将要读取的样本。 将内置变量SampleId(当前带阴影的样本)输入到其中即可解决该问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。