From: Alejandro Piñeiro <apinhe...@igalia.com> From Vulkan 1.0.50 spec, Section 3.30.1. Format Definition: VK_FORMAT_R16G16_SFLOAT
A two-component, 32-bit signed floating-point format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3. So this format expects those 16-bit floats to be passed without any conversion (applies too using 2/3/4 components, and with int formats) But from skl PRM, vol 07, section FormatConversion, page 445 there is a table that points that *16*FLOAT formats are converted to FLOAT, that in that context, is a 32-bit float. This is similar to the *64*FLOAT formats, that converts 64-bit floats to 32-bit floats. Unfortunately, while with 64-bit floats we have the alternative to use *64*PASSTHRU formats, it is not the case with 16-bits. This issue happens too with 16-bit int surface formats. As a workaround, if we are using a 16-bit location at the shader, we use 32-bit formats to avoid the conversion, and will fix getting the proper content later. Note that as we are using 32-bit formats, we can use formats with less components (example: use *R32* for *R16G16*). Signed-off-by: Jose Maria Casanova Crespo <jmcasan...@igalia.com> Signed-off-by: Alejandro Piñeiro <apinhe...@igalia.com> --- src/intel/vulkan/genX_pipeline.c | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index c2fa9c0ff7..8b2d472787 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -83,6 +83,44 @@ vertex_element_comp_control(enum isl_format format, unsigned comp) } } +#if GEN_GEN >= 8 +static enum isl_format +adjust_16bit_format(enum isl_format format) +{ + switch(format) { + case ISL_FORMAT_R16_FLOAT: + return ISL_FORMAT_R32_FLOAT; + case ISL_FORMAT_R16G16_FLOAT: + return ISL_FORMAT_R32_FLOAT; + case ISL_FORMAT_R16G16B16_FLOAT: + return ISL_FORMAT_R32G32_FLOAT; + case ISL_FORMAT_R16G16B16A16_FLOAT: + return ISL_FORMAT_R32G32_FLOAT; + + case ISL_FORMAT_R16_SINT: + return ISL_FORMAT_R32_SINT; + case ISL_FORMAT_R16G16_SINT: + return ISL_FORMAT_R32_SINT; + case ISL_FORMAT_R16G16B16_SINT: + return ISL_FORMAT_R32G32_SINT; + case ISL_FORMAT_R16G16B16A16_SINT: + return ISL_FORMAT_R32G32_SINT; + + case ISL_FORMAT_R16_UINT: + return ISL_FORMAT_R32_UINT; + case ISL_FORMAT_R16G16_UINT: + return ISL_FORMAT_R32_UINT; + case ISL_FORMAT_R16G16B16_UINT: + return ISL_FORMAT_R32G32_UINT; + case ISL_FORMAT_R16G16B16A16_UINT: + return ISL_FORMAT_R32G32_UINT; + + default: + return format; + } +} +#endif + static void emit_vertex_input(struct anv_pipeline *pipeline, const VkPipelineVertexInputStateCreateInfo *info) @@ -95,6 +133,10 @@ emit_vertex_input(struct anv_pipeline *pipeline, assert((inputs_read & ((1 << VERT_ATTRIB_GENERIC0) - 1)) == 0); const uint32_t elements = inputs_read >> VERT_ATTRIB_GENERIC0; const uint32_t elements_double = double_inputs_read >> VERT_ATTRIB_GENERIC0; +#if GEN_GEN >= 8 + const uint64_t half_inputs_read = vs_prog_data->half_inputs_read; + const uint32_t elements_half = half_inputs_read >> VERT_ATTRIB_GENERIC0; +#endif const bool needs_svgs_elem = vs_prog_data->uses_vertexid || vs_prog_data->uses_instanceid || vs_prog_data->uses_basevertex || @@ -125,6 +167,11 @@ emit_vertex_input(struct anv_pipeline *pipeline, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_TILING_LINEAR); +#if GEN_GEN >= 8 + if ((elements_half & (1 << desc->location)) != 0) { + format = adjust_16bit_format(format); + } +#endif assert(desc->binding < MAX_VBS); if ((elements & (1 << desc->location)) == 0) -- 2.13.6 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev