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