OSDN Git Service

enable surface sync function
[android-x86/external-mesa.git] / src / mesa / drivers / dri / r600 / r700_render.c
1 /*
2  * Copyright (C) 2008-2009  Advanced Micro Devices, Inc.
3  *
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:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
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.
20  */
21
22 /*
23  * Authors:
24  *   Richard Li <RichardZ.Li@amd.com>, <richardradeon@gmail.com>
25  *   CooperYuan <cooper.yuan@amd.com>, <cooperyuan@gmail.com>
26  */
27
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"
34 #include "main/dd.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"
39 #include "vbo/vbo.h"
40
41 #include "tnl/tnl.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"
46
47 #include "r600_context.h"
48 #include "r600_cmdbuf.h"
49
50 #include "r700_chip.h"
51 #include "r700_tex.h"
52
53 #include "r700_vertprog.h"
54 #include "r700_fragprog.h"
55 #include "r700_state.h"
56
57 void r700WaitForIdle(context_t *context)
58 {
59     BATCH_LOCALS(&context->radeon);
60     BEGIN_BATCH_NO_AUTOSTATE(3);
61
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);
65
66     END_BATCH();
67     COMMIT_BATCH();
68 }
69
70 void r700WaitForIdleClean(context_t *context)
71 {
72     BATCH_LOCALS(&context->radeon);
73     BEGIN_BATCH_NO_AUTOSTATE(5);
74
75     R600_OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
76     R600_OUT_BATCH(CACHE_FLUSH_AND_INV_EVENT);
77
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);
81
82     END_BATCH();
83     COMMIT_BATCH();
84 }
85
86 static void r700Start3D(context_t *context)
87 {
88     BATCH_LOCALS(&context->radeon);
89     if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
90     {
91         BEGIN_BATCH_NO_AUTOSTATE(2);
92         R600_OUT_BATCH(CP_PACKET3(R600_IT_START_3D_CMDBUF, 0));
93         R600_OUT_BATCH(0);
94         END_BATCH();
95     }
96
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);
101     END_BATCH();
102
103     COMMIT_BATCH();
104
105     r700WaitForIdleClean(context);
106 }
107
108 static GLboolean r700SetupShaders(GLcontext * ctx)
109 {
110     context_t *context = R700_CONTEXT(ctx);
111
112     R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(context->chipobj.pvChipObj);
113
114     GLuint exportCount;
115
116         r700->SQ_PGM_RESOURCES_PS.u32All = 0;
117         r700->SQ_PGM_RESOURCES_VS.u32All = 0;
118
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);
121
122     r700SetupVertexProgram(ctx);
123
124     r700SetupFragmentProgram(ctx);
125
126         exportCount = (r700->SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift);
127     r700->CB_SHADER_CONTROL.u32All = (1 << exportCount) - 1;
128
129     return GL_TRUE;
130 }
131
132 GLboolean r700SendTextureState(context_t *context)
133 {
134     unsigned int i;
135
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++)
139     {
140         if(r700->texture_states.textures[i] != 0)
141         {
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);
152         }
153
154         if(r700->texture_states.samplers[i] != 0)
155         {
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);
162         }
163     }
164 #endif
165     return GL_TRUE;
166 }
167
168 GLboolean r700SyncSurf(context_t *context)
169 {
170     BATCH_LOCALS(&context->radeon);
171
172     /* TODO : too heavy? */
173     unsigned int CP_COHER_CNTL   = 0;
174
175     CP_COHER_CNTL |= (TC_ACTION_ENA_bit
176                       | VC_ACTION_ENA_bit
177                       | CB_ACTION_ENA_bit
178                       | DB_ACTION_ENA_bit
179                       | SH_ACTION_ENA_bit
180                       | SMX_ACTION_ENA_bit);
181
182
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);
188     R600_OUT_BATCH(10);
189
190     END_BATCH();
191     COMMIT_BATCH();
192
193     return GL_TRUE;
194 }
195
196 unsigned int r700PrimitiveType(int prim)
197 {
198     switch (prim & PRIM_MODE_MASK) 
199     {
200     case GL_POINTS:
201         return DI_PT_POINTLIST;
202         break;
203     case GL_LINES:
204         return DI_PT_LINELIST;
205         break;
206     case GL_LINE_STRIP:
207         return DI_PT_LINESTRIP;
208         break;
209     case GL_LINE_LOOP:
210         return DI_PT_LINELOOP;
211         break;
212     case GL_TRIANGLES:
213         return DI_PT_TRILIST;
214         break;
215     case GL_TRIANGLE_STRIP:
216         return DI_PT_TRISTRIP;
217         break;
218     case GL_TRIANGLE_FAN:
219         return DI_PT_TRIFAN;
220         break;
221     case GL_QUADS:
222         return DI_PT_QUADLIST;
223         break;
224     case GL_QUAD_STRIP:
225         return DI_PT_QUADSTRIP;
226         break;
227     case GL_POLYGON:
228         return DI_PT_POLYGON;
229         break;
230     default:
231         assert(0);
232         return -1;
233         break;
234     }
235 }
236
237 static GLboolean r700RunRender(GLcontext * ctx,
238                                            struct tnl_pipeline_stage *stage)
239 {
240     context_t *context = R700_CONTEXT(ctx);
241     R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(context->chipobj.pvChipObj);
242 #if 1
243     BATCH_LOCALS(&context->radeon);
244
245     unsigned int i, j;
246     TNLcontext *tnl = TNL_CONTEXT(ctx);
247     struct vertex_buffer *vb = &tnl->vb;
248
249     struct r700_fragment_program *fp = (struct r700_fragment_program *)
250                                            (ctx->FragmentProgram._Current);
251     if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
252     {
253         fp->r700AsmCode.bR6xx = 1;
254     }
255
256     r700Start3D(context); /* TODO : this is too much. */
257
258     r700SyncSurf(context); /* TODO : make it light. */
259
260     r700UpdateShaders(ctx);
261
262     r700SetRenderTarget(context);
263
264     if(r700SetupStreams(ctx))
265     {
266         return GL_TRUE;
267     }
268
269     /* flush TX */
270     //r700SyncSurf(context); /*  */
271
272     r700UpdateTextureState(context);
273     r700SendTextureState(context);
274
275     if(GL_FALSE == fp->translated)
276     {
277         if( GL_FALSE == r700TranslateFragmentShader(fp, &(fp->mesa_program)) )
278         {
279             return GL_TRUE;
280         }
281     }
282
283     /* flush SQ */
284     //r700SyncSurf(context); /*  */
285     //r700SyncSurf(context); /*  */
286
287     r700SetupShaders(ctx);
288
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;
293
294     /* flush vtx */
295     //r700SyncSurf(context); /*  */
296
297     r700SendContextStates(context, GL_FALSE);
298
299     /* richard test code */
300     for (i = 0; i < vb->PrimitiveCount; i++) 
301     {
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;
306         GLuint numEntires;
307                 //r300RunRenderPrimitive(rmesa, ctx, start, end, prim);
308
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;
313         
314         numEntires = 2 /* VGT_INDEX_TYPE */
315                      + 3 /* VGT_PRIMITIVE_TYPE */
316                      + numIndices + 3; /* DRAW_INDEX_IMMD */                  
317                      
318         BEGIN_BATCH_NO_AUTOSTATE(numEntires);  
319
320         VGT_INDEX_TYPE |= DI_INDEX_SIZE_32_BIT << INDEX_TYPE_shift;
321
322         R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
323         R600_OUT_BATCH(VGT_INDEX_TYPE);
324
325         VGT_NUM_INDICES = numIndices;
326
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);
331
332         VGT_DRAW_INITIATOR |= DI_SRC_SEL_IMMEDIATE << SOURCE_SELECT_shift;
333         VGT_DRAW_INITIATOR |= DI_MAJOR_MODE_0 << MAJOR_MODE_shift;
334
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);
338
339         for (j=0; j<numIndices; j++)
340         {
341             R600_OUT_BATCH(j);
342         }
343         END_BATCH();
344         COMMIT_BATCH();
345     }
346
347     /* Flush render op cached for last several quads. */
348     r700WaitForIdleClean(context);
349
350     /* flush dst */
351     //r700SyncSurf(context); /*  */
352
353     (context->chipobj.FlushCmdBuffer)(context);
354
355     (context->chipobj.ReleaseArrays)(ctx);
356
357     //richard test
358     /* test stamp, write a number to mmSCRATCH4 */
359     BEGIN_BATCH_NO_AUTOSTATE(3);
360     R600_OUT_BATCH_REGVAL((0x2144 << 2), 0x56785678);
361     END_BATCH();
362     COMMIT_BATCH();
363
364
365 #endif //0
366     rcommonFlushCmdBuf( &context->radeon, __FUNCTION__ );
367
368     return GL_FALSE;
369 }
370
371 static GLboolean r700RunNonTCLRender(GLcontext * ctx,
372                                      struct tnl_pipeline_stage *stage) /* -------------------- */
373 {
374         GLboolean bRet = GL_TRUE;
375         
376         return bRet;
377 }
378
379 static GLboolean r700RunTCLRender(GLcontext * ctx,  /*----------------------*/
380                                   struct tnl_pipeline_stage *stage)
381 {
382         GLboolean bRet = GL_FALSE;
383
384     /* TODO : sw fallback */
385
386     /**
387     * Ensure all enabled and complete textures are uploaded along with any buffers being used.
388     */
389     if(!r700ValidateBuffers(ctx))
390     {
391         return GL_TRUE;
392     }
393
394     context_t *context = R700_CONTEXT(ctx);
395
396     r700UpdateShaders(ctx);
397
398     bRet = r700RunRender(ctx, stage);
399
400     return bRet;
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.
403 }
404
405 const struct tnl_pipeline_stage _r700_render_stage = {
406         "r700 Hardware Rasterization",
407         NULL,
408         NULL,
409         NULL,
410         NULL,
411         r700RunNonTCLRender
412 };
413
414 const struct tnl_pipeline_stage _r700_tcl_stage = {
415         "r700 Hardware Transform, Clipping and Lighting",
416         NULL,
417         NULL,
418         NULL,
419         NULL,
420         r700RunTCLRender
421 };
422
423 const struct tnl_pipeline_stage *r700_pipeline[] = 
424 {
425     &_r700_tcl_stage,
426     &_tnl_vertex_transform_stage,
427         &_tnl_normal_transform_stage,
428         &_tnl_lighting_stage,
429         &_tnl_fog_coordinate_stage,
430         &_tnl_texgen_stage,
431         &_tnl_texture_transform_stage,
432         &_tnl_vertex_program_stage,
433
434     &_r700_render_stage,
435     &_tnl_render_stage,
436     0,
437 };
438
439