Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
 
3
/*
4
 * Copyright (C) 2013 Rob Clark 
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice (including the next
14
 * paragraph) shall be included in all copies or substantial portions of the
15
 * Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
 *
25
 * Authors:
26
 *    Rob Clark 
27
 */
28
 
29
#include "pipe/p_state.h"
30
#include "util/u_string.h"
31
#include "util/u_memory.h"
32
#include "util/u_inlines.h"
33
#include "util/u_format.h"
34
 
35
#include "freedreno_state.h"
36
#include "freedreno_resource.h"
37
 
38
#include "fd3_gmem.h"
39
#include "fd3_context.h"
40
#include "fd3_emit.h"
41
#include "fd3_program.h"
42
#include "fd3_util.h"
43
#include "fd3_zsa.h"
44
 
45
 
46
static void
47
emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
48
		struct pipe_surface **bufs, uint32_t *bases, uint32_t bin_w)
49
{
50
	enum a3xx_tile_mode tile_mode;
51
	unsigned i;
52
 
53
	if (bin_w) {
54
		tile_mode = TILE_32X32;
55
	} else {
56
		tile_mode = LINEAR;
57
	}
58
 
59
	for (i = 0; i < 4; i++) {
60
		enum a3xx_color_fmt format = 0;
61
		enum a3xx_color_swap swap = WZYX;
62
		struct fd_resource *res = NULL;
63
		uint32_t stride = 0;
64
		uint32_t base = 0;
65
 
66
		if (i < nr_bufs) {
67
			struct pipe_surface *psurf = bufs[i];
68
 
69
			res = fd_resource(psurf->texture);
70
			format = fd3_pipe2color(psurf->format);
71
			swap = fd3_pipe2swap(psurf->format);
72
 
73
			if (bin_w) {
74
				stride = bin_w * res->cpp;
75
 
76
				if (bases) {
77
					base = bases[i] * res->cpp;
78
				}
79
			} else {
80
				stride = res->pitch * res->cpp;
81
			}
82
		}
83
 
84
		OUT_PKT0(ring, REG_A3XX_RB_MRT_BUF_INFO(i), 2);
85
		OUT_RING(ring, A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) |
86
				A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
87
				A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride) |
88
				A3XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap));
89
		if (bin_w || (i >= nr_bufs)) {
90
			OUT_RING(ring, A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(base));
91
		} else {
4401 Serge 92
			OUT_RELOCW(ring, res->bo, 0, 0, -1);
4358 Serge 93
		}
94
 
95
		OUT_PKT0(ring, REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(i), 1);
96
		OUT_RING(ring, A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT(format));
97
	}
98
}
99
 
100
static uint32_t
101
depth_base(struct fd_gmem_stateobj *gmem)
102
{
103
	return align(gmem->bin_w * gmem->bin_h, 0x4000);
104
}
105
 
106
/* transfer from gmem to system memory (ie. normal RAM) */
107
 
108
static void
109
emit_gmem2mem_surf(struct fd_ringbuffer *ring,
110
		enum adreno_rb_copy_control_mode mode,
111
		uint32_t base, struct pipe_surface *psurf)
112
{
113
	struct fd_resource *rsc = fd_resource(psurf->texture);
114
 
115
	OUT_PKT0(ring, REG_A3XX_RB_COPY_CONTROL, 4);
116
	OUT_RING(ring, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) |
117
			A3XX_RB_COPY_CONTROL_MODE(mode) |
118
			A3XX_RB_COPY_CONTROL_GMEM_BASE(base));
4401 Serge 119
	OUT_RELOCW(ring, rsc->bo, 0, 0, -1);    /* RB_COPY_DEST_BASE */
4358 Serge 120
	OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(rsc->pitch * rsc->cpp));
121
	OUT_RING(ring, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR) |
122
			A3XX_RB_COPY_DEST_INFO_FORMAT(fd3_pipe2color(psurf->format)) |
123
			A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(0xf) |
124
			A3XX_RB_COPY_DEST_INFO_ENDIAN(ENDIAN_NONE) |
125
			A3XX_RB_COPY_DEST_INFO_SWAP(fd3_pipe2swap(psurf->format)));
