xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_state_cs.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (c) 2022-2024 Broadcom. All Rights Reserved.
3  * The term “Broadcom” refers to Broadcom Inc.
4  * and/or its subsidiaries.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include "util/u_inlines.h"
9 #include "util/u_memory.h"
10 #include "util/u_bitmask.h"
11 #include "translate/translate.h"
12 
13 #include "svga_context.h"
14 #include "svga_cmd.h"
15 #include "svga_shader.h"
16 #include "svga_tgsi.h"
17 
18 
19 /**
20  * Create compute shader compile key.
21  */
22 static void
make_cs_key(struct svga_context * svga,struct svga_compile_key * key)23 make_cs_key(struct svga_context *svga,
24             struct svga_compile_key *key)
25 {
26    struct svga_compute_shader *cs = svga->curr.cs;
27 
28    memset(key, 0, sizeof *key);
29 
30    svga_init_shader_key_common(svga, PIPE_SHADER_COMPUTE, &cs->base, key);
31 
32    key->cs.grid_size[0] = svga->curr.grid_info.size[0];
33    key->cs.grid_size[1] = svga->curr.grid_info.size[1];
34    key->cs.grid_size[2] = svga->curr.grid_info.size[2];
35    key->cs.mem_size = cs->shared_mem_size;
36 
37    if (svga->curr.grid_info.indirect && cs->base.info.uses_grid_size) {
38       struct pipe_transfer *transfer = NULL;
39       const void *map = NULL;
40       map = pipe_buffer_map(&svga->pipe, svga->curr.grid_info.indirect,
41                             PIPE_MAP_READ, &transfer);
42       memcpy(key->cs.grid_size, map, 3 * sizeof(uint));
43       pipe_buffer_unmap(&svga->pipe, transfer);
44    }
45 }
46 
47 
48 /**
49  * Emit current compute shader to device.
50  */
51 static enum pipe_error
emit_hw_cs(struct svga_context * svga,uint64_t dirty)52 emit_hw_cs(struct svga_context *svga, uint64_t dirty)
53 {
54    struct svga_shader_variant *variant;
55    struct svga_compute_shader *cs = svga->curr.cs;
56    enum pipe_error ret = PIPE_OK;
57    struct svga_compile_key key;
58 
59    assert(svga_have_sm5(svga));
60 
61    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITCS);
62 
63    if (!cs) {
64       if (svga->state.hw_draw.cs != NULL) {
65 
66          /** The previous compute shader is made inactive.
67           *  Needs to unbind the compute shader.
68           */
69          ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_CS, NULL);
70          if (ret != PIPE_OK)
71             goto done;
72          svga->state.hw_draw.cs = NULL;
73       }
74       goto done;
75    }
76 
77    make_cs_key(svga, &key);
78 
79    /* See if we already have a CS variant that matches the key */
80    variant = svga_search_shader_key(&cs->base, &key);
81 
82    if (!variant) {
83       ret = svga_compile_shader(svga, &cs->base, &key, &variant);
84       if (ret != PIPE_OK)
85          goto done;
86    }
87 
88    if (variant != svga->state.hw_draw.cs) {
89       /* Bind the new variant */
90       ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_CS, variant);
91       if (ret != PIPE_OK)
92          goto done;
93 
94       svga->rebind.flags.cs = false;
95       svga->dirty |= SVGA_NEW_CS_VARIANT;
96       svga->state.hw_draw.cs = variant;
97    }
98 
99 done:
100    SVGA_STATS_TIME_POP(svga_sws(svga));
101    return ret;
102 }
103 
104 struct svga_tracked_state svga_hw_cs =
105 {
106    "compute shader",
107    (SVGA_NEW_CS |
108     SVGA_NEW_TEXTURE_BINDING |
109     SVGA_NEW_SAMPLER |
110     SVGA_NEW_CS_RAW_BUFFER),
111    emit_hw_cs
112 };
113