1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
4 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
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:
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
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
26 * Rob Clark <robclark@freedesktop.org>
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"
37 #include "freedreno_program.h"
39 #include "fd2_program.h"
40 #include "fd2_compiler.h"
41 #include "fd2_texture.h"
44 static struct fd2_shader_stateobj
*
45 create_shader(enum shader_t type
)
47 struct fd2_shader_stateobj
*so
= CALLOC_STRUCT(fd2_shader_stateobj
);
55 delete_shader(struct fd2_shader_stateobj
*so
)
59 ir2_shader_destroy(so
->ir
);
65 static struct fd2_shader_stateobj
*
66 assemble(struct fd2_shader_stateobj
*so
)
69 so
->bin
= ir2_shader_assemble(so
->ir
, &so
->info
);
73 if (fd_mesa_debug
& FD_DBG_DISASM
) {
74 DBG("disassemble: type=%d", so
->type
);
75 disasm_a2xx(so
->bin
, so
->info
.sizedwords
, 0, so
->type
);
81 debug_error("assemble failed!");
86 static struct fd2_shader_stateobj
*
87 compile(struct fd_program_stateobj
*prog
, struct fd2_shader_stateobj
*so
)
91 if (fd_mesa_debug
& FD_DBG_DISASM
) {
92 DBG("dump tgsi: type=%d", so
->type
);
93 tgsi_dump(so
->tokens
, 0);
96 ret
= fd2_compile_shader(prog
, so
);
100 /* NOTE: we don't assemble yet because for VS we don't know the
101 * type information for vertex fetch yet.. so those need to be
102 * patched up later before assembling.
105 so
->info
.sizedwords
= 0;
110 debug_error("compile failed!");
116 emit(struct fd_ringbuffer
*ring
, struct fd2_shader_stateobj
*so
)
120 if (so
->info
.sizedwords
== 0)
123 OUT_PKT3(ring
, CP_IM_LOAD_IMMEDIATE
, 2 + so
->info
.sizedwords
);
124 OUT_RING(ring
, (so
->type
== SHADER_VERTEX
) ? 0 : 1);
125 OUT_RING(ring
, so
->info
.sizedwords
);
126 for (i
= 0; i
< so
->info
.sizedwords
; i
++)
127 OUT_RING(ring
, so
->bin
[i
]);
131 fd2_fp_state_create(struct pipe_context
*pctx
,
132 const struct pipe_shader_state
*cso
)
134 struct fd2_shader_stateobj
*so
= create_shader(SHADER_FRAGMENT
);
137 so
->tokens
= tgsi_dup_tokens(cso
->tokens
);
142 fd2_fp_state_delete(struct pipe_context
*pctx
, void *hwcso
)
144 struct fd2_shader_stateobj
*so
= hwcso
;
149 fd2_vp_state_create(struct pipe_context
*pctx
,
150 const struct pipe_shader_state
*cso
)
152 struct fd2_shader_stateobj
*so
= create_shader(SHADER_VERTEX
);
155 so
->tokens
= tgsi_dup_tokens(cso
->tokens
);
160 fd2_vp_state_delete(struct pipe_context
*pctx
, void *hwcso
)
162 struct fd2_shader_stateobj
*so
= hwcso
;
167 patch_vtx_fetches(struct fd_context
*ctx
, struct fd2_shader_stateobj
*so
,
168 struct fd_vertex_stateobj
*vtx
)
172 assert(so
->num_vfetch_instrs
== vtx
->num_elements
);
174 /* update vtx fetch instructions: */
175 for (i
= 0; i
< so
->num_vfetch_instrs
; i
++) {
176 struct ir2_instruction
*instr
= so
->vfetch_instrs
[i
];
177 struct pipe_vertex_element
*elem
= &vtx
->pipe
[i
];
178 struct pipe_vertex_buffer
*vb
=
179 &ctx
->vtx
.vertexbuf
.vb
[elem
->vertex_buffer_index
];
180 enum pipe_format format
= elem
->src_format
;
181 const struct util_format_description
*desc
=
182 util_format_description(format
);
185 /* Find the first non-VOID channel. */
186 for (j
= 0; j
< 4; j
++)
187 if (desc
->channel
[j
].type
!= UTIL_FORMAT_TYPE_VOID
)
190 /* CI/CIS can probably be set in compiler instead: */
191 instr
->fetch
.const_idx
= 20 + (i
/ 3);
192 instr
->fetch
.const_idx_sel
= i
% 3;
194 instr
->fetch
.fmt
= fd2_pipe2surface(format
);
195 instr
->fetch
.is_normalized
= desc
->channel
[j
].normalized
;
196 instr
->fetch
.is_signed
=
197 desc
->channel
[j
].type
== UTIL_FORMAT_TYPE_SIGNED
;
198 instr
->fetch
.stride
= vb
->stride
? : 1;
199 instr
->fetch
.offset
= elem
->src_offset
;
201 for (j
= 0; j
< 4; j
++)
202 instr
->dst_reg
.swizzle
[j
] = "xyzw01__"[desc
->swizzle
[j
]];
204 assert(instr
->fetch
.fmt
!= ~0);
206 DBG("vtx[%d]: %s (%d), ci=%d, cis=%d, id=%d, swizzle=%s, "
207 "stride=%d, offset=%d",
208 i
, util_format_name(format
),
210 instr
->fetch
.const_idx
,
211 instr
->fetch
.const_idx_sel
,
212 elem
->instance_divisor
,
213 instr
->dst_reg
.swizzle
,
215 instr
->fetch
.offset
);
218 /* trigger re-assemble: */
219 so
->info
.sizedwords
= 0;
223 patch_tex_fetches(struct fd_context
*ctx
, struct fd2_shader_stateobj
*so
,
224 struct fd_texture_stateobj
*tex
)
228 /* update tex fetch instructions: */
229 for (i
= 0; i
< so
->num_tfetch_instrs
; i
++) {
230 struct ir2_instruction
*instr
= so
->tfetch_instrs
[i
].instr
;
231 unsigned samp_id
= so
->tfetch_instrs
[i
].samp_id
;
232 unsigned const_idx
= fd2_get_const_idx(ctx
, tex
, samp_id
);
234 if (const_idx
!= instr
->fetch
.const_idx
) {
235 instr
->fetch
.const_idx
= const_idx
;
236 /* trigger re-assemble: */
237 so
->info
.sizedwords
= 0;
243 fd2_program_validate(struct fd_context
*ctx
)
245 struct fd_program_stateobj
*prog
= &ctx
->prog
;
246 bool dirty_fp
= !!(ctx
->dirty_shader
[PIPE_SHADER_FRAGMENT
] & FD_DIRTY_SHADER_PROG
);
247 bool dirty_vp
= !!(ctx
->dirty_shader
[PIPE_SHADER_VERTEX
] & FD_DIRTY_SHADER_PROG
);
249 /* if vertex or frag shader is dirty, we may need to recompile. Compile
250 * frag shader first, as that assigns the register slots for exports
251 * from the vertex shader. And therefore if frag shader has changed we
252 * need to recompile both vert and frag shader.
255 compile(prog
, prog
->fp
);
257 if (dirty_fp
|| dirty_vp
)
258 compile(prog
, prog
->vp
);
260 /* if necessary, fix up vertex fetch instructions: */
261 if (ctx
->dirty
& (FD_DIRTY_VTXSTATE
| FD_DIRTY_PROG
))
262 patch_vtx_fetches(ctx
, prog
->vp
, ctx
->vtx
.vtx
);
264 /* if necessary, fix up texture fetch instructions: */
265 if (ctx
->dirty
& (FD_DIRTY_TEXSTATE
| FD_DIRTY_PROG
)) {
266 patch_tex_fetches(ctx
, prog
->vp
, &ctx
->tex
[PIPE_SHADER_VERTEX
]);
267 patch_tex_fetches(ctx
, prog
->fp
, &ctx
->tex
[PIPE_SHADER_FRAGMENT
]);
272 fd2_program_emit(struct fd_ringbuffer
*ring
,
273 struct fd_program_stateobj
*prog
)
275 struct ir2_shader_info
*vsi
=
276 &((struct fd2_shader_stateobj
*)prog
->vp
)->info
;
277 struct ir2_shader_info
*fsi
=
278 &((struct fd2_shader_stateobj
*)prog
->fp
)->info
;
279 uint8_t vs_gprs
, fs_gprs
, vs_export
;
281 emit(ring
, prog
->vp
);
282 emit(ring
, prog
->fp
);
284 vs_gprs
= (vsi
->max_reg
< 0) ? 0x80 : vsi
->max_reg
;
285 fs_gprs
= (fsi
->max_reg
< 0) ? 0x80 : fsi
->max_reg
;
286 vs_export
= MAX2(1, prog
->num_exports
) - 1;
288 OUT_PKT3(ring
, CP_SET_CONSTANT
, 2);
289 OUT_RING(ring
, CP_REG(REG_A2XX_SQ_PROGRAM_CNTL
));
290 OUT_RING(ring
, A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE(POSITION_2_VECTORS_SPRITE
) |
291 A2XX_SQ_PROGRAM_CNTL_VS_RESOURCE
|
292 A2XX_SQ_PROGRAM_CNTL_PS_RESOURCE
|
293 A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(vs_export
) |
294 A2XX_SQ_PROGRAM_CNTL_PS_REGS(fs_gprs
) |
295 A2XX_SQ_PROGRAM_CNTL_VS_REGS(vs_gprs
));
299 * EXEC ADDR(0x2) CNT(0x1)
300 * (S)FETCH: SAMPLE R0.xyzw = R0.xyx CONST(0) LOCATION(CENTER)
301 * ALLOC PARAM/PIXEL SIZE(0x0)
302 * EXEC_END ADDR(0x3) CNT(0x1)
303 * ALU: MAXv export0 = R0, R0 ; gl_FragColor
306 static struct fd2_shader_stateobj
*
309 struct fd2_shader_stateobj
*so
= create_shader(SHADER_FRAGMENT
);
310 struct ir2_instruction
*instr
;
315 so
->ir
= ir2_shader_create();
317 instr
= ir2_instr_create_tex_fetch(so
->ir
, 0);
318 ir2_dst_create(instr
, 0, "xyzw", 0);
319 ir2_reg_create(instr
, 0, "xyx", IR2_REG_INPUT
);
322 instr
= ir2_instr_create_alu_v(so
->ir
, MAXv
);
323 ir2_dst_create(instr
, 0, NULL
, IR2_REG_EXPORT
);
324 ir2_reg_create(instr
, 0, NULL
, 0);
325 ir2_reg_create(instr
, 0, NULL
, 0);
331 * EXEC ADDR(0x3) CNT(0x2)
332 * FETCH: VERTEX R1.xy01 = R0.x FMT_32_32_FLOAT UNSIGNED STRIDE(8) CONST(26, 1)
333 * FETCH: VERTEX R2.xyz1 = R0.x FMT_32_32_32_FLOAT UNSIGNED STRIDE(12) CONST(26, 0)
334 * ALLOC POSITION SIZE(0x0)
335 * EXEC ADDR(0x5) CNT(0x1)
336 * ALU: MAXv export62 = R2, R2 ; gl_Position
337 * ALLOC PARAM/PIXEL SIZE(0x0)
338 * EXEC_END ADDR(0x6) CNT(0x1)
339 * ALU: MAXv export0 = R1, R1
342 static struct fd2_shader_stateobj
*
345 struct fd2_shader_stateobj
*so
= create_shader(SHADER_VERTEX
);
346 struct ir2_instruction
*instr
;
351 so
->ir
= ir2_shader_create();
353 instr
= ir2_instr_create_vtx_fetch(so
->ir
, 26, 1, FMT_32_32_FLOAT
, false, 8);
354 instr
->fetch
.is_normalized
= true;
355 ir2_dst_create(instr
, 1, "xy01", 0);
356 ir2_reg_create(instr
, 0, "x", IR2_REG_INPUT
);
358 instr
= ir2_instr_create_vtx_fetch(so
->ir
, 26, 0, FMT_32_32_32_FLOAT
, false, 12);
359 instr
->fetch
.is_normalized
= true;
360 ir2_dst_create(instr
, 2, "xyz1", 0);
361 ir2_reg_create(instr
, 0, "x", IR2_REG_INPUT
);
363 instr
= ir2_instr_create_alu_v(so
->ir
, MAXv
);
364 ir2_dst_create(instr
, 62, NULL
, IR2_REG_EXPORT
);
365 ir2_reg_create(instr
, 2, NULL
, 0);
366 ir2_reg_create(instr
, 2, NULL
, 0);
368 instr
= ir2_instr_create_alu_v(so
->ir
, MAXv
);
369 ir2_dst_create(instr
, 0, NULL
, IR2_REG_EXPORT
);
370 ir2_reg_create(instr
, 1, NULL
, 0);
371 ir2_reg_create(instr
, 1, NULL
, 0);
377 * ALLOC PARAM/PIXEL SIZE(0x0)
378 * EXEC_END ADDR(0x1) CNT(0x1)
379 * ALU: MAXv export0 = C0, C0 ; gl_FragColor
381 static struct fd2_shader_stateobj
*
382 create_solid_fp(void)
384 struct fd2_shader_stateobj
*so
= create_shader(SHADER_FRAGMENT
);
385 struct ir2_instruction
*instr
;
390 so
->ir
= ir2_shader_create();
392 instr
= ir2_instr_create_alu_v(so
->ir
, MAXv
);
393 ir2_dst_create(instr
, 0, NULL
, IR2_REG_EXPORT
);
394 ir2_reg_create(instr
, 0, NULL
, IR2_REG_CONST
);
395 ir2_reg_create(instr
, 0, NULL
, IR2_REG_CONST
);
401 * EXEC ADDR(0x3) CNT(0x1)
402 * (S)FETCH: VERTEX R1.xyz1 = R0.x FMT_32_32_32_FLOAT
403 * UNSIGNED STRIDE(12) CONST(26, 0)
404 * ALLOC POSITION SIZE(0x0)
405 * EXEC ADDR(0x4) CNT(0x1)
406 * ALU: MAXv export62 = R1, R1 ; gl_Position
407 * ALLOC PARAM/PIXEL SIZE(0x0)
408 * EXEC_END ADDR(0x5) CNT(0x0)
410 static struct fd2_shader_stateobj
*
411 create_solid_vp(void)
413 struct fd2_shader_stateobj
*so
= create_shader(SHADER_VERTEX
);
414 struct ir2_instruction
*instr
;
419 so
->ir
= ir2_shader_create();
421 instr
= ir2_instr_create_vtx_fetch(so
->ir
, 26, 0, FMT_32_32_32_FLOAT
, false, 12);
422 ir2_dst_create(instr
, 1, "xyz1", 0);
423 ir2_reg_create(instr
, 0, "x", IR2_REG_INPUT
);
425 instr
= ir2_instr_create_alu_v(so
->ir
, MAXv
);
426 ir2_dst_create(instr
, 62, NULL
, IR2_REG_EXPORT
);
427 ir2_reg_create(instr
, 1, NULL
, 0);
428 ir2_reg_create(instr
, 1, NULL
, 0);
435 fd2_prog_init(struct pipe_context
*pctx
)
437 struct fd_context
*ctx
= fd_context(pctx
);
439 pctx
->create_fs_state
= fd2_fp_state_create
;
440 pctx
->delete_fs_state
= fd2_fp_state_delete
;
442 pctx
->create_vs_state
= fd2_vp_state_create
;
443 pctx
->delete_vs_state
= fd2_vp_state_delete
;
447 ctx
->solid_prog
.fp
= create_solid_fp();
448 ctx
->solid_prog
.vp
= create_solid_vp();
449 ctx
->blit_prog
[0].fp
= create_blit_fp();
450 ctx
->blit_prog
[0].vp
= create_blit_vp();