126
 
127
	OUT_PKT3(ring, CP_DRAW_INDX, 3);
128
	OUT_RING(ring, 0x00000000);
129
	OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
130
			INDEX_SIZE_IGN, IGNORE_VISIBILITY));
131
	OUT_RING(ring, 2);					/* NumIndices */
132
}
133
 
134
static void
135
fd3_emit_tile_gmem2mem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
136
		uint32_t bin_w, uint32_t bin_h)
137
{
138
	struct fd3_context *fd3_ctx = fd3_context(ctx);
139
	struct fd_ringbuffer *ring = ctx->ring;
140
	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
141
 
142
	OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
143
	OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
144
 
145
	OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
146
	OUT_RING(ring, A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) |
147
			A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
148
			A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
149
			A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
150
			A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
151
			A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
152
			A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
153
			A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
154
 
155
	OUT_PKT0(ring, REG_A3XX_RB_STENCILREFMASK, 2);
156
	OUT_RING(ring, 0xff000000 |
157
			A3XX_RB_STENCILREFMASK_STENCILREF(0) |
158
			A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
159
			A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
160
	OUT_RING(ring, 0xff000000 |
161
			A3XX_RB_STENCILREFMASK_STENCILREF(0) |
162
			A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
163
			A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
164
 
165
	OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
166
	OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
167
 
168
	OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
169
	OUT_RING(ring, 0x00000000);   /* GRAS_CL_CLIP_CNTL */
170
 
4401 Serge 171
	OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6);
172
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET((float)pfb->width/2.0 - 0.5));
173
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE((float)pfb->width/2.0));
174
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET((float)pfb->height/2.0 - 0.5));
175
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-(float)pfb->height/2.0));
176
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
177
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
178
 
4358 Serge 179
	OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
180
	OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
181
			A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
182
 
183
	fd3_emit_rbrc_draw_state(ring,
184
			A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE |
185
			A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER));
186
 
187
	OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
188
	OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
189
			A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
190
			A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
191
 
192
	OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
193
	OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
194
			A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
195
			A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
196
			A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
197
 
198
	OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
199
	OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
200
			A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
201
	OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(pfb->width - 1) |
202
			A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(pfb->height - 1));
203
 
204
	OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
205
	OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
206
	OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
207
	OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
208
	OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
209
 
210
	fd3_program_emit(ring, &ctx->solid_prog);
211
 
212
	fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
213
			{ .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
214
		}, 1);
215
 
216
	if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
4401 Serge 217
		uint32_t base = 0;
218
		if (pfb->cbufs[0]) {
219
			struct fd_resource *rsc =
220
					fd_resource(pfb->cbufs[0]->texture);
221
			base = depth_base(&ctx->gmem) * rsc->cpp;
222
		}
4358 Serge 223
		emit_gmem2mem_surf(ring, RB_COPY_DEPTH_STENCIL, base, pfb->zsbuf);
224
	}
225
 
226
	if (ctx->resolve & FD_BUFFER_COLOR) {
227
		emit_gmem2mem_surf(ring, RB_COPY_RESOLVE, 0, pfb->cbufs[0]);
228
	}
229
 
230
	OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
231
	OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
232
			A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
233
 
234
	OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
235
	OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
236
			A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
237
			A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
238
}
239
 
240
/* transfer from system memory to gmem */
241
 
242
static void
243
emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base,
244
		struct pipe_surface *psurf, uint32_t bin_w)
245
{
246
	emit_mrt(ring, 1, &psurf, &base, bin_w);
247
 
248
	fd3_emit_gmem_restore_tex(ring, psurf);
249
 
250
	OUT_PKT3(ring, CP_DRAW_INDX, 3);
251
	OUT_RING(ring, 0x00000000);
252
	OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
253
			INDEX_SIZE_IGN, IGNORE_VISIBILITY));
254
	OUT_RING(ring, 2);					/* NumIndices */
255
}
256
 
257
static void
258
fd3_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
259
		uint32_t bin_w, uint32_t bin_h)
