简体   繁体   English

确定输入附件在着色器中是否有效

[英]Determine if input attachment is valid within shader

For fragment shaders, it's possible to set color attachment indexes to VK_ATTACHMENT_UNUSED (from the C/C++ API);对于片段着色器,可以将颜色附件索引设置为VK_ATTACHMENT_UNUSED (来自 C/C++ API); in that case, writes to those attachments are discarded.在这种情况下,对这些附件的写入将被丢弃。 This is nice because it allows us to write shaders that unconditionally write to output attachments, and the writes may or may not be discarded, depending on what the renderer decided.这很好,因为它允许我们编写无条件写入 output 附件的着色器,并且写入可能会或可能不会被丢弃,具体取决于渲染器的决定。

It's also possible to set input attachment indexes to VK_ATTACHMENT_UNUSED , but we're not allowed to read from such attachments.也可以将输入附件索引设置为VK_ATTACHMENT_UNUSED ,但我们不允许从此类附件中读取。 That means that if an input attachment could be VK_ATTACHMENT_UNUSED , the shader must know whether it should read from it or not.这意味着如果输入附件可以VK_ATTACHMENT_UNUSED ,着色器必须知道它是否应该从中读取。

Is there a glsl/spir-v builtin way to check if an input attachment is bound to a valid image-view vs pointing to VK_ATTACHMENT_UNUSED ?是否有 glsl/spir-v 内置方法来检查输入附件是否绑定到有效的图像视图与指向VK_ATTACHMENT_UNUSED Otherwise, the app would have to pass data to the shader determining whether is can read or not.否则,应用程序必须将数据传递给着色器,以确定是否可以读取。 That's kind of a pain.那是一种痛苦。

Something builtin like:内置的东西,如:

layout(input_attachment_index=0, binding=42) uniform subpassInput inputData;

vec4 color = vec4(0);
if (gl_isInputAttachmentValid(0)) {
    color = subpassLoad(inputData).rgba
} 

Vulkan doesn't generally have convenience features. Vulkan 通常没有便利功能。 If the user is perfectly capable of doing a thing, then if the user wants that thing done, Vulkan won't do it for them.如果用户完全有能力做某事,那么如果用户想要完成那件事,Vulkan 就不会为他们做这件事。 If you can provide a value that specifies whether a resource the shader wants to use is available, Vulkan is not going to provide a query for you.如果您可以提供一个值来指定着色器想要使用的资源是否可用,Vulkan 不会为您提供查询。

So there is no such query in Vulkan.所以在 Vulkan 中没有这样的查询。 You can build one yourself quite easily, however.但是,您可以很容易地自己构建一个。

In Vulkan, pipelines are compiled against a specific subpass of a specific renderpass.在 Vulkan 中,管道是针对特定渲染通道的特定子通道编译的。 And whether a subpass of a renderpass uses an input attachment or not is something that is fixed to the renderpass.渲染通道的子通道是否使用输入附件是固定到渲染通道的。 As such, at the moment your C++ code compiles the shader module(s) into a pipeline, it knows if the subpass uses an input attachment or not.因此,当您的 C++ 代码将着色器模块编译到管道中时,它知道子通道是否使用输入附件。 There's no way it doesn't know.不可能不知道。

Therefore, there is no reason your pipeline compilation code cannot provide a specialization constant for your shader to test to see if it should use the input attachment or not.因此,您的管道编译代码没有理由不能为您的着色器提供专门化常量来测试它是否应该使用输入附件。 Simply declare a particular specialization constant, check it in the shader, and provide the specialization to the pipeline creation step via VkPipelineShaderStageCreateInfo::pSpecializationInfo .只需声明一个特定的特化常量,在着色器中检查它,并通过VkPipelineShaderStageCreateInfo::pSpecializationInfo为管道创建步骤提供特化。

//In shader
layout(constant_id = 0) const bool use_input_attachment;

...

if (use_input_attachment) {
    color = subpassLoad(inputData).rgba
} 

//In C++

const VkSpecializationMapEntry entries[] =
{
  {
    0, // constantID
    0, // offset
    sizeof(VkBool) // size
  }
};

const VkBool data[] = { /*VK_TRUE or VK_FALSE, as needed*/ };

const VkSpecializationInfo info =
{
  1, // mapEntryCount
  entries, // pMapEntries
  sizeof(VkBool), // dataSize
  data, // pData
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM