Questions about SDK triangle demo

I’ve been going through the source code for the triangle demo in the Vulkan SDK, and I’ve stumbled over a couple of things that are somewhat unclear to me:
[ul]
[li]You can use the “–use_staging”-parameter to force it to use a staging buffer, but I can’t find any explanation of what a staging buffer actually is. Can someone explain it to me?
[/li][li]The “setup_cmd” command buffer in the demo is destroyed and re-created every frame. Is there a particular reason for that?
[/li][li]The “setup_cmd” and “draw_cmd” are created with the same parameters. Why are both of them needed, why not run all of the commands through a single command buffer?
[/li][li]The shader stages are bound directly to the graphics pipeline on creation. Does that mean I need a separate graphics pipeline for each shader program?
[/li][/ul]
I’ve only worked with OpenGL so far, so some of these concepts are new to me, I would appreciate if someone could clear this up for me.

The shader stages are bound directly to the graphics pipeline on creation. Does that mean I need a separate graphics pipeline for each shader program?

Yes. Think of a graphics pipeline as all of OpenGL’s rendering (minus the framebuffer stuff that goes into rendering passes). That naturally includes the shaders you will use.

You don’t need to re-compile shader modules. But if you change programs, you will be changing every piece of non-dynamic state along with them.

Think of this as a subtle hint that you should endeavor not to change programs often :wink:

[QUOTE=Silverlan;39869]I’ve been going through the source code for the triangle demo in the Vulkan SDK, and I’ve stumbled over a couple of things that are somewhat unclear to me:
[ul]
[li]You can use the “–use_staging”-parameter to force it to use a staging buffer, but I can’t find any explanation of what a staging buffer actually is. Can someone explain it to me?[/li][li]The “setup_cmd” command buffer in the demo is destroyed and re-created every frame. Is there a particular reason for that?[/li][li]The “setup_cmd” and “draw_cmd” are created with the same parameters. Why are both of them needed, why not run all of the commands through a single command buffer?[/li][li]The shader stages are bound directly to the graphics pipeline on creation. Does that mean I need a separate graphics pipeline for each shader program?[/li][/ul]
I’ve only worked with OpenGL so far, so some of these concepts are new to me, I would appreciate if someone could clear this up for me.[/QUOTE]

A staging buffer is a place to store the data temporarily before being copied to the final destination for use.

There are some differences between the subsequent command buffers, like which rendertarget is used, the location of the data

[QUOTE=Alfonse Reinheart;39871]Yes. Think of a graphics pipeline as all of OpenGL’s rendering (minus the framebuffer stuff that goes into rendering passes). That naturally includes the shaders you will use.

You don’t need to re-compile shader modules. But if you change programs, you will be changing every piece of non-dynamic state along with them.

Think of this as a subtle hint that you should endeavor not to change programs often ;)[/QUOTE]

Well you really want to create and cache the programs in advance and not change them

When I said “change”, I meant change which one you were currently using, not actually recompiling them (a no-no even in OpenGL). That is, the only way to switch programs in Vulkan is to switch pipelines, which causes more changes than mere programs.

Thanks, that helps quite a bit.

I have another question regarding compressed image formats:
I’m using dds-files with DXT1, DXT3 and DXT5 compressions. I’m a bit confused about the equivalent formats in Vulkan:
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = VkFormat::VK_FORMAT_BC1_RGBA_SRGB_BLOCK?
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = VkFormat::VK_FORMAT_BC2_SRGB_BLOCK?
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = VkFormat::VK_FORMAT_BC3_SRGB_BLOCK?

  1. Why are there no alpha formats for BC2 and BC3?

  2. To create a compressed image, I essentially have to:
    a) Create the VkImage with the compressed format type
    b) Retrieve the memory requirements, create and bind the memory
    c) Map the memory with the compressed image data (And unmap it)
    Is that correct? I’ve been getting VkResult::VK_ERROR_MEMORY_MAP_FAILED errors with this method, is there anything else I need to be aware of?

You can only map host-visible memory objects. A proper way to do what you want is to allocate a buffer in pinned host memory to use it as an intermediate buffer, map it and and use DMA transfer to move data to local memory. You should not overallocate pinned memory, so use staging buffers. I’m assuming you should use a heap with properties either VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_ MEMORY_PROPERTY_HOST_COHERENT_BIT or VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT. If you do not want to bother too much with this yet, simply use VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_ MEMORY_PROPERTY_HOST_CACHED_BIT heap and act as you intended to do, but it is a bad idea for production. And you still need barriers. Read section 10.2 of specs for clarifications.

  1. Why are there no alpha formats for BC2 and BC3?

There are. See, BC1 has an option for being 3 component or 4 component (with a one-bit, pre-multipled alpha), so the Vulkan format name needs to be specific. BC2 and BC3 are always four component (indeed, having an alpha is the only reason to use them over BC1). It has the option to be SRGB or just UNORM, but not the option for fewer than 4 components. So the Vulkan format name doesn’t see the need to mention the number of components. It’s still 4.

The actual descriptions for BC2&3 says, “A four-component, block compressed format…”

So,

  1. Allocate an intermediate VkImage with host visible memory
  2. Load the image file data, map the image data to the intermediate image
  3. Then transfer the image data from the intermediate VkImage to the actual VkImage (Which doesn’t have host visible memory (Device memory only))
  4. Rinse and repeat from step 2 for all image files
    Did I get that right?

[QUOTE=Alfonse Reinheart;39880]There are. See, BC1 has an option for being 3 component or 4 component (with a one-bit, pre-multipled alpha), so the Vulkan format name needs to be specific. BC2 and BC3 are always four component (indeed, having an alpha is the only reason to use them over BC1). It has the option to be SRGB or just UNORM, but not the option for fewer than 4 components. So the Vulkan format name doesn’t see the need to mention the number of components. It’s still 4.

The actual descriptions for BC2&3 says, “A four-component, block compressed format…”[/QUOTE]
That makes a lot more sense now, thanks.

Another question, regarding descriptors:
What does the ‘maxSets’ attribute in the ‘VkDescriptorPoolCreateInfo’ actually do? Is it just some arbitrary limit, or is it used to (pre-)allocate data?
In my case it’s impossible to know beforehand how many descriptor sets will be created of each type, so I’m not sure what to set this to. What values are okay to use?