Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | 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) 2012 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
#include "tgsi/tgsi_dump.h"
35
#include "tgsi/tgsi_parse.h"
36
 
37
#include "fd2_program.h"
38
#include "fd2_compiler.h"
39
#include "fd2_texture.h"
40
#include "fd2_util.h"
41
 
42
static struct fd2_shader_stateobj *
43
create_shader(enum shader_t type)
44
{
45
	struct fd2_shader_stateobj *so = CALLOC_STRUCT(fd2_shader_stateobj);
46
	if (!so)
47
		return NULL;
48
	so->type = type;
49
	return so;
50
}
51
 
52
static void
53
delete_shader(struct fd2_shader_stateobj *so)
54
{
55
	ir2_shader_destroy(so->ir);
56
	free(so->tokens);
57
	free(so->bin);
58
	free(so);
59
}
60
 
61
static struct fd2_shader_stateobj *
62
assemble(struct fd2_shader_stateobj *so)
63
{
64
	free(so->bin);
65
	so->bin = ir2_shader_assemble(so->ir, &so->info);
66
	if (!so->bin)
67
		goto fail;
68
 
69
	if (fd_mesa_debug & FD_DBG_DISASM) {
70
		DBG("disassemble: type=%d", so->type);
71
		disasm_a2xx(so->bin, so->info.sizedwords, 0, so->type);
72
	}
73
 
74
	return so;
75
 
76
fail:
77
	debug_error("assemble failed!");
78
	delete_shader(so);
79
	return NULL;
80
}
81
 
82
static struct fd2_shader_stateobj *
83
compile(struct fd_program_stateobj *prog, struct fd2_shader_stateobj *so)
84
{
85
	int ret;
86
 
87
	if (fd_mesa_debug & FD_DBG_DISASM) {
88
		DBG("dump tgsi: type=%d", so->type);
89
		tgsi_dump(so->tokens, 0);
90
	}
91
 
92
	ret = fd2_compile_shader(prog, so);
93
	if (ret)
94
		goto fail;
95
 
96
	/* NOTE: we don't assemble yet because for VS we don't know the
97
	 * type information for vertex fetch yet.. so those need to be
98
	 * patched up later before assembling.
99
	 */
100
 
101
	so->info.sizedwords = 0;
102
 
103
	return so;
104
 
105
fail:
106
	debug_error("compile failed!");
107
	delete_shader(so);
108
	return NULL;
109
}
110
 
111
static void
112
emit(struct fd_ringbuffer *ring, struct fd2_shader_stateobj *so)
113
{
114
	unsigned i;
115
 
116
	if (so->info.sizedwords == 0)
117
		assemble(so);
118
 
119
	OUT_PKT3(ring, CP_IM_LOAD_IMMEDIATE, 2 + so->info.sizedwords);
120
	OUT_RING(ring, (so->type == SHADER_VERTEX) ? 0 : 1);
121
	OUT_RING(ring, so->info.sizedwords);
122
	for (i = 0; i < so->info.sizedwords; i++)
123
		OUT_RING(ring, so->bin[i]);
124
}
125
 
126
static void *
127
fd2_fp_state_create(struct pipe_context *pctx,
128
		const struct pipe_shader_state *cso)
129
{
130
	struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
131
	if (!so)
132
		return NULL;
133
	so->tokens = tgsi_dup_tokens(cso->tokens);
134
	return so;
135
}
136
 
137
static void
138
fd2_fp_state_delete(struct pipe_context *pctx, void *hwcso)
139
{
140
	struct fd2_shader_stateobj *so = hwcso;
141
	delete_shader(so);
142
}
143
 
144
static void
145
fd2_fp_state_bind(struct pipe_context *pctx, void *hwcso)
146
{
147
	struct fd_context *ctx = fd_context(pctx);
148
	ctx->prog.fp = hwcso;
149
	ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
150
	ctx->dirty |= FD_DIRTY_PROG;
151
}
152
 
153
static void *
154
fd2_vp_state_create(struct pipe_context *pctx,
155
		const struct pipe_shader_state *cso)
156
{
157
	struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX);
158
	if (!so)
159
		return NULL;
160
	so->tokens = tgsi_dup_tokens(cso->tokens);
161
	return so;
162
}
163
 
164
static void
165
fd2_vp_state_delete(struct pipe_context *pctx, void *hwcso)
166
{
167
	struct fd2_shader_stateobj *so = hwcso;
168
	delete_shader(so);
169
}
170
 
171
static void
172
fd2_vp_state_bind(struct pipe_context *pctx, void *hwcso)
173
{
174
	struct fd_context *ctx = fd_context(pctx);
175
	ctx->prog.vp = hwcso;
176
	ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
177
	ctx->dirty |= FD_DIRTY_PROG;
178
}
179
 
