Num Vertex Attributes & Passing array of samplers to the FS

Hello guys,
i am implementing Shadow-Mapping for multiple Lights but i have two problems and dont know how to overcome them:

1.) Pass unlimited Vertex-Attributes from the VS to the FS
My first approach was this to pass the Shadow-Coords to the fragment-shader:

#define MAX_NUM_SHADOW_MAPS 32
layout (location = 3) out vec4 outShadowCoords[MAX_NUM_SHADOW_MAPS];

But then i recognized i cant pass (mostly) more than 16 vertex attributes to the FS. Pipeline-Creation fails then. What is a nice solution?

2.) Read from a variable amount of ShadowMaps in the FS
Again i tried using an array of samplers:

layout (set = 1, binding = 4) uniform sampler2D ShadowMaps[MAX_NUM_SHADOW_MAPS];

I wanted to pass the “real” amount of shadow-maps as a uniform to the shaders, so i read only the first “X” ShadowMaps, which were updated from the Application via VkUpdateDescriptorSet.
But the validation layers told me i have to update all samplers, so whats the best way to read from a “variable amount” of shadow-maps in the FS?

Thanks in Advance :slight_smile:

But then i recognized i cant pass (mostly) more than 16 vertex attributes to the FS. Pipeline-Creation fails then. What is a nice solution?

Stop passing so much data. I mean, do you really need to render 32 separate shadow maps in the same draw call?

Also, the term “vertex attributes” only applies to vertex shader inputs. VS outputs and FS inputs are just called outputs and inputs.

But the validation layers told me i have to update all samplers

What exactly does it say? Show us your vkUpdateDescriptorSet call, along with all of its parameters. And the validation error from it.

Also, show your descriptor set layout.

I never said i render 32 shadow-maps in the same draw-call. I want to sample from at most 32 shadow-maps within my “main shader” and for that i need to pass the ShadowCoords (vertex-pos * lightViewMatrix) for each light to my fragment-shader right?

[QUOTE=Alfonse Reinheart;40812]
What exactly does it say? Show us your vkUpdateDescriptorSet call, along with all of its parameters. And the validation error from it.

Also, show your descriptor set layout.[/QUOTE]

My fault, i made a mistake in my spirv-parsing code using spirv-cross. But still it give me another error message, which says i have to update the samplers-array even when im using only the first one (and updated only the first one).
[ATTACH=CONFIG]122[/ATTACH]
I just want to know i can sample from a different amount of textures in my fragment-shader.

Update:

So i am created a new texture size one by one and updated the whole array with this texture as the “default”:

        emptyTex = new Texture("white.dds");

        for(int i = 0; i < MAX_SHADOW_MAPS; i++)
            setTexture("ShadowMap", emptyTex, i); // Updates the descriptor-set at dstArrayElement "i" 

This works but is an really ugly hack :confused: Do i really have to update all “ArrayElements” of Sampler2Ds in a descriptor-set? Is there another way?

There’s a difference between “I want to have a bunch of textures bound so I don’t have to keep changing my descriptors” and “I intend to use every single one of these textures in a single draw call”.

If you only want to sample from one of the textures, then you need one set of texture coordinates and an index that tells you which you want to sample from. The number of actual samples you pull from the textures should be 1. Or at least, much less than 32.

Do you “have to” as far as the spec is concerned? No. My reading of the specification is that, if you access an array of textures with a dynamically uniform index, then the only descriptors in that array that must be valid are the ones that are actually accessed. Now, this would only be meaningful if dynamically uniform indexing of arrays of textures is permitted in your implementation.

Do you “have to” in order to shut the validator up? Yes. The validator has no way to know which elements you intend to access.

You could file a validation layer bug report on it. Presumably, the resolution would be that, if the implementation allows dynamically uniform indexing of that kind of descriptor, then the layer should assume that any update to the descriptor is sufficient, even if it does not fully update the array. It may emit a warning if you don’t update the whole array, but it shouldn’t error out.

Thanks for the detailed explanation Alfonse :slight_smile: