• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Alyssa Rosenzweig
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #pragma once
7 
8 #include "asahi/genxml/agx_pack.h"
9 #include "agx_compile.h"
10 #include "libagx_dgc.h"
11 #include "shader_enums.h"
12 
13 static inline unsigned
agx_usc_size(unsigned num_reg_bindings)14 agx_usc_size(unsigned num_reg_bindings)
15 {
16    STATIC_ASSERT(AGX_USC_UNIFORM_HIGH_LENGTH == AGX_USC_UNIFORM_LENGTH);
17    STATIC_ASSERT(AGX_USC_TEXTURE_LENGTH == AGX_USC_UNIFORM_LENGTH);
18    STATIC_ASSERT(AGX_USC_SAMPLER_LENGTH == AGX_USC_UNIFORM_LENGTH);
19 
20    size_t size = AGX_USC_UNIFORM_LENGTH * num_reg_bindings;
21 
22    size += AGX_USC_SHARED_LENGTH;
23    size += AGX_USC_SHADER_LENGTH;
24    size += AGX_USC_REGISTERS_LENGTH;
25    size += MAX2(AGX_USC_NO_PRESHADER_LENGTH, AGX_USC_PRESHADER_LENGTH);
26    size += AGX_USC_FRAGMENT_PROPERTIES_LENGTH;
27 
28    return size;
29 }
30 
31 static void
agx_usc_shared_none(struct agx_usc_builder * b)32 agx_usc_shared_none(struct agx_usc_builder *b)
33 {
34    agx_usc_pack(b, SHARED, cfg) {
35       cfg.layout = AGX_SHARED_LAYOUT_VERTEX_COMPUTE;
36       cfg.bytes_per_threadgroup = 65536;
37    }
38 }
39 
40 static inline void
agx_usc_shared(struct agx_usc_builder * b,uint16_t local_size,uint16_t imageblock_stride,unsigned variable_shared_mem)41 agx_usc_shared(struct agx_usc_builder *b, uint16_t local_size,
42                uint16_t imageblock_stride, unsigned variable_shared_mem)
43 {
44    if (imageblock_stride) {
45       assert(local_size == 0 && "we don't handle this interaction");
46       assert(variable_shared_mem == 0 && "we don't handle this interaction");
47 
48       agx_usc_pack(b, SHARED, cfg) {
49          cfg.layout = AGX_SHARED_LAYOUT_32X32;
50          cfg.uses_shared_memory = true;
51          cfg.sample_count = 1;
52          cfg.sample_stride_in_8_bytes = DIV_ROUND_UP(imageblock_stride, 8);
53          cfg.bytes_per_threadgroup = cfg.sample_stride_in_8_bytes * 8 * 32 * 32;
54       }
55    } else if (local_size || variable_shared_mem) {
56       unsigned size = local_size + variable_shared_mem;
57 
58       agx_usc_pack(b, SHARED, cfg) {
59          cfg.layout = AGX_SHARED_LAYOUT_VERTEX_COMPUTE;
60          cfg.bytes_per_threadgroup = size > 0 ? size : 65536;
61          cfg.uses_shared_memory = size > 0;
62       }
63    } else {
64       agx_usc_shared_none(b);
65    }
66 }
67 
68 static inline void
agx_usc_immediates(struct agx_usc_builder * b,const struct agx_rodata * ro,uint64_t base_addr)69 agx_usc_immediates(struct agx_usc_builder *b, const struct agx_rodata *ro,
70                    uint64_t base_addr)
71 {
72    for (unsigned range = 0; range < DIV_ROUND_UP(ro->size_16, 64); ++range) {
73       unsigned offset = 64 * range;
74       assert(offset < ro->size_16);
75 
76       agx_usc_uniform(b, ro->base_uniform + offset,
77                       MIN2(64, ro->size_16 - offset),
78                       base_addr + ro->offset + (offset * 2));
79    }
80 }
81 
82 static void
agx_usc_shared_non_fragment(struct agx_usc_builder * b,const struct agx_shader_info * info,unsigned variable_shared_mem)83 agx_usc_shared_non_fragment(struct agx_usc_builder *b,
84                             const struct agx_shader_info *info,
85                             unsigned variable_shared_mem)
86 {
87    if (info->stage != PIPE_SHADER_FRAGMENT) {
88       agx_usc_shared(b, info->local_size, info->imageblock_stride,
89                      variable_shared_mem);
90    }
91 }
92