Is there a way to get the disassembly that your driver generates when compiling a shader? I noticed that you can get an accidental disassembly dump if you go over the maximum thread group size supported by the hardware in compute shaders, so naturally I figured there must be some way to do this for all shader types. Is there a reliable way to get the disassembly (perhaps specific to NVIDIA/AMD/Intel hardware), using tools or even just "hacks" like causing errors during compilation / linking?
At least on NVIDIA hardware, the shader assembly representation can be queried using the glGetProgramBinary() OpenGL function (initially part of the gl_arb_get_program_binary extension), which requires OpenGL 3.0 and upwards.
const size_t MAX_SIZE = 1<<24; char binary[MAX_SIZE]; GLenum format; GLint length; glGetProgramBinary(shaderProgramObject,MAX_SIZE,&length,&format,&binary);
You can then dump it however you want, for example (for easy copy and paste purposes of this answer) in C++:
std::ofstream binaryfile("bin.txt"); binaryfile.write(binary,length);
If you open the file with a text editor, it will contain some garbage (presumably the actual compiled binary representation of the assembly code), but at least on the three different sets of hardware and two different sets on driver versions I could test, it will also contain the assembly output of the program. Technically, the output of glGetProgramBinary is implementation (of your driver) dependent, so in the future or in older driver versions it might not contain any assembly, but it seems to work out so far.
I can't test whether AMD hardware drivers output the assembly as well, but it would make sense.
For AMD GPUs, check out Radeon GPU Analyzer -
Using this you can generate ISA disassembly and performance statistics for DX11, OpenGL and Vulkan shaders, and for OpenCL kernels.