简体   繁体   中英

Vulkan, single render pass, 2 shaders, different number of outputs

This is my current setup:

  • Start render pass
  • Shader 1 outputs color to 5 attachments.
  • Shader 2 outputs color to the same 5 attachments
  • Finish recording commands

However that second doesn't really need to output anything to the 5 attachments, only to the first one.

Is it possible to change the number of attachments on the fly? Something like:

  • Start render pass
  • Shader 1 outputs color to 5 attachments.
  • Modify active framebuffer in the render pass
  • Shader 2 outputs color to only one the first attachment.
  • Finish recording commands

Or if that can't be done. Is it possible to switch off attachment clearing between render passes?

Edit the fragment shader in question looks like this:

#version 450
#extension GL_ARB_separate_shader_objects : enable

layout(location = 0) out vec4 color_out;
layout(location = 1) out vec4 color_out1;
layout(location = 2) out vec4 color_out2;
layout(location = 3) out vec4 color_out3;
layout(location = 4) out vec4 color_out4;

void main()
{
    color_out = vec4(1,1,1,1);
    color_out1 = vec4(0,0,0,0);
    color_out2 = vec4(0,0,0,0);
    color_out3 = vec4(0,0,0,0);
    color_out4 = vec4(0,0,0,0);
}

I am trying to get rid of it.

The way I currently do My render pass is:

// Initialize the FB with 5 image attachemnts + the clear values, etc...
vk::RenderPassBeginInfo render_pass_info;
render_pass_info.renderPass = *render_pass;
render_pass_info.framebuffer = *framebuffer;
render_pass_info.renderArea = vk::Rect2D({0,0}, extent);
render_pass_info.clearValueCount = clears.size();
render_pass_info.pClearValues = clears.data();

cmd.beginRenderPass(&render_pass_info, vk::SubpassContents::eInline);

/* setup pipeline 1 info, like it's descriptor sets, samplers etc*/
cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, *graphics_pipeline);
cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, *pipeline_layout, 0, 1, descriptor_set_ptr, 0, nullptr);

/* Do the same for the second pipeline */
cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, *graphics_pipeline);
cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, *pipeline_layout, 0, 1, descriptor_set_ptr, 0, nullptr);

The goal is to not output the additional 5 attachments in the shader. Which currently terminates my program with the following error:

Message ID name: UNASSIGNED-CoreValidation-Shader-InputNotProduced
Message: Attachment 1 not written by fragment shader; undefined values will be written to attachment
Severity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT

You have many options for this.

"Shader 2" can employ write masks to turn off writes to the other attachments. These are found in VkPipelineColorBlendAttachmentState::colorWriteMask , so you simply set this value to 0 to prevent writes to that attachment.

Alternatively, you can execute "Shader 2" in a separate subpass, one which only uses the attachment of interest.

Which to use depends on the nature of your rendering operations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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