2 * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
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 shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * Richard Li <RichardZ.Li@amd.com>, <richardradeon@gmail.com>
25 * CooperYuan <cooper.yuan@amd.com>, <cooperyuan@gmail.com>
28 #include "main/glheader.h"
29 #include "main/state.h"
30 #include "main/imports.h"
31 #include "main/enums.h"
32 #include "main/macros.h"
33 #include "main/context.h"
35 #include "main/simple_list.h"
36 #include "main/api_arrayelt.h"
37 #include "swrast/swrast.h"
38 #include "swrast_setup/swrast_setup.h"
42 #include "tnl/t_vp_build.h"
43 #include "tnl/t_context.h"
44 #include "tnl/t_vertex.h"
45 #include "tnl/t_pipeline.h"
47 #include "r600_context.h"
48 #include "r600_cmdbuf.h"
50 #include "r700_chip.h"
53 #include "r700_vertprog.h"
54 #include "r700_fragprog.h"
55 #include "r700_state.h"
57 void r700WaitForIdle(context_t
*context
)
59 BATCH_LOCALS(&context
->radeon
);
60 BEGIN_BATCH_NO_AUTOSTATE(3);
62 OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG
, 1));
63 OUT_BATCH(mmWAIT_UNTIL
- ASIC_CONFIG_BASE_INDEX
);
70 void r700WaitForIdleClean(context_t
*context
)
72 BATCH_LOCALS(&context
->radeon
);
73 BEGIN_BATCH_NO_AUTOSTATE(5);
75 OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE
, 0));
78 OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG
, 1));
79 OUT_BATCH(mmWAIT_UNTIL
- ASIC_CONFIG_BASE_INDEX
);
86 static void r700Start3D(context_t
*context
)
88 BATCH_LOCALS(&context
->radeon
);
89 if (context
->radeon
.radeonScreen
->chip_family
<= CHIP_FAMILY_RV670
)
91 BEGIN_BATCH_NO_AUTOSTATE(2);
92 OUT_BATCH(CP_PACKET3(R600_IT_START_3D_CMDBUF
, 1));
97 BEGIN_BATCH_NO_AUTOSTATE(3);
98 OUT_BATCH(CP_PACKET3(R600_IT_CONTEXT_CONTROL
, 1));
99 OUT_BATCH(0x80000000);
100 OUT_BATCH(0x80000000);
105 r700WaitForIdleClean(context
);
108 static GLboolean
r700SetupShaders(GLcontext
* ctx
)
110 context_t
*context
= R700_CONTEXT(ctx
);
112 R700_CHIP_CONTEXT
*r700
= (R700_CHIP_CONTEXT
*)(context
->chipobj
.pvChipObj
);
116 r700
->SQ_PGM_RESOURCES_PS
.u32All
= 0;
117 r700
->SQ_PGM_RESOURCES_VS
.u32All
= 0;
119 SETbit(r700
->SQ_PGM_RESOURCES_PS
.u32All
, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit
);
120 SETbit(r700
->SQ_PGM_RESOURCES_VS
.u32All
, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit
);
122 r700SetupVertexProgram(ctx
);
124 r700SetupFragmentProgram(ctx
);
126 exportCount
= (r700
->SQ_PGM_EXPORTS_PS
.u32All
& EXPORT_MODE_mask
) / (1 << EXPORT_MODE_shift
);
127 r700
->CB_SHADER_CONTROL
.u32All
= (1 << exportCount
) - 1;
132 GLboolean
r700SendTextureState(context_t
*context
)
136 R700_CHIP_CONTEXT
*r700
= (R700_CHIP_CONTEXT
*)(context
->chipobj
.pvChipObj
);
137 #if 0 /* to be enabled */
138 for(i
=0; i
<R700_TEXTURE_NUMBERUNITS
; i
++)
140 if(r700
->texture_states
.textures
[i
] != 0)
142 R700_CMDBUF_CHECK_SPACE(9);
143 R700EP3 (context
, IT_SET_RESOURCE
, 7);
144 R700E32 (context
, i
* 7);
145 R700E32 (context
, r700
->texture_states
.textures
[i
]->SQ_TEX_RESOURCE0
.u32All
);
146 R700E32 (context
, r700
->texture_states
.textures
[i
]->SQ_TEX_RESOURCE1
.u32All
);
147 R700E32 (context
, r700
->texture_states
.textures
[i
]->SQ_TEX_RESOURCE2
.u32All
);
148 R700E32 (context
, r700
->texture_states
.textures
[i
]->SQ_TEX_RESOURCE3
.u32All
);
149 R700E32 (context
, r700
->texture_states
.textures
[i
]->SQ_TEX_RESOURCE4
.u32All
);
150 R700E32 (context
, r700
->texture_states
.textures
[i
]->SQ_TEX_RESOURCE5
.u32All
);
151 R700E32 (context
, r700
->texture_states
.textures
[i
]->SQ_TEX_RESOURCE6
.u32All
);
154 if(r700
->texture_states
.samplers
[i
] != 0)
156 R700_CMDBUF_CHECK_SPACE(5);
157 R700EP3 (context
, IT_SET_SAMPLER
, 3);
158 R700E32 (context
, i
* 3); // Base at 0x7000
159 R700E32 (context
, r700
->texture_states
.samplers
[i
]->SQ_TEX_SAMPLER0
.u32All
);
160 R700E32 (context
, r700
->texture_states
.samplers
[i
]->SQ_TEX_SAMPLER1
.u32All
);
161 R700E32 (context
, r700
->texture_states
.samplers
[i
]->SQ_TEX_SAMPLER2
.u32All
);
168 GLboolean
r700SyncSurf(context_t
*context
)
170 #if 0 //to be enabled
171 BATCH_LOCALS(&context
->radeon
);
173 /* TODO : too heavy? */
174 unsigned int CP_COHER_CNTL
= 0;
176 CP_COHER_CNTL
|= TC_ACTION_ENA_bit
184 BEGIN_BATCH_NO_AUTOSTATE(5);
186 OUT_BATCH(CP_PACKET3((IT_SURFACE_SYNC
<< 8), 3)));
187 OUT_BATCH(CP_COHER_CNTL
);
188 OUT_BATCH(0xFFFFFFFF);
189 OUT_BATCH(0x00000000);
198 unsigned int r700PrimitiveType(int prim
)
200 switch (prim
& PRIM_MODE_MASK
)
203 return DI_PT_POINTLIST
;
206 return DI_PT_LINELIST
;
209 return DI_PT_LINESTRIP
;
212 return DI_PT_LINELOOP
;
215 return DI_PT_TRILIST
;
217 case GL_TRIANGLE_STRIP
:
218 return DI_PT_TRISTRIP
;
220 case GL_TRIANGLE_FAN
:
224 return DI_PT_QUADLIST
;
227 return DI_PT_QUADSTRIP
;
230 return DI_PT_POLYGON
;
239 static GLboolean
r700RunRender(GLcontext
* ctx
,
240 struct tnl_pipeline_stage
*stage
)
242 context_t
*context
= R700_CONTEXT(ctx
);
243 R700_CHIP_CONTEXT
*r700
= (R700_CHIP_CONTEXT
*)(context
->chipobj
.pvChipObj
);
245 BATCH_LOCALS(&context
->radeon
);
248 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
249 struct vertex_buffer
*vb
= &tnl
->vb
;
251 struct r700_fragment_program
*fp
= (struct r700_fragment_program
*)
252 (ctx
->FragmentProgram
._Current
);
253 if (context
->radeon
.radeonScreen
->chip_family
<= CHIP_FAMILY_RV670
)
255 fp
->r700AsmCode
.bR6xx
= 1;
258 r700Start3D(context
); /* TODO : this is too much. */
260 r700SyncSurf(context
); /* TODO : make it light. */
262 r700UpdateShaders(ctx
);
264 r700SetRenderTarget(context
);
266 if(r700SetupStreams(ctx
))
271 r700UpdateTextureState(context
);
272 r700SendTextureState(context
);
274 if(GL_FALSE
== fp
->translated
)
276 if( GL_FALSE
== r700TranslateFragmentShader(fp
, &(fp
->mesa_program
)) )
282 r700SetupShaders(ctx
);
284 /* set a valid base address to make the command checker happy */
285 r700
->SQ_PGM_START_FS
.u32All
= r700
->SQ_PGM_START_PS
.u32All
;
286 r700
->SQ_PGM_START_ES
.u32All
= r700
->SQ_PGM_START_PS
.u32All
;
287 r700
->SQ_PGM_START_GS
.u32All
= r700
->SQ_PGM_START_PS
.u32All
;
289 r700SendContextStates(context
, NULL
, NULL
);
291 /* richard test code */
292 for (i
= 0; i
< vb
->PrimitiveCount
; i
++)
294 GLuint prim
= _tnl_translate_prim(&vb
->Primitive
[i
]);
295 GLuint start
= vb
->Primitive
[i
].start
;
296 GLuint end
= vb
->Primitive
[i
].start
+ vb
->Primitive
[i
].count
;
297 GLuint numIndices
= vb
->Primitive
[i
].count
;
299 //r300RunRenderPrimitive(rmesa, ctx, start, end, prim);
301 unsigned int VGT_DRAW_INITIATOR
= 0;
302 unsigned int VGT_INDEX_TYPE
= 0;
303 unsigned int VGT_PRIMITIVE_TYPE
= 0;
304 unsigned int VGT_NUM_INDICES
= 0;
306 numEntires
= 2 /* VGT_INDEX_TYPE */
307 + 3 /* VGT_PRIMITIVE_TYPE */
308 + numIndices
+ 3 /* DRAW_INDEX_IMMD */
309 + 2; /* test stamp */
311 BEGIN_BATCH_NO_AUTOSTATE(numEntires
);
313 VGT_INDEX_TYPE
|= DI_INDEX_SIZE_32_BIT
<< INDEX_TYPE_shift
;
315 OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE
, 0));
316 OUT_BATCH(VGT_INDEX_TYPE
);
318 VGT_NUM_INDICES
= numIndices
;
320 VGT_PRIMITIVE_TYPE
|= r700PrimitiveType(prim
) << VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift
;
321 OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG
, 1));
322 OUT_BATCH(mmVGT_PRIMITIVE_TYPE
- ASIC_CONFIG_BASE_INDEX
);
323 OUT_BATCH(VGT_PRIMITIVE_TYPE
);
325 VGT_DRAW_INITIATOR
|= DI_SRC_SEL_IMMEDIATE
<< SOURCE_SELECT_shift
;
326 VGT_DRAW_INITIATOR
|= DI_MAJOR_MODE_0
<< MAJOR_MODE_shift
;
328 OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD
, (numIndices
+ 1)));
329 OUT_BATCH(VGT_NUM_INDICES
);
330 OUT_BATCH(VGT_DRAW_INITIATOR
);
332 for (j
=0; j
<numIndices
; j
++)
340 /* Flush render op cached for last several quads. */
341 BEGIN_BATCH_NO_AUTOSTATE(2);
342 OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE
, 0));
343 OUT_BATCH(CACHE_FLUSH_AND_INV_EVENT
);
347 (context
->chipobj
.FlushCmdBuffer
)(context
);
349 (context
->chipobj
.ReleaseArrays
)(ctx
);
352 /* test stamp, write a number to mmSCRATCH4 */
353 BEGIN_BATCH_NO_AUTOSTATE(3);
354 R600_OUT_BATCH_REGVAL((0x2144 << 2), 0x56785678);
358 rcommonFlushCmdBuf( &context
->radeon
, __FUNCTION__
);
363 static GLboolean
r700RunNonTCLRender(GLcontext
* ctx
,
364 struct tnl_pipeline_stage
*stage
) /* -------------------- */
366 GLboolean bRet
= GL_TRUE
;
371 static GLboolean
r700RunTCLRender(GLcontext
* ctx
, /*----------------------*/
372 struct tnl_pipeline_stage
*stage
)
374 GLboolean bRet
= GL_FALSE
;
376 /* TODO : sw fallback */
379 * Ensure all enabled and complete textures are uploaded along with any buffers being used.
381 if(!r700ValidateBuffers(ctx
))
386 context_t
*context
= R700_CONTEXT(ctx
);
388 r700UpdateShaders(ctx
);
390 bRet
= r700RunRender(ctx
, stage
);
393 //GL_FALSE will stop to do other pipe stage in _tnl_run_pipeline
394 //The render here DOES finish the whole pipe, so GL_FALSE should be returned for success.
397 const struct tnl_pipeline_stage _r700_render_stage
= {
398 "r700 Hardware Rasterization",
406 const struct tnl_pipeline_stage _r700_tcl_stage
= {
407 "r700 Hardware Transform, Clipping and Lighting",
415 const struct tnl_pipeline_stage
*r700_pipeline
[] =
418 &_tnl_vertex_transform_stage
,
419 &_tnl_normal_transform_stage
,
420 &_tnl_lighting_stage
,
421 &_tnl_fog_coordinate_stage
,
423 &_tnl_texture_transform_stage
,
424 &_tnl_vertex_program_stage
,