a603017dd847abba23aaf4d274f5432bc7bc35da
[mesa.git] / src / gallium / drivers / freedreno / a6xx / fd6_emit.h
1 /*
2 * Copyright (C) 2016 Rob Clark <robclark@freedesktop.org>
3 * Copyright © 2018 Google, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * Authors:
25 * Rob Clark <robclark@freedesktop.org>
26 */
27
28 #ifndef FD6_EMIT_H
29 #define FD6_EMIT_H
30
31 #include "pipe/p_context.h"
32
33 #include "freedreno_context.h"
34 #include "fd6_context.h"
35 #include "fd6_format.h"
36 #include "fd6_program.h"
37 #include "ir3_shader.h"
38
39 struct fd_ringbuffer;
40
41 /* grouped together emit-state for prog/vertex/state emit: */
42 struct fd6_emit {
43 struct pipe_debug_callback *debug;
44 const struct fd_vertex_state *vtx;
45 const struct fd_program_stateobj *prog;
46 const struct pipe_draw_info *info;
47 struct ir3_shader_key key;
48 enum fd_dirty_3d_state dirty;
49
50 uint32_t sprite_coord_enable; /* bitmask */
51 bool sprite_coord_mode;
52 bool rasterflat;
53 bool no_decode_srgb;
54
55 /* in binning pass, we don't have real frag shader, so we
56 * don't know if real draw disqualifies lrz write. So just
57 * figure that out up-front and stash it in the emit.
58 */
59 bool no_lrz_write;
60
61 /* cached to avoid repeated lookups of same variants: */
62 const struct ir3_shader_variant *vp, *fp;
63 /* TODO: other shader stages.. */
64
65 unsigned streamout_mask;
66 };
67
68 static inline enum a6xx_color_fmt fd6_emit_format(struct pipe_surface *surf)
69 {
70 if (!surf)
71 return 0;
72 return fd6_pipe2color(surf->format);
73 }
74
75 static inline const struct ir3_shader_variant *
76 fd6_emit_get_vp(struct fd6_emit *emit)
77 {
78 if (!emit->vp) {
79 struct fd6_shader_stateobj *so = emit->prog->vp;
80 emit->vp = ir3_shader_variant(so->shader, emit->key, emit->debug);
81 }
82 return emit->vp;
83 }
84
85 static inline const struct ir3_shader_variant *
86 fd6_emit_get_fp(struct fd6_emit *emit)
87 {
88 if (!emit->fp) {
89 if (emit->key.binning_pass) {
90 /* use dummy stateobj to simplify binning vs non-binning: */
91 static const struct ir3_shader_variant binning_fp = {};
92 emit->fp = &binning_fp;
93 } else {
94 struct fd6_shader_stateobj *so = emit->prog->fp;
95 emit->fp = ir3_shader_variant(so->shader, emit->key, emit->debug);
96 }
97 }
98 return emit->fp;
99 }
100
101 static inline void
102 fd6_cache_flush(struct fd_batch *batch, struct fd_ringbuffer *ring)
103 {
104 fd_reset_wfi(batch);
105 #if 0
106 OUT_PKT4(ring, REG_A6XX_UCHE_CACHE_INVALIDATE_MIN_LO, 5);
107 OUT_RING(ring, 0x00000000); /* UCHE_CACHE_INVALIDATE_MIN_LO */
108 OUT_RING(ring, 0x00000000); /* UCHE_CACHE_INVALIDATE_MIN_HI */
109 OUT_RING(ring, 0x00000000); /* UCHE_CACHE_INVALIDATE_MAX_LO */
110 OUT_RING(ring, 0x00000000); /* UCHE_CACHE_INVALIDATE_MAX_HI */
111 OUT_RING(ring, 0x00000012); /* UCHE_CACHE_INVALIDATE */
112 fd_wfi(batch, ring);
113 #else
114 DBG("fd6_cache_flush stub");
115 #endif
116 }
117
118 static inline void
119 fd6_emit_blit(struct fd_context *ctx, struct fd_ringbuffer *ring)
120 {
121 emit_marker6(ring, 7);
122
123 OUT_PKT7(ring, CP_EVENT_WRITE, 1);
124 OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(BLIT));
125
126 emit_marker6(ring, 7);
127 }
128
129 static inline void
130 fd6_emit_render_cntl(struct fd_context *ctx, bool blit, bool binning)
131 {
132 #if 0
133 struct fd_ringbuffer *ring = binning ? ctx->batch->binning : ctx->batch->draw;
134
135 /* TODO eventually this partially depends on the pfb state, ie.
136 * which of the cbuf(s)/zsbuf has an UBWC flag buffer.. that part
137 * we could probably cache and just regenerate if framebuffer
138 * state is dirty (or something like that)..
139 *
140 * Other bits seem to depend on query state, like if samples-passed
141 * query is active.
142 */
143 bool samples_passed = (fd6_context(ctx)->samples_passed_queries > 0);
144 OUT_PKT4(ring, REG_A6XX_RB_RENDER_CNTL, 1);
145 OUT_RING(ring, 0x00000000 | /* RB_RENDER_CNTL */
146 COND(binning, A6XX_RB_RENDER_CNTL_BINNING_PASS) |
147 COND(binning, A6XX_RB_RENDER_CNTL_DISABLE_COLOR_PIPE) |
148 COND(samples_passed, A6XX_RB_RENDER_CNTL_SAMPLES_PASSED) |
149 COND(!blit, 0x8));
150 OUT_PKT4(ring, REG_A6XX_GRAS_SC_CNTL, 1);
151 OUT_RING(ring, 0x00000008 | /* GRAS_SC_CNTL */
152 COND(binning, A6XX_GRAS_SC_CNTL_BINNING_PASS) |
153 COND(samples_passed, A6XX_GRAS_SC_CNTL_SAMPLES_PASSED));
154 #else
155 DBG("render ctl stub");
156 #endif
157 }
158
159 static inline void
160 fd6_emit_lrz_flush(struct fd_ringbuffer *ring)
161 {
162 /* TODO I think the extra writes to GRAS_LRZ_CNTL are probably
163 * a workaround and not needed on all a5xx.
164 */
165 OUT_PKT4(ring, REG_A6XX_GRAS_LRZ_CNTL, 1);
166 OUT_RING(ring, A6XX_GRAS_LRZ_CNTL_ENABLE);
167
168 OUT_PKT7(ring, CP_EVENT_WRITE, 1);
169 OUT_RING(ring, LRZ_FLUSH);
170
171 OUT_PKT4(ring, REG_A6XX_GRAS_LRZ_CNTL, 1);
172 OUT_RING(ring, 0x0);
173 }
174
175 static inline enum a6xx_state_block
176 fd6_stage2shadersb(enum shader_t type)
177 {
178 switch (type) {
179 case SHADER_VERTEX:
180 return SB6_VS_SHADER;
181 case SHADER_FRAGMENT:
182 return SB6_FS_SHADER;
183 case SHADER_COMPUTE:
184 return SB6_CS_SHADER;
185 default:
186 unreachable("bad shader type");
187 return ~0;
188 }
189 }
190
191 void fd6_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd6_emit *emit);
192
193 void fd6_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
194 struct fd6_emit *emit);
195
196 void fd6_emit_cs_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
197 struct ir3_shader_variant *cp);
198
199 void fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring);
200
201 void fd6_emit_init(struct pipe_context *pctx);
202
203 #define WRITE(reg, val) do { \
204 OUT_PKT4(ring, reg, 1); \
205 OUT_RING(ring, val); \
206 } while (0)
207
208
209 #endif /* FD6_EMIT_H */