2 * Copyright (C) 2009 Maciej Cencora <m.cencora@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include "radeon_common.h"
29 #include "r300_context.h"
31 #include "r300_blit.h"
32 #include "r300_cmdbuf.h"
33 #include "r300_emit.h"
35 #include "compiler/radeon_compiler.h"
36 #include "compiler/radeon_opcodes.h"
40 * - handle depth buffer
41 * - r300 fp and rs setup
44 static void vp_ins_outs(struct r300_vertex_program_compiler
*c
)
46 c
->code
->inputs
[VERT_ATTRIB_POS
] = 0;
47 c
->code
->inputs
[VERT_ATTRIB_TEX0
] = 1;
48 c
->code
->outputs
[VERT_RESULT_HPOS
] = 0;
49 c
->code
->outputs
[VERT_RESULT_TEX0
] = 1;
52 static void fp_allocate_hw_inputs(
53 struct r300_fragment_program_compiler
* c
,
54 void (*allocate
)(void * data
, unsigned input
, unsigned hwreg
),
57 allocate(mydata
, FRAG_ATTRIB_TEX0
, 0);
60 static void create_vertex_program(struct r300_context
*r300
)
62 struct r300_vertex_program_compiler compiler
;
63 struct rc_instruction
*inst
;
65 rc_init(&compiler
.Base
);
67 inst
= rc_insert_new_instruction(&compiler
.Base
, compiler
.Base
.Program
.Instructions
.Prev
);
68 inst
->U
.I
.Opcode
= RC_OPCODE_MOV
;
69 inst
->U
.I
.DstReg
.File
= RC_FILE_OUTPUT
;
70 inst
->U
.I
.DstReg
.Index
= VERT_RESULT_HPOS
;
71 inst
->U
.I
.DstReg
.RelAddr
= 0;
72 inst
->U
.I
.DstReg
.WriteMask
= RC_MASK_XYZW
;
73 inst
->U
.I
.SrcReg
[0].Abs
= 0;
74 inst
->U
.I
.SrcReg
[0].File
= RC_FILE_INPUT
;
75 inst
->U
.I
.SrcReg
[0].Index
= VERT_ATTRIB_POS
;
76 inst
->U
.I
.SrcReg
[0].Negate
= 0;
77 inst
->U
.I
.SrcReg
[0].RelAddr
= 0;
78 inst
->U
.I
.SrcReg
[0].Swizzle
= RC_SWIZZLE_XYZW
;
80 inst
= rc_insert_new_instruction(&compiler
.Base
, compiler
.Base
.Program
.Instructions
.Prev
);
81 inst
->U
.I
.Opcode
= RC_OPCODE_MOV
;
82 inst
->U
.I
.DstReg
.File
= RC_FILE_OUTPUT
;
83 inst
->U
.I
.DstReg
.Index
= VERT_RESULT_TEX0
;
84 inst
->U
.I
.DstReg
.RelAddr
= 0;
85 inst
->U
.I
.DstReg
.WriteMask
= RC_MASK_XYZW
;
86 inst
->U
.I
.SrcReg
[0].Abs
= 0;
87 inst
->U
.I
.SrcReg
[0].File
= RC_FILE_INPUT
;
88 inst
->U
.I
.SrcReg
[0].Index
= VERT_ATTRIB_TEX0
;
89 inst
->U
.I
.SrcReg
[0].Negate
= 0;
90 inst
->U
.I
.SrcReg
[0].RelAddr
= 0;
91 inst
->U
.I
.SrcReg
[0].Swizzle
= RC_SWIZZLE_XYZW
;
93 compiler
.Base
.Program
.InputsRead
= (1 << VERT_ATTRIB_POS
) | (1 << VERT_ATTRIB_TEX0
);
94 compiler
.RequiredOutputs
= compiler
.Base
.Program
.OutputsWritten
= (1 << VERT_RESULT_HPOS
) | (1 << VERT_RESULT_TEX0
);
95 compiler
.SetHwInputOutput
= vp_ins_outs
;
96 compiler
.code
= &r300
->blit
.vp_code
;
98 r3xx_compile_vertex_program(&compiler
);
101 static void create_fragment_program(struct r300_context
*r300
)
103 struct r300_fragment_program_compiler compiler
;
104 struct rc_instruction
*inst
;
106 rc_init(&compiler
.Base
);
108 inst
= rc_insert_new_instruction(&compiler
.Base
, compiler
.Base
.Program
.Instructions
.Prev
);
109 inst
->U
.I
.Opcode
= RC_OPCODE_TEX
;
110 inst
->U
.I
.TexSrcTarget
= RC_TEXTURE_2D
;
111 inst
->U
.I
.TexSrcUnit
= 0;
112 inst
->U
.I
.DstReg
.File
= RC_FILE_OUTPUT
;
113 inst
->U
.I
.DstReg
.Index
= FRAG_RESULT_COLOR
;
114 inst
->U
.I
.DstReg
.WriteMask
= RC_MASK_XYZW
;
115 inst
->U
.I
.SrcReg
[0].Abs
= 0;
116 inst
->U
.I
.SrcReg
[0].File
= RC_FILE_INPUT
;
117 inst
->U
.I
.SrcReg
[0].Index
= FRAG_ATTRIB_TEX0
;
118 inst
->U
.I
.SrcReg
[0].Negate
= 0;
119 inst
->U
.I
.SrcReg
[0].RelAddr
= 0;
120 inst
->U
.I
.SrcReg
[0].Swizzle
= RC_SWIZZLE_XYZW
;
122 compiler
.Base
.Program
.InputsRead
= (1 << FRAG_ATTRIB_TEX0
);
123 compiler
.OutputColor
= FRAG_RESULT_COLOR
;
124 compiler
.OutputDepth
= FRAG_RESULT_DEPTH
;
125 compiler
.is_r500
= (r300
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
);
126 compiler
.code
= &r300
->blit
.fp_code
;
127 compiler
.AllocateHwInputs
= fp_allocate_hw_inputs
;
129 r3xx_compile_fragment_program(&compiler
);
132 void r300_blit_init(struct r300_context
*r300
)
134 create_vertex_program(r300
);
135 create_fragment_program(r300
);
138 static void r500_emit_rs_setup(struct r300_context
*r300
)
140 BATCH_LOCALS(&r300
->radeon
);
143 OUT_BATCH_REGSEQ(R300_RS_COUNT
, 2);
144 OUT_BATCH((4 << R300_IT_COUNT_SHIFT
) | R300_HIRES_EN
);
146 OUT_BATCH_REGVAL(R500_RS_INST_0
,
147 (0 << R500_RS_INST_TEX_ID_SHIFT
) |
148 (0 << R500_RS_INST_TEX_ADDR_SHIFT
) |
149 R500_RS_INST_TEX_CN_WRITE
|
150 R500_RS_INST_COL_CN_NO_WRITE
);
151 OUT_BATCH_REGVAL(R500_RS_IP_0
,
152 (0 << R500_RS_IP_TEX_PTR_S_SHIFT
) |
153 (1 << R500_RS_IP_TEX_PTR_T_SHIFT
) |
154 (2 << R500_RS_IP_TEX_PTR_R_SHIFT
) |
155 (3 << R500_RS_IP_TEX_PTR_Q_SHIFT
));
159 static void r300_emit_fp_setup(struct r300_context
*r300
)
164 static void r300_emit_rs_setup(struct r300_context
*r300
)
169 static void r300_emit_tx_setup(struct r300_context
*r300
,
170 gl_format mesa_format
,
171 struct radeon_bo
*bo
,
177 BATCH_LOCALS(&r300
->radeon
);
179 assert(width
<= 2048);
180 assert(height
<= 2048);
181 assert(r300TranslateTexFormat(mesa_format
) != 0);
182 assert(offset
% 32 == 0);
185 OUT_BATCH_REGVAL(R300_TX_FILTER0_0
,
186 (R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_S_SHIFT
) |
187 (R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_T_SHIFT
) |
188 (R300_TX_CLAMP_TO_EDGE
<< R300_TX_WRAP_R_SHIFT
) |
189 R300_TX_MIN_FILTER_MIP_NONE
|
190 R300_TX_MIN_FILTER_LINEAR
|
191 R300_TX_MAG_FILTER_LINEAR
|
193 OUT_BATCH_REGVAL(R300_TX_FILTER1_0
, 0);
194 OUT_BATCH_REGVAL(R300_TX_SIZE_0
,
195 ((width
-1) << R300_TX_WIDTHMASK_SHIFT
) |
196 ((height
-1) << R300_TX_HEIGHTMASK_SHIFT
) |
197 (0 << R300_TX_DEPTHMASK_SHIFT
) |
198 (0 << R300_TX_MAX_MIP_LEVEL_SHIFT
) |
199 R300_TX_SIZE_TXPITCH_EN
);
201 OUT_BATCH_REGVAL(R300_TX_FORMAT_0
, r300TranslateTexFormat(mesa_format
));
202 OUT_BATCH_REGVAL(R300_TX_FORMAT2_0
, pitch
/_mesa_get_format_bytes(mesa_format
) - 1);
203 OUT_BATCH_REGSEQ(R300_TX_OFFSET_0
, 1);
204 OUT_BATCH_RELOC(0, bo
, offset
, RADEON_GEM_DOMAIN_GTT
|RADEON_GEM_DOMAIN_VRAM
, 0, 0);
206 OUT_BATCH_REGSEQ(R300_TX_INVALTAGS
, 2);
213 #define EASY_US_FORMAT(FMT, C0, C1, C2, C3, SIGN) \
214 (FMT | R500_C0_SEL_##C0 | R500_C1_SEL_##C1 | \
215 R500_C2_SEL_##C2 | R500_C3_SEL_##C3 | R500_OUT_SIGN(SIGN))
217 static uint32_t mesa_format_to_us_format(gl_format mesa_format
)
221 case MESA_FORMAT_S8_Z24
:
222 case MESA_FORMAT_X8_Z24
:
223 case MESA_FORMAT_RGBA8888
: // x
224 return EASY_US_FORMAT(R500_OUT_FMT_C4_8
, A
, B
, G
, R
, 0);
225 case MESA_FORMAT_RGB565
: // x
226 case MESA_FORMAT_ARGB1555
: // x
227 case MESA_FORMAT_RGBA8888_REV
: // x
228 return EASY_US_FORMAT(R500_OUT_FMT_C4_8
, R
, G
, B
, A
, 0);
229 case MESA_FORMAT_ARGB8888
: // x
230 return EASY_US_FORMAT(R500_OUT_FMT_C4_8
, B
, G
, R
, A
, 0);
231 case MESA_FORMAT_ARGB8888_REV
:
232 return EASY_US_FORMAT(R500_OUT_FMT_C4_8
, A
, R
, G
, B
, 0);
233 case MESA_FORMAT_XRGB8888
:
234 return EASY_US_FORMAT(R500_OUT_FMT_C4_8
, A
, R
, G
, B
, 0);
236 case MESA_FORMAT_RGB332
:
237 return EASY_US_FORMAT(R500_OUT_FMT_C_3_3_2
, A
, R
, G
, B
, 0);
239 case MESA_FORMAT_RGBA_FLOAT32
:
240 return EASY_US_FORMAT(R500_OUT_FMT_C4_32_FP
, R
, G
, B
, A
, 0);
241 case MESA_FORMAT_RGBA_FLOAT16
:
242 return EASY_US_FORMAT(R500_OUT_FMT_C4_16_FP
, R
, G
, B
, A
, 0);
243 case MESA_FORMAT_ALPHA_FLOAT32
:
244 return EASY_US_FORMAT(R500_OUT_FMT_C_32_FP
, A
, A
, A
, A
, 0);
245 case MESA_FORMAT_ALPHA_FLOAT16
:
246 return EASY_US_FORMAT(R500_OUT_FMT_C_16_FP
, A
, A
, A
, A
, 0);
248 case MESA_FORMAT_SIGNED_RGBA8888
:
249 return EASY_US_FORMAT(R500_OUT_FMT_C4_8
, R
, G
, B
, A
, 0xf);
250 case MESA_FORMAT_SIGNED_RGBA8888_REV
:
251 return EASY_US_FORMAT(R500_OUT_FMT_C4_8
, A
, B
, G
, R
, 0xf);
252 case MESA_FORMAT_SIGNED_RGBA_16
:
253 return EASY_US_FORMAT(R500_OUT_FMT_C4_16
, R
, G
, B
, A
, 0xf);
256 assert(!"Invalid format for US output\n");
260 #undef EASY_US_FORMAT
262 static void r500_emit_fp_setup(struct r300_context
*r300
,
263 struct r500_fragment_program_code
*fp
,
264 gl_format dst_format
)
266 r500_emit_fp(r300
, (uint32_t *)fp
->inst
, (fp
->inst_end
+ 1) * 6, 0, 0, 0);
267 BATCH_LOCALS(&r300
->radeon
);
270 OUT_BATCH_REGSEQ(R500_US_CODE_ADDR
, 3);
271 OUT_BATCH(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(fp
->inst_end
));
272 OUT_BATCH(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(fp
->inst_end
));
274 OUT_BATCH_REGVAL(R500_US_CONFIG
, 0);
275 OUT_BATCH_REGVAL(R500_US_OUT_FMT_0
, mesa_format_to_us_format(dst_format
));
276 OUT_BATCH_REGVAL(R500_US_PIXSIZE
, fp
->max_temp_idx
);
280 static void emit_pvs_setup(struct r300_context
*r300
,
284 BATCH_LOCALS(&r300
->radeon
);
286 r300_emit_vpu(r300
, vp_code
, vp_len
* 4, R300_PVS_CODE_START
);
289 OUT_BATCH_REGSEQ(R300_VAP_PVS_CODE_CNTL_0
, 3);
290 OUT_BATCH((0 << R300_PVS_FIRST_INST_SHIFT
) |
291 ((vp_len
- 1) << R300_PVS_XYZW_VALID_INST_SHIFT
) |
292 ((vp_len
- 1)<< R300_PVS_LAST_INST_SHIFT
));
294 OUT_BATCH((vp_len
- 1) << R300_PVS_LAST_VTX_SRC_INST_SHIFT
);
298 static void emit_vap_setup(struct r300_context
*r300
, unsigned width
, unsigned height
)
300 BATCH_LOCALS(&r300
->radeon
);
303 OUT_BATCH_REGSEQ(R300_SE_VTE_CNTL
, 2);
304 OUT_BATCH(R300_VTX_XY_FMT
| R300_VTX_Z_FMT
);
307 OUT_BATCH_REGVAL(R300_VAP_PSC_SGN_NORM_CNTL
, 0xaaaaaaaa);
308 OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_0
,
309 ((R300_DATA_TYPE_FLOAT_2
| (0 << R300_DST_VEC_LOC_SHIFT
)) << 0) |
310 (((1 << R300_DST_VEC_LOC_SHIFT
) | R300_DATA_TYPE_FLOAT_2
| R300_LAST_VEC
) << 16));
311 OUT_BATCH_REGVAL(R300_VAP_PROG_STREAM_CNTL_EXT_0
,
312 ((((R300_SWIZZLE_SELECT_X
<< R300_SWIZZLE_SELECT_X_SHIFT
) |
313 (R300_SWIZZLE_SELECT_Y
<< R300_SWIZZLE_SELECT_Y_SHIFT
) |
314 (R300_SWIZZLE_SELECT_FP_ZERO
<< R300_SWIZZLE_SELECT_Z_SHIFT
) |
315 (R300_SWIZZLE_SELECT_FP_ONE
<< R300_SWIZZLE_SELECT_W_SHIFT
) |
316 (0xf << R300_WRITE_ENA_SHIFT
) ) << 0) |
317 (((R300_SWIZZLE_SELECT_X
<< R300_SWIZZLE_SELECT_X_SHIFT
) |
318 (R300_SWIZZLE_SELECT_Y
<< R300_SWIZZLE_SELECT_Y_SHIFT
) |
319 (R300_SWIZZLE_SELECT_FP_ZERO
<< R300_SWIZZLE_SELECT_Z_SHIFT
) |
320 (R300_SWIZZLE_SELECT_FP_ONE
<< R300_SWIZZLE_SELECT_W_SHIFT
) |
321 (0xf << R300_WRITE_ENA_SHIFT
) ) << 16) ) );
322 OUT_BATCH_REGSEQ(R300_VAP_OUTPUT_VTX_FMT_0
, 2);
323 OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT
);
324 OUT_BATCH(R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS
);
328 static GLboolean
validate_buffers(struct r300_context
*r300
,
329 struct radeon_bo
*src_bo
,
330 struct radeon_bo
*dst_bo
)
333 radeon_cs_space_add_persistent_bo(r300
->radeon
.cmdbuf
.cs
,
334 src_bo
, RADEON_GEM_DOMAIN_VRAM
, 0);
336 radeon_cs_space_add_persistent_bo(r300
->radeon
.cmdbuf
.cs
,
337 dst_bo
, 0, RADEON_GEM_DOMAIN_VRAM
);
339 ret
= radeon_cs_space_check_with_bo(r300
->radeon
.cmdbuf
.cs
,
340 first_elem(&r300
->radeon
.dma
.reserved
)->bo
,
341 RADEON_GEM_DOMAIN_GTT
, 0);
348 static void emit_draw_packet(struct r300_context
*r300
, float width
, float height
)
350 float verts
[] = { 0.0, 0.0, 0.0, 1.0,
351 0.0, height
, 0.0, 0.0,
352 width
, height
, 1.0, 0.0,
353 width
, 0.0, 1.0, 1.0 };
355 BATCH_LOCALS(&r300
->radeon
);
358 OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_IMMD_2
, 16);
359 OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED
|
360 (4 << 16) | R300_VAP_VF_CNTL__PRIM_QUADS
);
361 OUT_BATCH_TABLE(verts
, 16);
365 static void other_stuff(struct r300_context
*r300
)
367 BATCH_LOCALS(&r300
->radeon
);
370 OUT_BATCH_REGVAL(R300_GA_POLY_MODE
,
371 R300_GA_POLY_MODE_FRONT_PTYPE_TRI
| R300_GA_POLY_MODE_BACK_PTYPE_TRI
);
372 OUT_BATCH_REGVAL(R300_SU_CULL_MODE
, R300_FRONT_FACE_CCW
);
373 OUT_BATCH_REGVAL(R300_FG_FOG_BLEND
, 0);
374 OUT_BATCH_REGVAL(R300_FG_ALPHA_FUNC
, 0);
375 OUT_BATCH_REGSEQ(R300_RB3D_CBLEND
, 2);
378 OUT_BATCH_REGVAL(R300_VAP_CLIP_CNTL
, R300_CLIP_DISABLE
);
379 OUT_BATCH_REGVAL(R300_ZB_CNTL
, 0);
383 static void emit_cb_setup(struct r300_context
*r300
,
384 struct radeon_bo
*bo
,
386 gl_format mesa_format
,
390 BATCH_LOCALS(&r300
->radeon
);
392 unsigned x1
, y1
, x2
, y2
;
398 if (r300
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV515
) {
399 x1
+= R300_SCISSORS_OFFSET
;
400 y1
+= R300_SCISSORS_OFFSET
;
401 x2
+= R300_SCISSORS_OFFSET
;
402 y2
+= R300_SCISSORS_OFFSET
;
405 r300_emit_cb_setup(r300
, bo
, offset
, mesa_format
,
406 _mesa_get_format_bytes(mesa_format
),
407 _mesa_format_row_stride(mesa_format
, width
));
409 BEGIN_BATCH_NO_AUTOSTATE(3);
410 OUT_BATCH_REGSEQ(R300_SC_SCISSORS_TL
, 2);
411 OUT_BATCH((x1
<< R300_SCISSORS_X_SHIFT
)|(y1
<< R300_SCISSORS_Y_SHIFT
));
412 OUT_BATCH((x2
<< R300_SCISSORS_X_SHIFT
)|(y2
<< R300_SCISSORS_Y_SHIFT
));
416 GLboolean
r300_blit(struct r300_context
*r300
,
417 struct radeon_bo
*src_bo
,
419 gl_format src_mesaformat
,
423 struct radeon_bo
*dst_bo
,
425 gl_format dst_mesaformat
,
429 //assert(src_width == dst_width);
430 //assert(src_height == dst_height);
432 if (src_bo
== dst_bo
) {
439 fprintf(stderr
, "src: width %d, height %d, pitch %d vs %d, format %s\n",
440 src_width
, src_height
, src_pitch
,
441 _mesa_format_row_stride(src_mesaformat
, src_width
),
442 _mesa_get_format_name(src_mesaformat
));
443 fprintf(stderr
, "dst: width %d, height %d, pitch %d, format %s\n",
444 dst_width
, dst_height
,
445 _mesa_format_row_stride(dst_mesaformat
, dst_width
),
446 _mesa_get_format_name(dst_mesaformat
));
449 if (!validate_buffers(r300
, src_bo
, dst_bo
))
452 rcommonEnsureCmdBufSpace(&r300
->radeon
, 200, __FUNCTION__
);
456 r300_emit_tx_setup(r300
, src_mesaformat
, src_bo
, src_offset
, src_width
, src_height
, src_pitch
);
458 if (r300
->radeon
.radeonScreen
->chip_family
>= CHIP_FAMILY_RV515
) {
459 r500_emit_fp_setup(r300
, &r300
->blit
.fp_code
.code
.r500
, dst_mesaformat
);
460 r500_emit_rs_setup(r300
);
462 r300_emit_fp_setup(r300
);
463 r300_emit_rs_setup(r300
);
466 emit_pvs_setup(r300
, r300
->blit
.vp_code
.body
.d
, 2);
467 emit_vap_setup(r300
, dst_width
, dst_height
);
469 emit_cb_setup(r300
, dst_bo
, dst_offset
, dst_mesaformat
, dst_width
, dst_height
);
471 emit_draw_packet(r300
, dst_width
, dst_height
);
473 r300EmitCacheFlush(r300
);
475 radeonFlush(r300
->radeon
.glCtx
);
476 //r300ResetHwState(r300);