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 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
63 R600_OUT_BATCH(mmWAIT_UNTIL - ASIC_CONFIG_BASE_INDEX);
64 R600_OUT_BATCH(WAIT_3D_IDLE_bit);
70 void r700WaitForIdleClean(context_t *context)
72 BATCH_LOCALS(&context->radeon);
73 BEGIN_BATCH_NO_AUTOSTATE(5);
75 R600_OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
76 R600_OUT_BATCH(CACHE_FLUSH_AND_INV_EVENT);
78 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
79 R600_OUT_BATCH(mmWAIT_UNTIL - ASIC_CONFIG_BASE_INDEX);
80 R600_OUT_BATCH(WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit);
86 static void r700Start3D(context_t *context)
88 BATCH_LOCALS(&context->radeon);
89 if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
91 BEGIN_BATCH_NO_AUTOSTATE(2);
92 R600_OUT_BATCH(CP_PACKET3(R600_IT_START_3D_CMDBUF, 0));
97 BEGIN_BATCH_NO_AUTOSTATE(3);
98 R600_OUT_BATCH(CP_PACKET3(R600_IT_CONTEXT_CONTROL, 1));
99 R600_OUT_BATCH(0x80000000);
100 R600_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 BATCH_LOCALS(&context->radeon);
172 /* TODO : too heavy? */
173 unsigned int CP_COHER_CNTL = 0;
175 CP_COHER_CNTL |= (TC_ACTION_ENA_bit
180 | SMX_ACTION_ENA_bit);
183 BEGIN_BATCH_NO_AUTOSTATE(5);
184 R600_OUT_BATCH(CP_PACKET3(R600_IT_SURFACE_SYNC, 3));
185 R600_OUT_BATCH(CP_COHER_CNTL);
186 R600_OUT_BATCH(0xFFFFFFFF);
187 R600_OUT_BATCH(0x00000000);
196 unsigned int r700PrimitiveType(int prim)
198 switch (prim & PRIM_MODE_MASK)
201 return DI_PT_POINTLIST;
204 return DI_PT_LINELIST;
207 return DI_PT_LINESTRIP;
210 return DI_PT_LINELOOP;
213 return DI_PT_TRILIST;
215 case GL_TRIANGLE_STRIP:
216 return DI_PT_TRISTRIP;
218 case GL_TRIANGLE_FAN:
222 return DI_PT_QUADLIST;
225 return DI_PT_QUADSTRIP;
228 return DI_PT_POLYGON;
237 static GLboolean r700RunRender(GLcontext * ctx,
238 struct tnl_pipeline_stage *stage)
240 context_t *context = R700_CONTEXT(ctx);
241 R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(context->chipobj.pvChipObj);
243 BATCH_LOCALS(&context->radeon);
246 TNLcontext *tnl = TNL_CONTEXT(ctx);
247 struct vertex_buffer *vb = &tnl->vb;
249 struct r700_fragment_program *fp = (struct r700_fragment_program *)
250 (ctx->FragmentProgram._Current);
251 if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
253 fp->r700AsmCode.bR6xx = 1;
256 r700Start3D(context); /* TODO : this is too much. */
258 r700SyncSurf(context); /* TODO : make it light. */
260 r700UpdateShaders(ctx);
262 r700SetRenderTarget(context);
264 if(r700SetupStreams(ctx))
270 //r700SyncSurf(context); /* */
272 r700UpdateTextureState(context);
273 r700SendTextureState(context);
275 if(GL_FALSE == fp->translated)
277 if( GL_FALSE == r700TranslateFragmentShader(fp, &(fp->mesa_program)) )
284 //r700SyncSurf(context); /* */
285 //r700SyncSurf(context); /* */
287 r700SetupShaders(ctx);
289 /* set a valid base address to make the command checker happy */
290 r700->SQ_PGM_START_FS.u32All = r700->SQ_PGM_START_PS.u32All;
291 r700->SQ_PGM_START_ES.u32All = r700->SQ_PGM_START_PS.u32All;
292 r700->SQ_PGM_START_GS.u32All = r700->SQ_PGM_START_PS.u32All;
295 //r700SyncSurf(context); /* */
297 r700SendContextStates(context, GL_FALSE);
299 /* richard test code */
300 for (i = 0; i < vb->PrimitiveCount; i++)
302 GLuint prim = _tnl_translate_prim(&vb->Primitive[i]);
303 GLuint start = vb->Primitive[i].start;
304 GLuint end = vb->Primitive[i].start + vb->Primitive[i].count;
305 GLuint numIndices = vb->Primitive[i].count;
307 //r300RunRenderPrimitive(rmesa, ctx, start, end, prim);
309 unsigned int VGT_DRAW_INITIATOR = 0;
310 unsigned int VGT_INDEX_TYPE = 0;
311 unsigned int VGT_PRIMITIVE_TYPE = 0;
312 unsigned int VGT_NUM_INDICES = 0;
314 numEntires = 2 /* VGT_INDEX_TYPE */
315 + 3 /* VGT_PRIMITIVE_TYPE */
316 + numIndices + 3; /* DRAW_INDEX_IMMD */
318 BEGIN_BATCH_NO_AUTOSTATE(numEntires);
320 VGT_INDEX_TYPE |= DI_INDEX_SIZE_32_BIT << INDEX_TYPE_shift;
322 R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
323 R600_OUT_BATCH(VGT_INDEX_TYPE);
325 VGT_NUM_INDICES = numIndices;
327 VGT_PRIMITIVE_TYPE |= r700PrimitiveType(prim) << VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift;
328 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
329 R600_OUT_BATCH(mmVGT_PRIMITIVE_TYPE - ASIC_CONFIG_BASE_INDEX);
330 R600_OUT_BATCH(VGT_PRIMITIVE_TYPE);
332 VGT_DRAW_INITIATOR |= DI_SRC_SEL_IMMEDIATE << SOURCE_SELECT_shift;
333 VGT_DRAW_INITIATOR |= DI_MAJOR_MODE_0 << MAJOR_MODE_shift;
335 R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (numIndices + 1)));
336 R600_OUT_BATCH(VGT_NUM_INDICES);
337 R600_OUT_BATCH(VGT_DRAW_INITIATOR);
339 for (j=0; j<numIndices; j++)
347 /* Flush render op cached for last several quads. */
348 r700WaitForIdleClean(context);
351 //r700SyncSurf(context); /* */
353 (context->chipobj.FlushCmdBuffer)(context);
355 (context->chipobj.ReleaseArrays)(ctx);
358 /* test stamp, write a number to mmSCRATCH4 */
359 BEGIN_BATCH_NO_AUTOSTATE(3);
360 R600_OUT_BATCH_REGVAL((0x2144 << 2), 0x56785678);
366 rcommonFlushCmdBuf( &context->radeon, __FUNCTION__ );
371 static GLboolean r700RunNonTCLRender(GLcontext * ctx,
372 struct tnl_pipeline_stage *stage) /* -------------------- */
374 GLboolean bRet = GL_TRUE;
379 static GLboolean r700RunTCLRender(GLcontext * ctx, /*----------------------*/
380 struct tnl_pipeline_stage *stage)
382 GLboolean bRet = GL_FALSE;
384 /* TODO : sw fallback */
387 * Ensure all enabled and complete textures are uploaded along with any buffers being used.
389 if(!r700ValidateBuffers(ctx))
394 context_t *context = R700_CONTEXT(ctx);
396 r700UpdateShaders(ctx);
398 bRet = r700RunRender(ctx, stage);
401 //GL_FALSE will stop to do other pipe stage in _tnl_run_pipeline
402 //The render here DOES finish the whole pipe, so GL_FALSE should be returned for success.
405 const struct tnl_pipeline_stage _r700_render_stage = {
406 "r700 Hardware Rasterization",
414 const struct tnl_pipeline_stage _r700_tcl_stage = {
415 "r700 Hardware Transform, Clipping and Lighting",
423 const struct tnl_pipeline_stage *r700_pipeline[] =
426 &_tnl_vertex_transform_stage,
427 &_tnl_normal_transform_stage,
428 &_tnl_lighting_stage,
429 &_tnl_fog_coordinate_stage,
431 &_tnl_texture_transform_stage,
432 &_tnl_vertex_program_stage,