180
static void
181
patch_vtx_fetches(struct fd_context *ctx, struct fd2_shader_stateobj *so,
182
		struct fd_vertex_stateobj *vtx)
183
{
184
	unsigned i;
185
 
186
	assert(so->num_vfetch_instrs == vtx->num_elements);
187
 
188
	/* update vtx fetch instructions: */
189
	for (i = 0; i < so->num_vfetch_instrs; i++) {
190
		struct ir2_instruction *instr = so->vfetch_instrs[i];
191
		struct pipe_vertex_element *elem = &vtx->pipe[i];
192
		struct pipe_vertex_buffer *vb =
193
				&ctx->vertexbuf.vb[elem->vertex_buffer_index];
194
		enum pipe_format format = elem->src_format;
195
		const struct util_format_description *desc =
196
				util_format_description(format);
197
		unsigned j;
198
 
199
		/* Find the first non-VOID channel. */
200
		for (j = 0; j < 4; j++)
201
			if (desc->channel[j].type != UTIL_FORMAT_TYPE_VOID)
202
				break;
203
 
204
		/* CI/CIS can probably be set in compiler instead: */
205
		instr->fetch.const_idx = 20 + (i / 3);
206
		instr->fetch.const_idx_sel = i % 3;
207
 
208
		instr->fetch.fmt = fd2_pipe2surface(format);
209
		instr->fetch.is_normalized = desc->channel[j].normalized;
210
		instr->fetch.is_signed =
211
				desc->channel[j].type == UTIL_FORMAT_TYPE_SIGNED;
212
		instr->fetch.stride = vb->stride ? : 1;
213
		instr->fetch.offset = elem->src_offset;
214
 
215
		for (j = 0; j < 4; j++)
216
			instr->regs[0]->swizzle[j] = "xyzw01__"[desc->swizzle[j]];
217
 
218
		assert(instr->fetch.fmt != ~0);
219
 
220
		DBG("vtx[%d]: %s (%d), ci=%d, cis=%d, id=%d, swizzle=%s, "
221
				"stride=%d, offset=%d",
222
				i, util_format_name(format),
223
				instr->fetch.fmt,
224
				instr->fetch.const_idx,
225
				instr->fetch.const_idx_sel,
226
				elem->instance_divisor,
227
				instr->regs[0]->swizzle,
228
				instr->fetch.stride,
229
				instr->fetch.offset);
230
	}
231
 
232
	/* trigger re-assemble: */
233
	so->info.sizedwords = 0;
234
}
235
 
236
static void
237
patch_tex_fetches(struct fd_context *ctx, struct fd2_shader_stateobj *so,
238
		struct fd_texture_stateobj *tex)
239
{
240
	unsigned i;
241
 
242
	/* update tex fetch instructions: */
243
	for (i = 0; i < so->num_tfetch_instrs; i++) {
244
		struct ir2_instruction *instr = so->tfetch_instrs[i].instr;
245
		unsigned samp_id = so->tfetch_instrs[i].samp_id;
246
		unsigned const_idx = fd2_get_const_idx(ctx, tex, samp_id);
247
 
248
		if (const_idx != instr->fetch.const_idx) {
249
			instr->fetch.const_idx = const_idx;
250
			/* trigger re-assemble: */
251
			so->info.sizedwords = 0;
252
		}
253
	}
254
}
255
 
256
void
257
fd2_program_validate(struct fd_context *ctx)
258
{
259
	struct fd_program_stateobj *prog = &ctx->prog;
260
 
261
	/* if vertex or frag shader is dirty, we may need to recompile. Compile
262
	 * frag shader first, as that assigns the register slots for exports
263
	 * from the vertex shader.  And therefore if frag shader has changed we
264
	 * need to recompile both vert and frag shader.
265
	 */
266
	if (prog->dirty & FD_SHADER_DIRTY_FP)
267
		compile(prog, prog->fp);
268
 
269
	if (prog->dirty & (FD_SHADER_DIRTY_FP | FD_SHADER_DIRTY_VP))
270
		compile(prog, prog->vp);
271
 
272
	if (prog->dirty)
273
		ctx->dirty |= FD_DIRTY_PROG;
274
 
275
	/* if necessary, fix up vertex fetch instructions: */
276
	if (ctx->dirty & (FD_DIRTY_VTXSTATE | FD_DIRTY_PROG))
277
		patch_vtx_fetches(ctx, prog->vp, ctx->vtx);
278
 
279
	/* if necessary, fix up texture fetch instructions: */
280
	if (ctx->dirty & (FD_DIRTY_TEXSTATE | FD_DIRTY_PROG)) {
281
		patch_tex_fetches(ctx, prog->vp, &ctx->verttex);
282
		patch_tex_fetches(ctx, prog->fp, &ctx->fragtex);
283
	}
284
}
285
 