260
{
261
	struct fd3_context *fd3_ctx = fd3_context(ctx);
262
	struct fd_gmem_stateobj *gmem = &ctx->gmem;
263
	struct fd_ringbuffer *ring = ctx->ring;
264
	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
265
	float x0, y0, x1, y1;
266
	unsigned i;
267
 
268
	/* write texture coordinates to vertexbuf: */
269
	x0 = ((float)xoff) / ((float)pfb->width);
270
	x1 = ((float)xoff + bin_w) / ((float)pfb->width);
271
	y0 = ((float)yoff) / ((float)pfb->height);
272
	y1 = ((float)yoff + bin_h) / ((float)pfb->height);
273
 
274
	OUT_PKT3(ring, CP_MEM_WRITE, 5);
4401 Serge 275
	OUT_RELOC(ring, fd_resource(fd3_ctx->blit_texcoord_vbuf)->bo, 0, 0, 0);
4358 Serge 276
	OUT_RING(ring, fui(x0));
277
	OUT_RING(ring, fui(y0));
278
	OUT_RING(ring, fui(x1));
279
	OUT_RING(ring, fui(y1));
280
 
281
	for (i = 0; i < 4; i++) {
282
		OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1);
283
		OUT_RING(ring, A3XX_RB_MRT_CONTROL_ROP_CODE(12) |
284
				A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_DISABLE) |
285
				A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf));
286
 
287
		OUT_PKT0(ring, REG_A3XX_RB_MRT_BLEND_CONTROL(i), 1);
288
		OUT_RING(ring, A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) |
289
				A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
290
				A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) |
291
				A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) |
292
				A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
293
				A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO) |
294
				A3XX_RB_MRT_BLEND_CONTROL_CLAMP_ENABLE);
295
	}
296
 
297
	fd3_emit_rbrc_tile_state(ring,
298
			A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
299
 
300
	OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
301
	OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_LESS));
302
 
303
	OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
304
	OUT_RING(ring, A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER);   /* GRAS_CL_CLIP_CNTL */
305
 
306
	OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 6);
307
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET((float)bin_w/2.0 - 0.5));
308
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE((float)bin_w/2.0));
309
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET((float)bin_h/2.0 - 0.5));
310
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-(float)bin_h/2.0));
311
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
312
	OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(1.0));
313
 
314
	OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
315
	OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(0) |
316
			A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(0));
317
	OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(bin_w - 1) |
318
			A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(bin_h - 1));
319
 
320
	OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
321
	OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
322
			A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
323
	OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(bin_w - 1) |
324
			A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(bin_h - 1));
325
 
326
	OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
327
	OUT_RING(ring, 0x2 |
328
			A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) |
329
			A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
330
			A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
331
			A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
332
			A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_ALWAYS) |
333
			A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
334
			A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
335
			A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
336
 
337
	fd3_emit_rbrc_draw_state(ring,
338
			A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_ALWAYS));
339
 
340
	OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
341
	OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
342
			A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
343
			A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
344
 
345
	OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
346
	OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(2) |
347
			A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
348
			A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
349
			A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
350
 
351
	OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
352
	OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
353
	OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
354
	OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
355
	OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
356
 
357
	fd3_program_emit(ring, &ctx->blit_prog);
358
 
359
	fd3_emit_vertex_bufs(ring, &ctx->blit_prog, (struct fd3_vertex_buf[]) {
360
			{ .prsc = fd3_ctx->blit_texcoord_vbuf, .stride = 8, .format = PIPE_FORMAT_R32G32_FLOAT },
361
			{ .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
362
		}, 2);
363
 
364
	/* for gmem pitch/base calculations, we need to use the non-
365
	 * truncated tile sizes:
366
	 */
367
	bin_w = gmem->bin_w;
368
	bin_h = gmem->bin_h;
369
 
370
	if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
371
		emit_mem2gmem_surf(ring, depth_base(gmem), pfb->zsbuf, bin_w);
372
 
373
	if (ctx->restore & FD_BUFFER_COLOR)
374
		emit_mem2gmem_surf(ring, 0, pfb->cbufs[0], bin_w);
375
 
376
	OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
377
	OUT_RING(ring, A3XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
378
			A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
379
			A3XX_GRAS_SC_CONTROL_RASTER_MODE(0));
380
}
381
 
