Skip to content

Texture and sampler descriptors #37

@mr-mobster

Description

@mr-mobster

I was trying to understand how resource descriptors work on the low level (especially in the context of this very informative blog post). I hope this is a good place to ask.

The texture_load instruction is sparsely documented and I've been having difficulties wrapping my head around it. From various code snippets (using Metal texture slots as well as argument buffers), it appears that both texture and sampler descriptor can either come from some sort of dedicated register space (tsN, ssN) — could anyone tell me more about it? Are they mapped to uniform registers or is it a completely separate hardware state? The instruction itself is disassembled like this (what is the purpose of that last uniform register?):

// tex0.sample(s0, float2(0, 0)).x 
texture_sample  0, 0b00, 0b01100, 0b0, 0b00000, x, 0b000, r0, None, ts0, ss0, tex_2d, r0_r1.discard, lod_min, u2l
                                                           ^        ^ texture+sampler ^ coordinates           ^  what's this?
                                                           |
                                                           |
                                                       output register

When using argument buffers, texture_load can also use regular registers, and if I understand the disassembly correctly, it's always a continuous register pair which presumably holds a 64-bit value. This is the disassembly:

// bindings[i].tex.sample(bindings[I].s, float2(0, 0)).x 
texture_sample   0, 0b00, 0b01100, 0b0, 0b00000, x, 0b000, r7, u0_u1, r0, r2l, tex_2d, r4_r5.discard, lod_min, u6l
                                                            ^  ^       ^   ^ sampler descriptor (previously loaded into r2_r3)
                                                            |  |       | 
                                                            |  |       texture  descriptor (previously loaded into r0_r1)                  
                                                            |  |                  
                                                            |  what is the purpose of this uniform?
                                                            |
                                                            output register

A couple of mysteries here: what is the purpose of the u0_u1 uniform? This seems to be a base address of some sort, but it's not the address of the argument buffer. Why is the sampler register referred to as r2l and not r2? And again, there is that mystery uniform at the end of the instruction — what's that about?

Bonus question: is there any information about what these descriptors represent? Are they pointers or some sort of table entries or something else entirely? Maybe there is something in the Asahi driver code? I tried to have a look but don't know hot to navigate the codebase...

Thank you for any pointers you might have!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions