asahi: Fix using multiple textures/samplers

The counts for textures/samplers are specified in the bind
texture/sampler packets. What's in the bind pipeline appear to be...
hints? of some kind? It's a direct function of the numbers of textures
and samplers, but much more coarse. Unknown purpose.

This should be correct for up to 48 textures and at least 8 samplers.
For more than 48 textures, Metal switches to a "bindless" mode, where
the textures are instead bound with a bind uniform packet, ts* is no
longer read in the shader, and instead registers and immediates are used
to index the texture with a substantial preshader. Details TBD. We don't
need to worry about that for a long while, though.

Fixes a number of dEQPs.

   dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.array_in_struct.sampler2D_samplerCube_both,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.array_in_struct.sampler2D_samplerCube_fragment,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.array_in_struct.sampler2D_samplerCube_vertex,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.nested_structs_arrays.sampler2D_samplerCube_both,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.nested_structs_arrays.sampler2D_samplerCube_fragment,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_pointer.render.nested_structs_arrays.sampler2D_samplerCube_vertex,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.array_in_struct.sampler2D_samplerCube_both,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.array_in_struct.sampler2D_samplerCube_fragment,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.array_in_struct.sampler2D_samplerCube_vertex,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.nested_structs_arrays.sampler2D_samplerCube_both,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.nested_structs_arrays.sampler2D_samplerCube_fragment,Crash
   dEQP-GLES2.functional.uniform_api.value.assigned.by_value.render.nested_structs_arrays.sampler2D_samplerCube_vertex,Crash

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17198>
This commit is contained in:
Alyssa Rosenzweig 2022-01-18 21:54:22 -05:00
parent d2fef02cc0
commit b1180fe2f6
2 changed files with 21 additions and 7 deletions

View file

@ -67,6 +67,8 @@
<enum name="Layout">
<value name="Linear" value="0"/>
<!-- Default layout if no other layout is set -->
<value name="Null" value="1"/>
<!-- Morton order with 64x64 tiles -->
<value name="Tiled 64x64" value="2"/>
</enum>
@ -213,6 +215,8 @@
to switch tile size (or disable tiling altogether?) at small mip levels to
reduce wasted memory due to padding. Causing test flakiness when set. -->
<field name="Unk mipmapped" size="1" start="102" type="bool"/>
<!-- This is set when no texture is bound, with layout 1 -->
<field name="Null" size="1" start="105" type="bool"/>
<field name="Compression" size="2" start="106" type="hex"/> <!-- 0 for 64x64 tiling -->
<field name="sRGB" size="1" start="108" type="bool"/>
<field name="Unk 2" size="1" start="109" type="bool"/>
@ -412,7 +416,7 @@
<field name="Tag" size="8" start="0:0" type="hex" default="0x4d"/>
<field name="Unk 1" size="24" start="0:8" type="hex" default="0x90"/>
<field name="Unk 2" size="8" start="1:0" type="hex" default="0x0d"/> <!-- TODO differs with stage -->
<field name="Unk 2b" size="8" start="1:8" type="uint" default="4"/>
<field name="Unk 2b" size="8" start="1:8" type="uint" default="4"/> <!--- Seemingly texture count related? -->
<field name="Code" size="32" start="1:16" type="address"/>
<field name="Unk 3" size="8" start="2:16" type="hex" default="0x8d"/>
<field name="Register quadwords" size="5" start="2:24" type="uint"/> <!-- 0 for max -->
@ -462,9 +466,12 @@
<value name="AGX_BIND_PIPELINE_VERTEX" value="0x4000002e"/>
<value name="AGX_BIND_PIPELINE_FRAGMENT" value="0x800000"/>
</field>
<!-- 4 if more than 32 textures bound -->
<field name="Unk 1" size="4" start="1:0" type="hex" default="0x2"/>
<field name="Sampler count" start="1:4" size="5" type="uint"/>
<field name="Texture count" start="1:9" size="3" type="uint"/>
<field name="Groups of 8 immediate textures" start="1:4" size="3" type="uint"/>
<field name="Groups of 4 samplers" start="1:9" size="3" type="uint"/>
<!-- When more than 48 textures bound, switches to 0x8, unk1 switches to
0x6, and some funny sort of bindless access(?) is used in the shader -->
<field name="Unk 2" size="4" start="1:12" type="hex" default="0x1"/>
<field name="Input count" size="8" start="1:16" type="uint" default="0"/>
<field name="Padding 1" size="8" start="1:24" type="hex" default="0x0"/>
@ -476,6 +483,8 @@
<field name="VS Output count 2" size="8" start="3:8" type="uint" default="0"/>
<field name="Padding 2" size="16" start="3:16" type="hex" default="0x0"/>
<field name="More than 4 textures" start="4:0" size="1" type="bool"/>
<field name="Unk 3" size="32" start="5:0" type="address"/> <!-- C020000 -->
</struct>

View file

@ -1356,10 +1356,12 @@ demo_launch_fragment(struct agx_context *ctx, struct agx_pool *pool, uint32_t pi
{
struct agx_ptr t = agx_pool_alloc_aligned(pool, AGX_BIND_PIPELINE_LENGTH, 64);
unsigned tex_count = ctx->stage[PIPE_SHADER_FRAGMENT].texture_count;
agx_pack(t.cpu, BIND_PIPELINE, cfg) {
cfg.tag = AGX_BIND_PIPELINE_FRAGMENT;
cfg.sampler_count = ctx->stage[PIPE_SHADER_FRAGMENT].texture_count;
cfg.texture_count = ctx->stage[PIPE_SHADER_FRAGMENT].texture_count;
cfg.groups_of_8_immediate_textures = DIV_ROUND_UP(tex_count, 8);
cfg.groups_of_4_samplers = DIV_ROUND_UP(tex_count, 4);
cfg.more_than_4_textures = tex_count >= 4;
cfg.input_count = input_count;
cfg.pipeline = pipeline;
cfg.fs_varyings = varyings;
@ -1494,13 +1496,16 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out,
uint32_t pipeline_vertex, uint32_t pipeline_fragment, uint32_t varyings,
bool is_lines, bool is_points)
{
unsigned tex_count = ctx->stage[PIPE_SHADER_VERTEX].texture_count;
agx_pack(out, BIND_PIPELINE, cfg) {
cfg.tag = AGX_BIND_PIPELINE_VERTEX;
cfg.pipeline = pipeline_vertex;
cfg.vs_output_count_1 = ctx->vs->info.varyings.nr_slots;
cfg.vs_output_count_2 = ctx->vs->info.varyings.nr_slots;
cfg.sampler_count = ctx->stage[PIPE_SHADER_VERTEX].texture_count;
cfg.texture_count = ctx->stage[PIPE_SHADER_VERTEX].texture_count;
cfg.groups_of_8_immediate_textures = DIV_ROUND_UP(tex_count, 8);
cfg.groups_of_4_samplers = DIV_ROUND_UP(tex_count, 4);
cfg.more_than_4_textures = tex_count >= 4;
}
out += AGX_BIND_PIPELINE_LENGTH;