286
void
287
fd2_program_emit(struct fd_ringbuffer *ring,
288
		struct fd_program_stateobj *prog)
289
{
290
	struct ir2_shader_info *vsi =
291
		&((struct fd2_shader_stateobj *)prog->vp)->info;
292
	struct ir2_shader_info *fsi =
293
		&((struct fd2_shader_stateobj *)prog->fp)->info;
294
	uint8_t vs_gprs, fs_gprs, vs_export;
295
 
296
	emit(ring, prog->vp);
297
	emit(ring, prog->fp);
298
 
299
	vs_gprs = (vsi->max_reg < 0) ? 0x80 : vsi->max_reg;
300
	fs_gprs = (fsi->max_reg < 0) ? 0x80 : fsi->max_reg;
301
	vs_export = MAX2(1, prog->num_exports) - 1;
302
 
303
	OUT_PKT3(ring, CP_SET_CONSTANT, 2);
304
	OUT_RING(ring, CP_REG(REG_A2XX_SQ_PROGRAM_CNTL));
305
	OUT_RING(ring, A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE(POSITION_2_VECTORS_SPRITE) |
306
			A2XX_SQ_PROGRAM_CNTL_VS_RESOURCE |
307
			A2XX_SQ_PROGRAM_CNTL_PS_RESOURCE |
308
			A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(vs_export) |
309
			A2XX_SQ_PROGRAM_CNTL_PS_REGS(fs_gprs) |
310
			A2XX_SQ_PROGRAM_CNTL_VS_REGS(vs_gprs));
311
 
312
	prog->dirty = 0;
313
}
314
 
315
/* Creates shader:
316
 *    EXEC ADDR(0x2) CNT(0x1)
317
 *       (S)FETCH:	SAMPLE	R0.xyzw = R0.xyx CONST(0) LOCATION(CENTER)
318
 *    ALLOC PARAM/PIXEL SIZE(0x0)
319
 *    EXEC_END ADDR(0x3) CNT(0x1)
320
 *          ALU:	MAXv	export0 = R0, R0	; gl_FragColor
321
 *    NOP
322
 */
323
static struct fd2_shader_stateobj *
324
create_blit_fp(void)
325
{
326
	struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
327
	struct ir2_cf *cf;
328
	struct ir2_instruction *instr;
329
 
330
	if (!so)
331
		return NULL;
332
 
333
	so->ir = ir2_shader_create();
334
 
335
	cf = ir2_cf_create(so->ir, EXEC);
336
 
337
	instr = ir2_instr_create_tex_fetch(cf, 0);
338
	ir2_reg_create(instr, 0, "xyzw", 0);
339
	ir2_reg_create(instr, 0, "xyx", 0);
340
	instr->sync = true;
341
 
342
	cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
343
	cf = ir2_cf_create(so->ir, EXEC_END);
344
 
345
	instr = ir2_instr_create_alu(cf, MAXv, ~0);
346
	ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
347
	ir2_reg_create(instr, 0, NULL, 0);
348
	ir2_reg_create(instr, 0, NULL, 0);
349
 
350
	return assemble(so);
351
}
352
 
353
/* Creates shader:
354
*     EXEC ADDR(0x3) CNT(0x2)
355
*           FETCH:	VERTEX	R1.xy01 = R0.x FMT_32_32_FLOAT UNSIGNED STRIDE(8) CONST(26, 1)
356
*           FETCH:	VERTEX	R2.xyz1 = R0.x FMT_32_32_32_FLOAT UNSIGNED STRIDE(12) CONST(26, 0)
357
*     ALLOC POSITION SIZE(0x0)
358
*     EXEC ADDR(0x5) CNT(0x1)
359
*           ALU:	MAXv	export62 = R2, R2	; gl_Position
360
*     ALLOC PARAM/PIXEL SIZE(0x0)
361
*     EXEC_END ADDR(0x6) CNT(0x1)
362
*           ALU:	MAXv	export0 = R1, R1
363
*     NOP
364
 */
365
static struct fd2_shader_stateobj *
366
create_blit_vp(void)
367
{
368
	struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX);
369
	struct ir2_cf *cf;
370
	struct ir2_instruction *instr;
371
 
372
	if (!so)
373
		return NULL;
374
 
375
	so->ir = ir2_shader_create();
376
 
377
	cf = ir2_cf_create(so->ir, EXEC);
378
 
379
	instr = ir2_instr_create_vtx_fetch(cf, 26, 1, FMT_32_32_FLOAT, false, 8);
380
	instr->fetch.is_normalized = true;
381
	ir2_reg_create(instr, 1, "xy01", 0);
382
	ir2_reg_create(instr, 0, "x", 0);
383
 
384
	instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12);
385
	instr->fetch.is_normalized = true;
