0a5e04154792b7b90b55dae98454185baad1c3f8
[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 "radeon_mipmap_tree.h"
48 #include "r600_context.h"
49 #include "r600_cmdbuf.h"
50
51 #include "r600_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 void r700WaitForIdleClean(context_t *context);
59 void r700Start3D(context_t *context);
60 GLboolean r700SendTextureState(context_t *context);
61 unsigned int r700PrimitiveType(int prim);
62 void r600UpdateTextureState(GLcontext * ctx);
63 GLboolean r700SyncSurf(context_t *context,
64 struct radeon_bo *pbo,
65 uint32_t read_domain,
66 uint32_t write_domain,
67 uint32_t sync_type);
68
69 void r700WaitForIdle(context_t *context)
70 {
71 BATCH_LOCALS(&context->radeon);
72 BEGIN_BATCH_NO_AUTOSTATE(3);
73
74 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
75 R600_OUT_BATCH(mmWAIT_UNTIL - ASIC_CONFIG_BASE_INDEX);
76 R600_OUT_BATCH(WAIT_3D_IDLE_bit);
77
78 END_BATCH();
79 COMMIT_BATCH();
80 }
81
82 void r700WaitForIdleClean(context_t *context)
83 {
84 BATCH_LOCALS(&context->radeon);
85 BEGIN_BATCH_NO_AUTOSTATE(5);
86
87 R600_OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
88 R600_OUT_BATCH(CACHE_FLUSH_AND_INV_EVENT);
89
90 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
91 R600_OUT_BATCH(mmWAIT_UNTIL - ASIC_CONFIG_BASE_INDEX);
92 R600_OUT_BATCH(WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit);
93
94 END_BATCH();
95 COMMIT_BATCH();
96 }
97
98 void r700Start3D(context_t *context)
99 {
100 BATCH_LOCALS(&context->radeon);
101 if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
102 {
103 BEGIN_BATCH_NO_AUTOSTATE(2);
104 R600_OUT_BATCH(CP_PACKET3(R600_IT_START_3D_CMDBUF, 0));
105 R600_OUT_BATCH(0);
106 END_BATCH();
107 }
108
109 BEGIN_BATCH_NO_AUTOSTATE(3);
110 R600_OUT_BATCH(CP_PACKET3(R600_IT_CONTEXT_CONTROL, 1));
111 R600_OUT_BATCH(0x80000000);
112 R600_OUT_BATCH(0x80000000);
113 END_BATCH();
114
115 COMMIT_BATCH();
116
117 r700WaitForIdleClean(context);
118 }
119
120 static GLboolean r700SetupShaders(GLcontext * ctx)
121 {
122 context_t *context = R700_CONTEXT(ctx);
123
124 R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
125
126 GLuint exportCount;
127
128 r700->ps.SQ_PGM_RESOURCES_PS.u32All = 0;
129 r700->vs.SQ_PGM_RESOURCES_VS.u32All = 0;
130
131 SETbit(r700->ps.SQ_PGM_RESOURCES_PS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
132 SETbit(r700->vs.SQ_PGM_RESOURCES_VS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
133
134 r700SetupVertexProgram(ctx);
135
136 r700SetupFragmentProgram(ctx);
137
138 exportCount = (r700->ps.SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift);
139 r700->CB_SHADER_CONTROL.u32All = (1 << exportCount) - 1;
140
141 return GL_TRUE;
142 }
143
144 GLboolean r700SendTextureState(context_t *context)
145 {
146 unsigned int i;
147 R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
148 offset_modifiers offset_mod = {NO_SHIFT, 0, 0xFFFFFFFF};
149 struct radeon_bo *bo = NULL;
150 BATCH_LOCALS(&context->radeon);
151
152 for (i=0; i<R700_TEXTURE_NUMBERUNITS; i++) {
153 radeonTexObj *t = r700->textures[i];
154 if (t) {
155 if (!t->image_override)
156 bo = t->mt->bo;
157 else
158 bo = t->bo;
159 if (bo) {
160
161 r700SyncSurf(context, bo,
162 RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM,
163 0, TC_ACTION_ENA_bit);
164
165 BEGIN_BATCH_NO_AUTOSTATE(9);
166 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
167 R600_OUT_BATCH(i * 7);
168 R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE0);
169 R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE1);
170 R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE2,
171 bo,
172 0,
173 RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0, &offset_mod);
174 R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE3,
175 bo,
176 0,
177 RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0, &offset_mod);
178 R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE4);
179 R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE5);
180 R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6);
181 END_BATCH();
182
183 BEGIN_BATCH_NO_AUTOSTATE(5);
184 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3));
185 R600_OUT_BATCH(i * 3);
186 R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER0);
187 R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER1);
188 R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER2);
189 END_BATCH();
190 COMMIT_BATCH();
191 }
192 }
193 }
194 return GL_TRUE;
195 }
196
197 GLboolean r700SyncSurf(context_t *context,
198 struct radeon_bo *pbo,
199 uint32_t read_domain,
200 uint32_t write_domain,
201 uint32_t sync_type)
202 {
203 BATCH_LOCALS(&context->radeon);
204 uint32_t cp_coher_size;
205 offset_modifiers offset_mod;
206
207 if (pbo->size == 0xffffffff)
208 cp_coher_size = 0xffffffff;
209 else
210 cp_coher_size = ((pbo->size + 255) >> 8);
211
212 offset_mod.shift = NO_SHIFT;
213 offset_mod.shiftbits = 0;
214 offset_mod.mask = 0xFFFFFFFF;
215
216 BEGIN_BATCH_NO_AUTOSTATE(5);
217 R600_OUT_BATCH(CP_PACKET3(R600_IT_SURFACE_SYNC, 3));
218 R600_OUT_BATCH(sync_type);
219 R600_OUT_BATCH(cp_coher_size);
220 R600_OUT_BATCH_RELOC(0,
221 pbo,
222 0,
223 read_domain, write_domain, 0, &offset_mod); // ???
224 R600_OUT_BATCH(10);
225
226 END_BATCH();
227 COMMIT_BATCH();
228
229 return GL_TRUE;
230 }
231
232 unsigned int r700PrimitiveType(int prim)
233 {
234 switch (prim & PRIM_MODE_MASK)
235 {
236 case GL_POINTS:
237 return DI_PT_POINTLIST;
238 break;
239 case GL_LINES:
240 return DI_PT_LINELIST;
241 break;
242 case GL_LINE_STRIP:
243 return DI_PT_LINESTRIP;
244 break;
245 case GL_LINE_LOOP:
246 return DI_PT_LINELOOP;
247 break;
248 case GL_TRIANGLES:
249 return DI_PT_TRILIST;
250 break;
251 case GL_TRIANGLE_STRIP:
252 return DI_PT_TRISTRIP;
253 break;
254 case GL_TRIANGLE_FAN:
255 return DI_PT_TRIFAN;
256 break;
257 case GL_QUADS:
258 return DI_PT_QUADLIST;
259 break;
260 case GL_QUAD_STRIP:
261 return DI_PT_QUADSTRIP;
262 break;
263 case GL_POLYGON:
264 return DI_PT_POLYGON;
265 break;
266 default:
267 assert(0);
268 return -1;
269 break;
270 }
271 }
272
273 static GLboolean r700RunRender(GLcontext * ctx,
274 struct tnl_pipeline_stage *stage)
275 {
276 context_t *context = R700_CONTEXT(ctx);
277 R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
278 int lastIndex = 0;
279 #if 1
280 BATCH_LOCALS(&context->radeon);
281
282 unsigned int i, j;
283 TNLcontext *tnl = TNL_CONTEXT(ctx);
284 struct vertex_buffer *vb = &tnl->vb;
285
286 struct r700_fragment_program *fp = (struct r700_fragment_program *)
287 (ctx->FragmentProgram._Current);
288 if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
289 {
290 fp->r700AsmCode.bR6xx = 1;
291 }
292
293 r700Start3D(context); /* TODO : this is too much. */
294
295 r700SendSQConfig(context);
296
297 r700UpdateShaders(ctx);
298
299 r700SetScissor(context);
300 r700SetRenderTarget(context, 0);
301 r700SetDepthTarget(context);
302
303 if(r700SetupStreams(ctx))
304 {
305 return GL_TRUE;
306 }
307
308 r600UpdateTextureState(ctx);
309 r700SendTextureState(context);
310
311 if(GL_FALSE == fp->translated)
312 {
313 if( GL_FALSE == r700TranslateFragmentShader(fp, &(fp->mesa_program)) )
314 {
315 return GL_TRUE;
316 }
317 }
318
319 r700SetupShaders(ctx);
320
321 r700SendFSState(context); // FIXME just a place holder for now
322 r700SendPSState(context);
323 r700SendVSState(context);
324
325 r700SendUCPState(context);
326 r700SendContextStates(context);
327 r700SendViewportState(context, 0);
328 r700SendRenderTargetState(context, 0);
329 r700SendDepthTargetState(context);
330
331 /* richard test code */
332 for (i = 0; i < vb->PrimitiveCount; i++)
333 {
334 GLuint prim = _tnl_translate_prim(&vb->Primitive[i]);
335 GLuint start = vb->Primitive[i].start;
336 GLuint end = vb->Primitive[i].start + vb->Primitive[i].count;
337 GLuint numIndices = vb->Primitive[i].count;
338 GLuint numEntires;
339
340 unsigned int VGT_DRAW_INITIATOR = 0;
341 unsigned int VGT_INDEX_TYPE = 0;
342 unsigned int VGT_PRIMITIVE_TYPE = 0;
343 unsigned int VGT_NUM_INDICES = 0;
344
345 numEntires = 3 /* VGT_PRIMITIVE_TYPE */
346 + 2 /* VGT_INDEX_TYPE */
347 + 2 /* NUM_INSTANCES */
348 + numIndices + 3; /* DRAW_INDEX_IMMD */
349
350 BEGIN_BATCH_NO_AUTOSTATE(numEntires);
351
352 // prim
353 VGT_PRIMITIVE_TYPE |= r700PrimitiveType(prim) << VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift;
354 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
355 R600_OUT_BATCH(mmVGT_PRIMITIVE_TYPE - ASIC_CONFIG_BASE_INDEX);
356 R600_OUT_BATCH(VGT_PRIMITIVE_TYPE);
357
358 // index type
359 VGT_INDEX_TYPE |= DI_INDEX_SIZE_32_BIT << INDEX_TYPE_shift;
360 R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
361 R600_OUT_BATCH(VGT_INDEX_TYPE);
362
363 // num instances
364 R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
365 R600_OUT_BATCH(1);
366
367 // draw packet
368 VGT_NUM_INDICES = numIndices;
369 VGT_DRAW_INITIATOR |= DI_SRC_SEL_IMMEDIATE << SOURCE_SELECT_shift;
370 VGT_DRAW_INITIATOR |= DI_MAJOR_MODE_0 << MAJOR_MODE_shift;
371
372 R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (numIndices + 1)));
373 R600_OUT_BATCH(VGT_NUM_INDICES);
374 R600_OUT_BATCH(VGT_DRAW_INITIATOR);
375
376 for (j = lastIndex; j < lastIndex + numIndices; j++)
377 {
378 R600_OUT_BATCH(j);
379 }
380 lastIndex += numIndices;
381
382 END_BATCH();
383 COMMIT_BATCH();
384 }
385
386 /* Flush render op cached for last several quads. */
387 r700WaitForIdleClean(context);
388
389 radeonReleaseArrays(ctx, 0);
390
391 #endif //0
392 rcommonFlushCmdBuf( &context->radeon, __FUNCTION__ );
393
394 return GL_FALSE;
395 }
396
397 static GLboolean r700RunNonTCLRender(GLcontext * ctx,
398 struct tnl_pipeline_stage *stage) /* -------------------- */
399 {
400 GLboolean bRet = GL_TRUE;
401
402 return bRet;
403 }
404
405 static GLboolean r700RunTCLRender(GLcontext * ctx, /*----------------------*/
406 struct tnl_pipeline_stage *stage)
407 {
408 GLboolean bRet = GL_FALSE;
409
410 /* TODO : sw fallback */
411
412 /**
413 * Ensure all enabled and complete textures are uploaded along with any buffers being used.
414 */
415 if(!r600ValidateBuffers(ctx))
416 {
417 return GL_TRUE;
418 }
419
420 context_t *context = R700_CONTEXT(ctx);
421
422 r700UpdateShaders(ctx);
423
424 bRet = r700RunRender(ctx, stage);
425
426 return bRet;
427 //GL_FALSE will stop to do other pipe stage in _tnl_run_pipeline
428 //The render here DOES finish the whole pipe, so GL_FALSE should be returned for success.
429 }
430
431 const struct tnl_pipeline_stage _r700_render_stage = {
432 "r700 Hardware Rasterization",
433 NULL,
434 NULL,
435 NULL,
436 NULL,
437 r700RunNonTCLRender
438 };
439
440 const struct tnl_pipeline_stage _r700_tcl_stage = {
441 "r700 Hardware Transform, Clipping and Lighting",
442 NULL,
443 NULL,
444 NULL,
445 NULL,
446 r700RunTCLRender
447 };
448
449 const struct tnl_pipeline_stage *r700_pipeline[] =
450 {
451 &_r700_tcl_stage,
452 &_tnl_vertex_transform_stage,
453 &_tnl_normal_transform_stage,
454 &_tnl_lighting_stage,
455 &_tnl_fog_coordinate_stage,
456 &_tnl_texgen_stage,
457 &_tnl_texture_transform_stage,
458 &_tnl_vertex_program_stage,
459
460 &_r700_render_stage,
461 &_tnl_render_stage,
462 0,
463 };
464
465