382
static void
383
update_vsc_pipe(struct fd_context *ctx)
384
{
385
	struct fd_ringbuffer *ring = ctx->ring;
386
	struct fd_gmem_stateobj *gmem = &ctx->gmem;
387
	struct fd_bo *bo = fd3_context(ctx)->vsc_pipe_mem;
388
	int i;
389
 
390
	/* since we aren't using binning, just try to assign all bins
391
	 * to same pipe for now:
392
	 */
393
	OUT_PKT0(ring, REG_A3XX_VSC_PIPE(0), 3);
394
	OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) |
395
			A3XX_VSC_PIPE_CONFIG_Y(0) |
396
			A3XX_VSC_PIPE_CONFIG_W(gmem->nbins_x) |
397
			A3XX_VSC_PIPE_CONFIG_H(gmem->nbins_y));
4401 Serge 398
	OUT_RELOC(ring, bo, 0, 0, 0);           /* VSC_PIPE[0].DATA_ADDRESS */
4358 Serge 399
	OUT_RING(ring, fd_bo_size(bo) - 32);    /* VSC_PIPE[0].DATA_LENGTH */
400
 
401
	for (i = 1; i < 8; i++) {
402
		OUT_PKT0(ring, REG_A3XX_VSC_PIPE(i), 3);
403
		OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) |
404
				A3XX_VSC_PIPE_CONFIG_Y(0) |
405
				A3XX_VSC_PIPE_CONFIG_W(0) |
406
				A3XX_VSC_PIPE_CONFIG_H(0));
407
		OUT_RING(ring, 0x00000000);         /* VSC_PIPE[i].DATA_ADDRESS */
408
		OUT_RING(ring, 0x00000000);         /* VSC_PIPE[i].DATA_LENGTH */
409
	}
410
}
411
 
412
/* for rendering directly to system memory: */
413
static void
414
fd3_emit_sysmem_prep(struct fd_context *ctx)
415
{
416
	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
417
	struct fd_ringbuffer *ring = ctx->ring;
4401 Serge 418
	uint32_t pitch = 0;
4358 Serge 419
 
4401 Serge 420
	if (pfb->cbufs[0])
421
		pitch = fd_resource(pfb->cbufs[0]->texture)->pitch;
422
 
4358 Serge 423
	fd3_emit_restore(ctx);
424
 
425
	OUT_PKT0(ring, REG_A3XX_RB_WINDOW_SIZE, 1);
426
	OUT_RING(ring, A3XX_RB_WINDOW_SIZE_WIDTH(pfb->width) |
427
			A3XX_RB_WINDOW_SIZE_HEIGHT(pfb->height));
428
 
429
	emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, 0);
430
 
431
	fd3_emit_rbrc_tile_state(ring,
4401 Serge 432
			A3XX_RB_RENDER_CONTROL_BIN_WIDTH(pitch));
4358 Serge 433
 
434
	/* setup scissor/offset for current tile: */
435
	OUT_PKT0(ring, REG_A3XX_PA_SC_WINDOW_OFFSET, 1);
436
	OUT_RING(ring, A3XX_PA_SC_WINDOW_OFFSET_X(0) |
437
			A3XX_PA_SC_WINDOW_OFFSET_Y(0));
438
 
439
	OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
440
	OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(0) |
441
			A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(0));
442
	OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(pfb->width - 1) |
443
			A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(pfb->height - 1));
444
 
445
	OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
446
	OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
447
			A3XX_RB_MODE_CONTROL_GMEM_BYPASS |
448
			A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
449
}
450
 
451
/* before first tile */
452
static void
453
fd3_emit_tile_init(struct fd_context *ctx)
454
{
455
	struct fd_ringbuffer *ring = ctx->ring;
456
	struct fd_gmem_stateobj *gmem = &ctx->gmem;
457
 
458
	fd3_emit_restore(ctx);
459
 
460
	/* note: use gmem->bin_w/h, the bin_w/h parameters may be truncated
461
	 * at the right and bottom edge tiles
462
	 */
463
	OUT_PKT0(ring, REG_A3XX_VSC_BIN_SIZE, 1);
464
	OUT_RING(ring, A3XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) |
465
			A3XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h));
