有没有办法强制 SPIR-V 汇编函数接受私有和函数存储 class 数组?

Is there way to force SPIR-V assembly function to accept both Private and Function storage class arrays?

我正在为 SPIR-V 着色器编写二进制处理模块,以修复由于 driver 错误导致的 float4x3[6] 矩阵的对齐问题。现在我有:

但现在我 运行 遇到了麻烦。看起来 SPIR-V 中的函数可以接受 Private 或 Function 存储限定符指针。不是都。有什么方法可以告诉我 SPIR-V“是的,你可以将这两个存储 classes 作为参数转储到这里”?

或者我是否需要修改我的解决方案以利用函数存储 class 矩阵目标,并在每次将它们用于新函数时注入它们并调用解压缩它们?这看起来不太优雅,因为那时可能会有更多的解包操作。更不用说 hassle-free,因为我必须分别扫描每个 OpFunction 块,并将带有函数存储的 OpVariables 注入到每个使用矩阵的块中。

我的问题是,在完成所有这些机器之后,我的目标将作为私有存储持续时间的 OpTypePointer 存在。因此我不能在从 HLSL 生成的任何 SPIR-V 函数中使用它们,因为它们采用函数持续时间的 OpTypePointers。我的解包函数是唯一的例外,因为我直接将它逐字节注入 SPIR-V asm,并且能够在 header.

中精确调整 OpFunctionParameters

这是调用约定的问题。或者更确切地说,缺乏 SPIR-V.

中的调用约定

Higher-level 像 GLSL 和 HLSL 这样的语言有调用约定。他们解释了函数接受输入参数意味着什么,以及这与提供给它的参数有何关系。

SPIR-V 在这个意义上没有调用约定。或者更重要的是,您必须 构造 您想要使用 SPIR-V.

的调用约定

HLSL 中的参数是conceptually always passed by copy。如果参数是输入参数,则使用给定参数初始化副本。如果参数是输出参数,调用函数后将函数中的数据复制到参数中。

HLSL 编译器必须在 SPIR-V 中实现它。因此,如果函数采用 struct 输入参数,则该函数的输入参数必须是来自任何现有对象的 new storage。当调用者尝试调用此函数时,它必须为该参数创建存储。该存储将使用 Function 存储限定符,因此该参数也使用该限定符。

SPIR-V 要求指针类型指定它们指向的对象的存储限定符。这一点很重要,因为编译器生成访问对象的 GPU 程序集的方式可能不同(可能非常不同)。因此,函数不能接受指向不同存储的指针 类;函数必须选择一个。

因此,如果您的 SPIR-V 调整系统发现一个函数调用,其源数据来自您需要调整的内容,那么您有两个选择:

  1. 创建一个新函数,它是旧函数的副本,除了它需要一个 Private 指针。

  2. 通过创建 Function 本地存储并在调用函数之前将数据从 Private 复制到其中(如果是输出参数)。那里可能已经有执行此操作的代码,因此您可能只需要更改它复制的位置 from/to.