gpt4 book ai didi

shader - AGAL seq 操作码适用于硬件,但不适用于软件仿真(两者的 float 比较不同?)

转载 作者:行者123 更新时间:2023-12-02 01:17:29 25 4
gpt4 key购买 nike

来自文档:seq set-if-equal destination = source1 == source2 ? 1 : 0,组件方面

我还没有对它进行彻底的测试,但到目前为止,我的片段着色器在两台机器(台式电脑)上都能正常工作,其中 context3D 初始化作为 DirectX 成功,但在闪存回退到软件渲染的机器上不起作用。

seq ft2.x, ft0.x, fc0.x

ft.x 在硬件上设置为 1,当存储在 ft0.x 中的当前像素红色值等于常量 fc0.x,里面存放着50/255。所以我想要发生的事情确实发生在硬件上的 #32???? (50 == 0x32) 彩色像素上,但软件上没有。

我已经测试了一种解决方法,我可以用更复杂的算法替换 seq 操作码,该算法涉及 slt(如果小于则设置)或 sge(如果大于或等于则设置)。

所以问题似乎在于比较我提供给 GPU 的常量 (50/255) 和实际的红色值(在纹理中为 50)。如果是其他情况(例如 RGBA 值具有不同的顺序),sltsge 也会失败。

我是不是做错了什么?我是否应该以某种方式舍入比较值(例如乘以 255,然后删除小数部分)以确保它适用于所有设备和模式?

更新:其中一台带有软件渲染回退的机器被设置为 16 位图形,但是将其更改为 32 位并没有解决问题。我还盲目尝试将颜色值除以 256、128 和 127 而不是 255,希望如果 float 具有不同的精度(并且更高和更低的数字都可以工作,只要它们等于256 像素长渐变内的像素之一),但我的希望没有得到返回。

然后我尝试了将常量存储为整数的解决方法,并在着色器内部将值乘以 255 并删除小数,令我惊讶的是,虽然它在 GPU 上工作,但在软件渲染上却失败了:

mul ft0.x, ft0.x, fc0.y 通过将 ft0.x(红色 channel )乘以常量 255< 将其转换为整数/强>

frc ft4.x, ft0.x 得到小数

sub ft0.x, ft0.x, ft4.x 去除小数,截断整数

现在进行比较,例如seq ft2.x, ft0.x, fc0.x

add ft0.x, ft0.x, ft4.x 向后加小数,这一步可能没有必要

div ft0.x, ft0.x, fc0.y 将整数值除以 255 以将其转换回 float (我指的是 0..1 范围内的数字)

接下来我要尝试的解决方法是简单地进行一系列小于比较,将临时寄存器设置为 1,将其添加到另一个临时寄存器(计数器),以便通过检查我可以看到值在哪个范围内的计数器。

最佳答案

这是最终为我解决问题的解决方法。

我在红色 alpha channel 上有 4 种颜色,它们通知着色器该做什么。如果红色值为 50,着色器将以左侧像素为源,如果为 100,则以顶部像素为源,依此类推。所以我所要做的就是 4 个 seq 命令来为一个寄存器的 4 个分量设置 0 或 1 个偏移量,稍后我可以在寄存器中添加或删除带有采样器位置的寄存器。

因为 seq 无法将第一次采样的像素的红色值与提供的常量进行比较,所以我制作了一个 set-if-greater-or-equal 操作码的“阶梯”:

"mov ft3.x, fc0.x \n" + //ft3 = 49/0xFF

"sge ft2.x, ft0.x, ft3.x \n" + //if red > 49/0xFF, set 1 to ft2.x

"add ft3.x, ft3.x, fc0.x \n" + //ft3 = 98/0xFF
"sge ft4.x, ft0.x, ft3.x \n" + //if red > 98/0xFF, set 1 to ft4.x
"add ft2.x, ft2.x, ft4.x \n" + //if 49 < red < 98, ft2.x = 1, if red > 98, ft2.x = 2

"add ft3.x, ft3.x, fc0.x \n" + //ft3 = 147/0xFF
"sge ft4.x, ft0.x, ft3.x \n" + //if red > 147/0xFF, set 1 to ft4.x
"add ft2.x, ft2.x, ft4.x \n" + //if 49 < red < 98, ft2.x = 1, if 98 < red < 147, ft2.x = 2, if red > 147, ft2.x = 3

"add ft3.x, ft3.x, fc0.x \n" + //ft3 = 196/0xFF
"sge ft4.x, ft0.x, ft3.x \n" + //if red > 196/0xFF, set 1 to ft4.x
"add ft2.x, ft2.x, ft4.x \n" + //ft2.x is between 0 and 4 including, where 0 means no control color

现在我有一个寄存器 ft2 存储:

0 表示低于 49 的红色(实际上所有这些红色值都除以 255,如上面代码中的注释所示)

1 代表 4998

之间的红色

2 表示 98147

之间的红色

3 代表 147196

之间的红色

4 代表红色 196

然后我不会将像素颜色与常量进行比较,而是将 ft2.x 计数器状态与常量进行比较(常量将是 1,2,3,4 而不是 50,100,150,200) .

不幸的是,这意味着上面的整个代码是额外的开销,我可以节省 GPU,但在 CPU 上无法避免,除非我能找到 seq 操作码在 CPU 上总是返回 0 的解决方案比较像素颜色和常量时。

关于shader - AGAL seq 操作码适用于硬件,但不适用于软件仿真(两者的 float 比较不同?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41953220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com