2 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Rob Clark <robclark@freedesktop.org>
25 * Jonathan Marek <jonathan@marek.ca>
28 #include "pipe/p_state.h"
29 #include "util/u_string.h"
30 #include "util/u_memory.h"
31 #include "util/u_inlines.h"
32 #include "util/format/u_format.h"
33 #include "tgsi/tgsi_dump.h"
34 #include "tgsi/tgsi_parse.h"
35 #include "nir/tgsi_to_nir.h"
37 #include "freedreno_program.h"
40 #include "fd2_program.h"
41 #include "fd2_texture.h"
43 #include "instr-a2xx.h"
45 static struct fd2_shader_stateobj
*
46 create_shader(struct pipe_context
*pctx
, gl_shader_stage type
)
48 struct fd2_shader_stateobj
*so
= CALLOC_STRUCT(fd2_shader_stateobj
);
52 so
->is_a20x
= is_a20x(fd_context(pctx
)->screen
);
57 delete_shader(struct fd2_shader_stateobj
*so
)
62 for (int i
= 0; i
< ARRAY_SIZE(so
->variant
); i
++)
63 free(so
->variant
[i
].info
.dwords
);
68 emit(struct fd_ringbuffer
*ring
, gl_shader_stage type
,
69 struct ir2_shader_info
*info
, struct util_dynarray
*patches
)
73 assert(info
->sizedwords
);
75 OUT_PKT3(ring
, CP_IM_LOAD_IMMEDIATE
, 2 + info
->sizedwords
);
76 OUT_RING(ring
, type
== MESA_SHADER_FRAGMENT
);
77 OUT_RING(ring
, info
->sizedwords
);
80 util_dynarray_append(patches
, uint32_t*, &ring
->cur
[info
->mem_export_ptr
]);
82 for (i
= 0; i
< info
->sizedwords
; i
++)
83 OUT_RING(ring
, info
->dwords
[i
]);
87 ir2_glsl_type_size(const struct glsl_type
*type
, bool bindless
)
89 return glsl_count_attribute_slots(type
, false);
93 fd2_fp_state_create(struct pipe_context
*pctx
,
94 const struct pipe_shader_state
*cso
)
96 struct fd2_shader_stateobj
*so
= create_shader(pctx
, MESA_SHADER_FRAGMENT
);
100 so
->nir
= (cso
->type
== PIPE_SHADER_IR_NIR
) ? cso
->ir
.nir
:
101 tgsi_to_nir(cso
->tokens
, pctx
->screen
);
103 NIR_PASS_V(so
->nir
, nir_lower_io
, nir_var_all
, ir2_glsl_type_size
,
104 (nir_lower_io_options
)0);
106 if (ir2_optimize_nir(so
->nir
, true))
109 so
->first_immediate
= so
->nir
->num_uniforms
;
111 ir2_compile(so
, 0, NULL
);
113 ralloc_free(so
->nir
);
123 fd2_fp_state_delete(struct pipe_context
*pctx
, void *hwcso
)
125 struct fd2_shader_stateobj
*so
= hwcso
;
130 fd2_vp_state_create(struct pipe_context
*pctx
,
131 const struct pipe_shader_state
*cso
)
133 struct fd2_shader_stateobj
*so
= create_shader(pctx
, MESA_SHADER_VERTEX
);
137 so
->nir
= (cso
->type
== PIPE_SHADER_IR_NIR
) ? cso
->ir
.nir
:
138 tgsi_to_nir(cso
->tokens
, pctx
->screen
);
140 NIR_PASS_V(so
->nir
, nir_lower_io
, nir_var_all
, ir2_glsl_type_size
,
141 (nir_lower_io_options
)0);
143 if (ir2_optimize_nir(so
->nir
, true))
146 so
->first_immediate
= so
->nir
->num_uniforms
;
148 /* compile binning variant now */
149 ir2_compile(so
, 0, NULL
);
159 fd2_vp_state_delete(struct pipe_context
*pctx
, void *hwcso
)
161 struct fd2_shader_stateobj
*so
= hwcso
;
166 patch_vtx_fetch(struct fd_context
*ctx
, struct pipe_vertex_element
*elem
,
167 instr_fetch_vtx_t
*instr
, uint16_t dst_swiz
)
169 struct surface_format fmt
= fd2_pipe2surface(elem
->src_format
);
171 instr
->dst_swiz
= fd2_vtx_swiz(elem
->src_format
, dst_swiz
);
172 instr
->format_comp_all
= fmt
.sign
== SQ_TEX_SIGN_SIGNED
;
173 instr
->num_format_all
= fmt
.num_format
;
174 instr
->format
= fmt
.format
;
175 instr
->exp_adjust_all
= fmt
.exp_adjust
;
176 instr
->stride
= ctx
->vtx
.vertexbuf
.vb
[elem
->vertex_buffer_index
].stride
;
177 instr
->offset
= elem
->src_offset
;
181 patch_fetches(struct fd_context
*ctx
, struct ir2_shader_info
*info
,
182 struct fd_vertex_stateobj
*vtx
, struct fd_texture_stateobj
*tex
)
184 for (int i
= 0; i
< info
->num_fetch_instrs
; i
++) {
185 struct ir2_fetch_info
*fi
= &info
->fetch_info
[i
];
187 instr_fetch_t
*instr
= (instr_fetch_t
*) &info
->dwords
[fi
->offset
];
188 if (instr
->opc
== VTX_FETCH
) {
189 unsigned idx
= (instr
->vtx
.const_index
- 20) * 3 +
190 instr
->vtx
.const_index_sel
;
191 patch_vtx_fetch(ctx
, &vtx
->pipe
[idx
], &instr
->vtx
, fi
->vtx
.dst_swiz
);
195 assert(instr
->opc
== TEX_FETCH
);
196 instr
->tex
.const_idx
= fd2_get_const_idx(ctx
, tex
, fi
->tex
.samp_id
);
197 instr
->tex
.src_swiz
= fi
->tex
.src_swiz
;
202 fd2_program_emit(struct fd_context
*ctx
, struct fd_ringbuffer
*ring
,
203 struct fd_program_stateobj
*prog
)
205 struct fd2_shader_stateobj
*fp
= NULL
, *vp
;
206 struct ir2_shader_info
*fpi
, *vpi
;
207 struct ir2_frag_linkage
*f
;
208 uint8_t vs_gprs
, fs_gprs
= 0, vs_export
= 0;
209 enum a2xx_sq_ps_vtx_mode mode
= POSITION_1_VECTOR
;
210 bool binning
= (ctx
->batch
&& ring
== ctx
->batch
->binning
);
211 unsigned variant
= 0;
215 /* find variant matching the linked fragment shader */
218 for (variant
= 1; variant
< ARRAY_SIZE(vp
->variant
); variant
++) {
219 /* if checked all variants, compile a new variant */
220 if (!vp
->variant
[variant
].info
.sizedwords
) {
221 ir2_compile(vp
, variant
, fp
);
225 /* check if fragment shader linkage matches */
226 if (!memcmp(&vp
->variant
[variant
].f
, &fp
->variant
[0].f
,
227 sizeof(struct ir2_frag_linkage
)))
230 assert(variant
< ARRAY_SIZE(vp
->variant
));
233 vpi
= &vp
->variant
[variant
].info
;
234 fpi
= &fp
->variant
[0].info
;
235 f
= &fp
->variant
[0].f
;
237 /* clear/gmem2mem/mem2gmem need to be changed to remove this condition */
238 if (prog
!= &ctx
->solid_prog
&& prog
!= &ctx
->blit_prog
[0]) {
239 patch_fetches(ctx
, vpi
, ctx
->vtx
.vtx
, &ctx
->tex
[PIPE_SHADER_VERTEX
]);
241 patch_fetches(ctx
, fpi
, NULL
, &ctx
->tex
[PIPE_SHADER_FRAGMENT
]);
244 emit(ring
, MESA_SHADER_VERTEX
, vpi
,
245 binning
? &ctx
->batch
->shader_patches
: NULL
);
248 emit(ring
, MESA_SHADER_FRAGMENT
, fpi
, NULL
);
249 fs_gprs
= (fpi
->max_reg
< 0) ? 0x80 : fpi
->max_reg
;
250 vs_export
= MAX2(1, f
->inputs_count
) - 1;
253 vs_gprs
= (vpi
->max_reg
< 0) ? 0x80 : vpi
->max_reg
;
255 if (vp
->writes_psize
&& !binning
)
256 mode
= POSITION_2_VECTORS_SPRITE
;
258 /* set register to use for param (fragcoord/pointcoord/frontfacing) */
259 OUT_PKT3(ring
, CP_SET_CONSTANT
, 2);
260 OUT_RING(ring
, CP_REG(REG_A2XX_SQ_CONTEXT_MISC
));
261 OUT_RING(ring
, A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL(CENTERS_ONLY
) |
262 COND(fp
, A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS(f
->inputs_count
)) |
263 /* we need SCREEN_XY for both fragcoord and frontfacing */
264 A2XX_SQ_CONTEXT_MISC_SC_OUTPUT_SCREEN_XY
);
266 OUT_PKT3(ring
, CP_SET_CONSTANT
, 2);
267 OUT_RING(ring
, CP_REG(REG_A2XX_SQ_PROGRAM_CNTL
));
268 OUT_RING(ring
, A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE(2) |
269 A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE(mode
) |
270 A2XX_SQ_PROGRAM_CNTL_VS_RESOURCE
|
271 A2XX_SQ_PROGRAM_CNTL_PS_RESOURCE
|
272 A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(vs_export
) |
273 A2XX_SQ_PROGRAM_CNTL_PS_REGS(fs_gprs
) |
274 A2XX_SQ_PROGRAM_CNTL_VS_REGS(vs_gprs
) |
275 COND(fp
&& fp
->need_param
, A2XX_SQ_PROGRAM_CNTL_PARAM_GEN
) |
276 COND(!fp
, A2XX_SQ_PROGRAM_CNTL_GEN_INDEX_VTX
));
280 fd2_prog_init(struct pipe_context
*pctx
)
282 struct fd_context
*ctx
= fd_context(pctx
);
283 struct fd_program_stateobj
*prog
;
284 struct fd2_shader_stateobj
*so
;
285 struct ir2_shader_info
*info
;
286 instr_fetch_vtx_t
*instr
;
288 pctx
->create_fs_state
= fd2_fp_state_create
;
289 pctx
->delete_fs_state
= fd2_fp_state_delete
;
291 pctx
->create_vs_state
= fd2_vp_state_create
;
292 pctx
->delete_vs_state
= fd2_vp_state_delete
;
296 /* XXX maybe its possible to reuse patch_vtx_fetch somehow? */
298 prog
= &ctx
->solid_prog
;
300 ir2_compile(prog
->vs
, 1, prog
->fs
);
302 #define IR2_FETCH_SWIZ_XY01 0xb08
303 #define IR2_FETCH_SWIZ_XYZ1 0xa88
305 info
= &so
->variant
[1].info
;
307 instr
= (instr_fetch_vtx_t
*) &info
->dwords
[info
->fetch_info
[0].offset
];
308 instr
->const_index
= 26;
309 instr
->const_index_sel
= 0;
310 instr
->format
= FMT_32_32_32_FLOAT
;
311 instr
->format_comp_all
= false;
313 instr
->num_format_all
= true;
314 instr
->dst_swiz
= IR2_FETCH_SWIZ_XYZ1
;
316 prog
= &ctx
->blit_prog
[0];
318 ir2_compile(prog
->vs
, 1, prog
->fs
);
320 info
= &so
->variant
[1].info
;
322 instr
= (instr_fetch_vtx_t
*) &info
->dwords
[info
->fetch_info
[0].offset
];
323 instr
->const_index
= 26;
324 instr
->const_index_sel
= 1;
325 instr
->format
= FMT_32_32_FLOAT
;
326 instr
->format_comp_all
= false;
328 instr
->num_format_all
= false;
329 instr
->dst_swiz
= IR2_FETCH_SWIZ_XY01
;
331 instr
= (instr_fetch_vtx_t
*) &info
->dwords
[info
->fetch_info
[1].offset
];
332 instr
->const_index
= 26;
333 instr
->const_index_sel
= 0;
334 instr
->format
= FMT_32_32_32_FLOAT
;
335 instr
->format_comp_all
= false;
337 instr
->num_format_all
= false;
338 instr
->dst_swiz
= IR2_FETCH_SWIZ_XYZ1
;