Dess
Dess

Reputation: 2659

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); 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.

It's also possible to set input attachment indexes to VK_ATTACHMENT_UNUSED, but we're not allowed to read from such attachments. That means that if an input attachment could be VK_ATTACHMENT_UNUSED, the shader must know whether it should read from it or not.

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? 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
} 

Upvotes: 1

Views: 482

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473447

Vulkan doesn't generally have convenience features. 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. 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.

So there is no such query in Vulkan. You can build one yourself quite easily, however.

In Vulkan, pipelines are compiled against a specific subpass of a specific renderpass. 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. 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.

//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
};

Upvotes: 2

Related Questions