KhronosGroup / KhronosGroup/glslang
compilation for GL_AMD_gpu_shader_half_float uses 16bit float constants, but does not declare Float16 capability
- Dominant language
- C++
- Stars
- 3.6k
- Forks
- 989
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 31
Description
This seems akin to the issue resolved by https://github.com/KhronosGroup/glslang/pull/1832
I am guessing a different situation is triggered by the fact it's AMD extensions triggering the use of 16bit floats.
This is a test case from SPIRV-Cross:
https://github.com/KhronosGroup/SPIRV-Cross/blob/master/shaders/frag/16bit-constants.invalid.frag
#version 450 core
#extension GL_AMD_gpu_shader_int16 : require
#extension GL_AMD_gpu_shader_half_float : require
layout(location = 0) out float16_t foo;
layout(location = 1) out int16_t bar;
layout(location = 2) out uint16_t baz;
void main() {
foo = 1.0hf;
bar = 2s;
baz = 3us;
}
Glslang generates this module:
```
OpCapability Shader
OpCapability StorageInputOutput16
OpExtension "SPV_KHR_16bit_storage"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %foo %bar %baz
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_AMD_gpu_shader_half_float"
OpSourceExtension "GL_AMD_gpu_shader_int16"
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpName %main "main"
OpName %foo "foo"
OpName %bar "bar"
OpName %baz "baz"
OpDecorate %foo Location 0
OpDecorate %bar Location 1
OpDecorate %baz Location 2
%void = OpTypeVoid
%3 = OpTypeFunction %void
%half = OpTypeFloat 16
%_ptr_Output_half = OpTypePointer Output %half
%foo = OpVariable %_ptr_Output_half Output
%half_0x1p_0 = OpConstant %half 0x1p+0
%short = OpTypeInt 16 1
%_ptr_Output_short = OpTypePointer Output %short
%bar = OpVariable %_ptr_Output_short Output
%short_2 = OpConstant %short 2
%ushort = OpTypeInt 16 0
%_ptr_Output_ushort = OpTypePointer Output %ushort
%baz = OpVariable %_ptr_Output_ushort Output
%ushort_3 = OpConstant %ushort 3
%main = OpFunction %void None %3
%5 = OpLabel
OpStore %foo %half_0x1p_0
OpStore %bar %short_2
OpStore %baz %ushort_3
OpReturn
OpFunctionEnd
```
Which then fails validation:
$ spirv-val --target-env vulkan1.0 a.spv
error: line 25: Cannot form constants of 8- or 16-bit types
%half_0x1p_0 = OpConstant %half 0x1p+0
The alternatives seem to be:
1. Generate a 32-bit constant then FConvert down to 16bit float
or
2. Declare the Float16 capability
Contributor guide
Research direction
Start with the SPIRV-Cross test case shaders/frag/16bit-constants.invalid.frag and reproduce the generated module with glslang. Run spirv-val --target-env vulkan1.0 and compare the emitted Float16 capability and constant instructions with the issue output. Done means the AMD half-float case produces SPIR-V accepted by the validator without regressing the 16-bit integer behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100