386
	ir2_reg_create(instr, 2, "xyz1", 0);
387
	ir2_reg_create(instr, 0, "x", 0);
388
 
389
	cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0);
390
	cf = ir2_cf_create(so->ir, EXEC);
391
 
392
	instr = ir2_instr_create_alu(cf, MAXv, ~0);
393
	ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT);
394
	ir2_reg_create(instr, 2, NULL, 0);
395
	ir2_reg_create(instr, 2, NULL, 0);
396
 
397
	cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
398
	cf = ir2_cf_create(so->ir, EXEC_END);
399
 
400
	instr = ir2_instr_create_alu(cf, MAXv, ~0);
401
	ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
402
	ir2_reg_create(instr, 1, NULL, 0);
403
	ir2_reg_create(instr, 1, NULL, 0);
404
 
405
	return assemble(so);
406
}
407
 
408
/* Creates shader:
409
 *    ALLOC PARAM/PIXEL SIZE(0x0)
410
 *    EXEC_END ADDR(0x1) CNT(0x1)
411
 *          ALU:	MAXv	export0 = C0, C0	; gl_FragColor
412
 */
413
static struct fd2_shader_stateobj *
414
create_solid_fp(void)
415
{
416
	struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT);
417
	struct ir2_cf *cf;
418
	struct ir2_instruction *instr;
419
 
420
	if (!so)
421
		return NULL;
422
 
423
	so->ir = ir2_shader_create();
424
 
425
	cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
426
	cf = ir2_cf_create(so->ir, EXEC_END);
427
 
428
	instr = ir2_instr_create_alu(cf, MAXv, ~0);
429
	ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT);
430
	ir2_reg_create(instr, 0, NULL, IR2_REG_CONST);
431
	ir2_reg_create(instr, 0, NULL, IR2_REG_CONST);
432
 
433
	return assemble(so);
434
}
435
 
436
/* Creates shader:
437
 *    EXEC ADDR(0x3) CNT(0x1)
438
 *       (S)FETCH:	VERTEX	R1.xyz1 = R0.x FMT_32_32_32_FLOAT
439
 *                           UNSIGNED STRIDE(12) CONST(26, 0)
440
 *    ALLOC POSITION SIZE(0x0)
441
 *    EXEC ADDR(0x4) CNT(0x1)
442
 *          ALU:	MAXv	export62 = R1, R1	; gl_Position
443
 *    ALLOC PARAM/PIXEL SIZE(0x0)
444
 *    EXEC_END ADDR(0x5) CNT(0x0)
445
 */
446
static struct fd2_shader_stateobj *
447
create_solid_vp(void)
448
{
449
	struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX);
450
	struct ir2_cf *cf;
451
	struct ir2_instruction *instr;
452
 
453
	if (!so)
454
		return NULL;
455
 
456
	so->ir = ir2_shader_create();
457
 
458
	cf = ir2_cf_create(so->ir, EXEC);
459
 
460
	instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12);
461
	ir2_reg_create(instr, 1, "xyz1", 0);
462
	ir2_reg_create(instr, 0, "x", 0);
463
 
464
	cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0);
465
	cf = ir2_cf_create(so->ir, EXEC);
466
 
467
	instr = ir2_instr_create_alu(cf, MAXv, ~0);
468
	ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT);
469
	ir2_reg_create(instr, 1, NULL, 0);
470
	ir2_reg_create(instr, 1, NULL, 0);
471
 
472
	cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0);
473
	cf = ir2_cf_create(so->ir, EXEC_END);
474
 
475
	return assemble(so);
476
}
477
 
478
void
479
fd2_prog_init(struct pipe_context *pctx)
480
{
481
	struct fd_context *ctx = fd_context(pctx);
482
 
483
	pctx->create_fs_state = fd2_fp_state_create;
484
	pctx->bind_fs_state = fd2_fp_state_bind;
485
	pctx->delete_fs_state = fd2_fp_state_delete;
486
 
487
	pctx->create_vs_state = fd2_vp_state_create;
488
	pctx->bind_vs_state = fd2_vp_state_bind;
489
	pctx->delete_vs_state = fd2_vp_state_delete;
490
 
491
	ctx->solid_prog.fp = create_solid_fp();
492
	ctx->solid_prog.vp = create_solid_vp();
493
	ctx->blit_prog.fp = create_blit_fp();
494
	ctx->blit_prog.vp = create_blit_vp();
495
}
496
 
497
void
498
fd2_prog_fini(struct pipe_context *pctx)
499
{
500
	struct fd_context *ctx = fd_context(pctx);
501
 
502
	delete_shader(ctx->solid_prog.vp);
503
	delete_shader(ctx->solid_prog.fp);
504
	delete_shader(ctx->blit_prog.vp);
505
	delete_shader(ctx->blit_prog.fp);
506
}