466
 
467
	/* TODO we only need to do this if gmem stateobj changes.. or in
468
	 * particular if the # of bins changes..
469
	 */
470
	update_vsc_pipe(ctx);
471
}
472
 
473
/* before mem2gmem */
474
static void
475
fd3_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
476
		uint32_t bin_w, uint32_t bin_h)
477
{
478
	struct fd_ringbuffer *ring = ctx->ring;
479
	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
480
	struct fd_gmem_stateobj *gmem = &ctx->gmem;
481
	uint32_t reg;
482
 
483
 
484
	OUT_PKT0(ring, REG_A3XX_RB_DEPTH_INFO, 2);
485
	reg = A3XX_RB_DEPTH_INFO_DEPTH_BASE(depth_base(gmem));
486
	if (pfb->zsbuf) {
487
		reg |= A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format));
488
	}
489
	OUT_RING(ring, reg);
490
	if (pfb->zsbuf) {
491
		uint32_t cpp = util_format_get_blocksize(pfb->zsbuf->format);
492
		OUT_RING(ring, A3XX_RB_DEPTH_PITCH(cpp * gmem->bin_w));
493
	} else {
494
		OUT_RING(ring, 0x00000000);
495
	}
496
 
497
	OUT_PKT0(ring, REG_A3XX_RB_WINDOW_SIZE, 1);
498
	OUT_RING(ring, A3XX_RB_WINDOW_SIZE_WIDTH(pfb->width) |
499
			A3XX_RB_WINDOW_SIZE_HEIGHT(pfb->height));
500
 
501
	OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 1);
502
	OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
503
			A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE);
504
}
505
 
506
/* before IB to rendering cmds: */
507
static void
508
fd3_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
509
		uint32_t bin_w, uint32_t bin_h)
510
{
511
	struct fd_ringbuffer *ring = ctx->ring;
512
	struct fd_gmem_stateobj *gmem = &ctx->gmem;
513
	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
514
 
515
	uint32_t x1 = xoff;
516
	uint32_t y1 = yoff;
517
	uint32_t x2 = xoff + bin_w - 1;
518
	uint32_t y2 = yoff + bin_h - 1;
519
 
520
	OUT_PKT3(ring, CP_SET_BIN, 3);
521
	OUT_RING(ring, 0x00000000);
522
	OUT_RING(ring, CP_SET_BIN_1_X1(x1) | CP_SET_BIN_1_Y1(y1));
523
	OUT_RING(ring, CP_SET_BIN_2_X2(x2) | CP_SET_BIN_2_Y2(y2));
524
 
525
	emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL, gmem->bin_w);
526
 
527
	fd3_emit_rbrc_tile_state(ring,
528
			A3XX_RB_RENDER_CONTROL_ENABLE_GMEM |
529
			A3XX_RB_RENDER_CONTROL_BIN_WIDTH(gmem->bin_w));
530
 
531
	/* setup scissor/offset for current tile: */
532
	OUT_PKT0(ring, REG_A3XX_PA_SC_WINDOW_OFFSET, 1);
533
	OUT_RING(ring, A3XX_PA_SC_WINDOW_OFFSET_X(xoff) |
534
			A3XX_PA_SC_WINDOW_OFFSET_Y(yoff));
535
 
536
	OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
537
	OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1) |
538
			A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(y1));
539
	OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(x2) |
540
			A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(y2));
541
}
542
 
543
void
544
fd3_gmem_init(struct pipe_context *pctx)
545
{
546
	struct fd_context *ctx = fd_context(pctx);
547
 
548
	ctx->emit_sysmem_prep = fd3_emit_sysmem_prep;
549
	ctx->emit_tile_init = fd3_emit_tile_init;
550
	ctx->emit_tile_prep = fd3_emit_tile_prep;
551
	ctx->emit_tile_mem2gmem = fd3_emit_tile_mem2gmem;
552
	ctx->emit_tile_renderprep = fd3_emit_tile_renderprep;
553
	ctx->emit_tile_gmem2mem = fd3_emit_tile_gmem2mem;
554
}