Translate a texture size query with the type its handle is sampled with #1627

Merged
jarynclouatre merged 2 commits from fix/txq-array-type into main 2026-11-10 17:01:56 +00:00
jarynclouatre commented 2026-11-10 11:30:12 +00:00 (Migrated from github.com)

A program that samples a texture as an array and also asks its size was prepared with the size query typed 2D, because the prepare has nothing bound to ask. In play the bound array gave another answer, so the program was translated again in the middle of a frame. The size query now takes the array type the same constant-buffer handle is sampled with. A dimension that the instruction itself fixes (TEX, TLD, TXD and the like) is no longer recorded as an answer either, since the same module and view run whatever is bound there. Rectangles and buffers still are answers.

This changes the translator stamp (texture_pass.cpp, shader_info.h, vk_shader.cpp), so the program cache is rebuilt once.

Testing: RTX 4070 Ti Super, driver 621.14, Windows 11, Ryzen 7 9800X3D.

Build: on 779bdcf the Windows DLL builds and tests/test_program_answer_domains.py passes (70 checks), built with clang on Linux.

Route: the scripted 10-minute route from #1429, first visit, each run on a fresh folder after its first start. Two runs each on 7d1562d with the stage libraries off, and one each with RX_VK_GPL=1 on a folder warmed by #1586:

main this #1586 #1586 and this
programs translated in play 88, 87 4, 5 92 4
time lost against 60 fps, s 75.8, 66.9 69.6, 63.8 38.1 26.2
waits for pipelines 509, 516 565, 574 44 6
draws left out 362,088, 416,364 343,080, 352,176 3,720 528
cold stage libraries 128 4

With the libraries off the programs it saves are a small part of the time lost, which is mostly pipelines; with them warmed, a program translated in play is also a cold library, and that is where it counts.

The branch as it is here, on 779bdcf, ran the same route once with the libraries off: 4 programs translated in play, 67.6 s lost.

tests/test_program_answer_domains.py covers the answer that is no longer recorded; the size query's type has no test of its own.

A program that samples a texture as an array and also asks its size was prepared with the size query typed 2D, because the prepare has nothing bound to ask. In play the bound array gave another answer, so the program was translated again in the middle of a frame. The size query now takes the array type the same constant-buffer handle is sampled with. A dimension that the instruction itself fixes (TEX, TLD, TXD and the like) is no longer recorded as an answer either, since the same module and view run whatever is bound there. Rectangles and buffers still are answers. This changes the translator stamp (texture_pass.cpp, shader_info.h, vk_shader.cpp), so the program cache is rebuilt once. Testing: RTX 4070 Ti Super, driver 621.14, Windows 11, Ryzen 7 9800X3D. Build: on 779bdcf the Windows DLL builds and tests/test_program_answer_domains.py passes (70 checks), built with clang on Linux. Route: the scripted 10-minute route from #1429, first visit, each run on a fresh folder after its first start. Two runs each on 7d1562d with the stage libraries off, and one each with RX_VK_GPL=1 on a folder warmed by #1586: | | main | this | #1586 | #1586 and this | |---|---|---|---|---| | programs translated in play | 88, 87 | 4, 5 | 92 | 4 | | time lost against 60 fps, s | 75.8, 66.9 | 69.6, 63.8 | 38.1 | 26.2 | | waits for pipelines | 509, 516 | 565, 574 | 44 | 6 | | draws left out | 362,088, 416,364 | 343,080, 352,176 | 3,720 | 528 | | cold stage libraries | | | 128 | 4 | With the libraries off the programs it saves are a small part of the time lost, which is mostly pipelines; with them warmed, a program translated in play is also a cold library, and that is where it counts. The branch as it is here, on 779bdcf, ran the same route once with the libraries off: 4 programs translated in play, 67.6 s lost. tests/test_program_answer_domains.py covers the answer that is no longer recorded; the size query's type has no test of its own.
hckrman101 (Migrated from github.com) approved these changes 2026-11-10 16:39:45 +00:00
hckrman101 (Migrated from github.com) left a comment

Looks good. I traced the flow: the size query takes the array type from a same-handle sampler (restricted to a single plain cbuf handle, so nothing else is guessed), type_fixed is ANDed when descriptors merge, and canonical_answer only canonicalizes the dimension when the descriptor is fixed while keeping the integer bit and leaving Rect/Buffer as real answers. The source-grep guard in the test script is a good touch. CI is green.

Nit: as the description says, the size query's own type choice (the array_types lookup) has no test, only the answer-domain side does. Not blocking.

Looks good. I traced the flow: the size query takes the array type from a same-handle sampler (restricted to a single plain cbuf handle, so nothing else is guessed), `type_fixed` is ANDed when descriptors merge, and `canonical_answer` only canonicalizes the dimension when the descriptor is fixed while keeping the integer bit and leaving Rect/Buffer as real answers. The source-grep guard in the test script is a good touch. CI is green. Nit: as the description says, the size query's own type choice (the array_types lookup) has no test, only the answer-domain side does. Not blocking.
Commenting is not possible because the repository is archived.
No description provided.