从 vulkan 中的附件中读取当前样本
Read current sample from an attachment in 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 规范说:
When the Image Dim operand is SubpassData, Coordinate is relative to the current fragment location. That is, the integer value (rounded down) of the current fragment’s window-relative (x, y) coordinate is added to (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(当前阴影样本)输入其中修复它。
我有一个多重采样的全屏效果通道。 如果我从输入附件(也是多重采样的)读取。我好像只看过同一个样本。
管道示例设置:
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 规范说:
When the Image Dim operand is SubpassData, Coordinate is relative to the current fragment location. That is, the integer value (rounded down) of the current fragment’s window-relative (x, y) coordinate is added to (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(当前阴影样本)输入其中修复它。