This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Vulkan driver issues - workaround collection thread

This is a list of Vulkan driver issues which are known to cause problems, have been fixed in the latest driver, but might not have gotten into updated drivers yet.

VK_REMAINING_* enums

 image_memory_barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
 image_memory_barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;

In some cases, this will directly crash the driver in vkCmdPipelineBarrier on older drivers. You can probably guess what the bug is :) Workaround is simply using the "correct" numbers for MIP_LEVELS and ARRAY_LAYERS instead.

Sampler parameters passed to functions

If you have code like:

vec4 function(sampler2D sampler, vec2 uv)
{
    return texture(sampler, uv);
}

This will cause problems on older drivers such as R12 (Midgard) when using a glslang version from last year or so. The workaround would be inlining with spirv-opt or avoiding this kind of code.

textureQueryLod

This crashes on R12 (Midgard), avoid altogether on this driver. However, it should be noted that textureQueryLod does not exist in GLES, only Vulkan (through desktop GLSL), so finding a workaround might not be difficult.

SPIRV-opt common uniform elimination pass

Avoid SPIR-V codegen where you end up loading an entire UBO with OpLoad, which this optimization typically ends up doing.

Partially loading depth/stencil

On older drivers, if you try to LOAD_OP_CLEAR depth, but LOAD_OP_LOAD stencil, this might lead to issues where loading and clearing does not work properly. On older drivers, use the same load operations for depth and stencil if you have a packed depth/stencil attachment. Easiest workaround is to just load DEPTH as well if you need this kind of render pass (although LOAD_OP_LOAD is discouraged on tile-based architectures).

Blending on B10G11R11

Older drivers did not report that B10G11R11_UFLOAT could blend with VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, but this works fine. As a workaround, you can assume that blending on this format just works.

Pipeline cache header version

On older drivers, the header in vkGetPipelineCacheData did not return VK_PIPELINE_CACHE_HEADER_VERSION_ONE properly in the blob header. You can just assume it's correct as a workaround.

MSAA on-tile resolve and MRT on swapchain images renders corrupt image

This bug affects very specifically Galaxy S7 on Android N with apiVersion 1.0.11 for the physical device. The workaround is to not use these features directly on the swapchain for this device + android version + driver version. To my knowledge, drivers have been updated on this device, but you may run into it on older images.

Primitive restart with vertexOffset/indirect and 16-bit indices renders corrupt image

On drivers before R22 (Midgard) / R10 (Bifrost), using primitive restart (16-bit indices) can render incorrectly if vertexOffset is non-zero in vkCmdDrawIndexed. A workaround for this is using vertexOffset = 0 and binding vertex buffers at the appropriate offset. Similar issue happens if you use indirect indexed draws (which might need vertex offset).

Viewports do not clip at clip-space boundaries

On drivers before R15 (Midgard), using a viewport which is a subset of the frame will not perform viewport bounds clipping properly when rendering outside the viewport area. The clipping behavior is purely guided by scissor tests on these drivers, so a simple workaround is to simply clip the scissor box against the viewport.

Renderpasses which only CLEAR and do not have any draw calls can lead to corrupt rendering

On drivers before R14 (Bifrost) and R26 (Midgard), using empty render passes which only clear color, but does not render anything can lead to corrupt rendering later. Transactional elimination state will not be updated properly, so what can happen is that you render something, but it is wrongly discarded, leading to odd tile-like artifacts.

To workaround this, you can check in EndRenderPass if any draw calls were submitted, and if not, emit a dummy draw call which renders outside the screen.

The best workaround is to defer the clear until you need to render anything if possible, as just clearing is not very bandwidth efficient.

Parents Reply Children