'Vulkan validation layer behaviour when complaining about image layout

In my code, I group my index buffer by material and render different materials with a loop

for (MaterialGroup matGroup : shape.materialGroups) {
    int materialId = matGroup.materialId;
    descSets[1] = _descriptorSets.materialDescriptorSets[materialId];
    vkCmdBindDescriptorSets(_commandBuffers.sceneCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, _pipelineLayouts.scenePipelineLayout, 0, descSets.size(), descSets.data(), 0, nullptr);
    vkCmdDrawIndexed(_commandBuffers.sceneCommandBuffers[i], matGroup.indexCount, 1, matGroup.indexBase, 0, 0);
}

Here descSets[0] contains a uniform buffer about the scene (camera, light) information, while descSet[1] contains the material information. The fragment shader is quite simple as I debug

#version 450
#extension GL_KHR_vulkan_glsl: enable

layout(set = 0, binding = 0) uniform CameraUniformObject {...} camera;

layout(set = 0, binding = 1) uniform LightUniformObject {...} light;

layout(set = 1, binding = 0) uniform MaterialUniformObject {...} material;

layout(set = 1, binding = 1) uniform sampler2D ambient_texture;
layout(set = 1, binding = 2) uniform sampler2D diffuse_texture;
layout(set = 1, binding = 3) uniform sampler2D specular_texture;
layout(set = 1, binding = 4) uniform sampler2D specular_highlight_texture;
layout(set = 1, binding = 5) uniform sampler2D bump_texture;
layout(set = 1, binding = 6) uniform sampler2D displacement_texture;
layout(set = 1, binding = 7) uniform sampler2D alpha_texture;
layout(set = 1, binding = 8) uniform sampler2D reflection_texture;

layout(location = 0) in vec3 fragColor;
layout(location = 1) in vec2 fragTexCoord;
layout(location = 2) in vec3 inPosition;
layout(location = 3) in vec3 inNormal;
layout(location = 4) in flat int inMaterialId;

layout(location = 0) out vec3 outColor;

void main() {
    vec4 kd = {0.0f, 0.0f, 0.0f, 0.0f};
    if (material.diffuse_texture_ind != 0)
        kd = texture(diffuse_texture, fragTexCoord);
    else
        kd = vec4(1.0f, 0.0f, 0.0f, 0.0f);
    outColor = vec3(kd.x, kd.y, kd.z);
}

It samples the color from a texture if material.diffuse_texture_ind is not 0, otherwise set the color red. There are samplers for other textures but they are never used by this fragment shader. The texture index here is actually the index of the texture in my texture cache which is a vector of textures. The first element is a default blank texture used as a placeholder for those samplers without a texture in my descriptor set.

Now there comes the problem. When I run the program, the validation layer complains that my default texture is not in the correct layout

validation layer: Validation Error: [ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] Object 0: handle = 0x1845e115cd0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x4dae5635 | vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x1845e115cd0[] expects VkImage 0x84c0580000000017[emptyTextureImage] (subresource: aspectMask 0x1 array layer 0, mip level 0) to be in layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_UNDEFINED.

whenever I draw a material whosematerial.diffuse_texture_ind is set 0, but does not complain when other combined samplers are created with the same default image. I am wondering why this would happen as the default texture is never actually sampled with my if...else... statement in the fragment shader. I am also wondering why it does not complain about other combined samplers constructed with the same image.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source