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 "radeon_mipmap_tree.h"
48 #include "r600_context.h"
49 #include "r600_cmdbuf.h"
53 #include "r700_vertprog.h"
54 #include "r700_fragprog.h"
55 #include "r700_state.h"
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
,
66 uint32_t write_domain
,
69 void r700WaitForIdle(context_t
*context
)
71 BATCH_LOCALS(&context
->radeon
);
72 BEGIN_BATCH_NO_AUTOSTATE(3);
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
);
82 void r700WaitForIdleClean(context_t
*context
)
84 BATCH_LOCALS(&context
->radeon
);
85 BEGIN_BATCH_NO_AUTOSTATE(5);
87 R600_OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE
, 0));
88 R600_OUT_BATCH(CACHE_FLUSH_AND_INV_EVENT
);
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
);
98 void r700Start3D(context_t
*context
)
100 BATCH_LOCALS(&context
->radeon
);
101 if (context
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV770
)
103 BEGIN_BATCH_NO_AUTOSTATE(2);
104 R600_OUT_BATCH(CP_PACKET3(R600_IT_START_3D_CMDBUF
, 0));
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);
117 r700WaitForIdleClean(context
);
120 static GLboolean
r700SetupShaders(GLcontext
* ctx
)
122 context_t
*context
= R700_CONTEXT(ctx
);
124 R700_CHIP_CONTEXT
*r700
= (R700_CHIP_CONTEXT
*)(&context
->hw
);
128 r700
->ps
.SQ_PGM_RESOURCES_PS
.u32All
= 0;
129 r700
->vs
.SQ_PGM_RESOURCES_VS
.u32All
= 0;
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
);
134 r700SetupVertexProgram(ctx
);
136 r700SetupFragmentProgram(ctx
);
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;
144 GLboolean
r700SendTextureState(context_t
*context
)
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
);
152 for (i
=0; i
<R700_TEXTURE_NUMBERUNITS
; i
++) {
153 radeonTexObj
*t
= r700
->textures
[i
];
155 if (!t
->image_override
)
161 r700SyncSurf(context
, bo
,
162 RADEON_GEM_DOMAIN_GTT
|RADEON_GEM_DOMAIN_VRAM
,
163 0, TC_ACTION_ENA_bit
);
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
,
173 RADEON_GEM_DOMAIN_GTT
|RADEON_GEM_DOMAIN_VRAM
, 0, 0, &offset_mod
);
174 R600_OUT_BATCH_RELOC(r700
->textures
[i
]->SQ_TEX_RESOURCE3
,
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
);
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
);
197 GLboolean
r700SyncSurf(context_t
*context
,
198 struct radeon_bo
*pbo
,
199 uint32_t read_domain
,
200 uint32_t write_domain
,
203 BATCH_LOCALS(&context
->radeon
);
204 uint32_t cp_coher_size
;
205 offset_modifiers offset_mod
;
207 if (pbo
->size
== 0xffffffff)
208 cp_coher_size
= 0xffffffff;
210 cp_coher_size
= ((pbo
->size
+ 255) >> 8);
212 offset_mod
.shift
= NO_SHIFT
;
213 offset_mod
.shiftbits
= 0;
214 offset_mod
.mask
= 0xFFFFFFFF;
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,
223 read_domain
, write_domain
, 0, &offset_mod
); // ???
232 unsigned int r700PrimitiveType(int prim
)
234 switch (prim
& PRIM_MODE_MASK
)
237 return DI_PT_POINTLIST
;
240 return DI_PT_LINELIST
;
243 return DI_PT_LINESTRIP
;
246 return DI_PT_LINELOOP
;
249 return DI_PT_TRILIST
;
251 case GL_TRIANGLE_STRIP
:
252 return DI_PT_TRISTRIP
;
254 case GL_TRIANGLE_FAN
:
258 return DI_PT_QUADLIST
;
261 return DI_PT_QUADSTRIP
;
264 return DI_PT_POLYGON
;
273 static GLboolean
r700RunRender(GLcontext
* ctx
,
274 struct tnl_pipeline_stage
*stage
)
276 context_t
*context
= R700_CONTEXT(ctx
);
277 R700_CHIP_CONTEXT
*r700
= (R700_CHIP_CONTEXT
*)(&context
->hw
);
280 BATCH_LOCALS(&context
->radeon
);
283 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
284 struct vertex_buffer
*vb
= &tnl
->vb
;
286 struct r700_fragment_program
*fp
= (struct r700_fragment_program
*)
287 (ctx
->FragmentProgram
._Current
);
288 if (context
->radeon
.radeonScreen
->chip_family
< CHIP_FAMILY_RV770
)
290 fp
->r700AsmCode
.bR6xx
= 1;
293 r700Start3D(context
); /* TODO : this is too much. */
295 r700SendSQConfig(context
);
297 r700UpdateShaders(ctx
);
299 r700SetScissor(context
);
300 r700SetRenderTarget(context
, 0);
301 r700SetDepthTarget(context
);
303 if(r700SetupStreams(ctx
))
308 r600UpdateTextureState(ctx
);
309 r700SendTextureState(context
);
311 if(GL_FALSE
== fp
->translated
)
313 if( GL_FALSE
== r700TranslateFragmentShader(fp
, &(fp
->mesa_program
)) )
319 r700SetupShaders(ctx
);
321 r700SendFSState(context
); // FIXME just a place holder for now
322 r700SendPSState(context
);
323 r700SendVSState(context
);
325 r700SendUCPState(context
);
326 r700SendContextStates(context
);
327 r700SendViewportState(context
, 0);
328 r700SendRenderTargetState(context
, 0);
329 r700SendDepthTargetState(context
);
331 /* richard test code */
332 for (i
= 0; i
< vb
->PrimitiveCount
; i
++)
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
;
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;
345 numEntires
= 3 /* VGT_PRIMITIVE_TYPE */
346 + 2 /* VGT_INDEX_TYPE */
347 + 2 /* NUM_INSTANCES */
348 + numIndices
+ 3; /* DRAW_INDEX_IMMD */
350 BEGIN_BATCH_NO_AUTOSTATE(numEntires
);
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
);
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
);
364 R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES
, 0));
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
;
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
);
376 for (j
= lastIndex
; j
< lastIndex
+ numIndices
; j
++)
380 lastIndex
+= numIndices
;
386 /* Flush render op cached for last several quads. */
387 r700WaitForIdleClean(context
);
389 radeonReleaseArrays(ctx
, 0);
392 rcommonFlushCmdBuf( &context
->radeon
, __FUNCTION__
);
397 static GLboolean
r700RunNonTCLRender(GLcontext
* ctx
,
398 struct tnl_pipeline_stage
*stage
) /* -------------------- */
400 GLboolean bRet
= GL_TRUE
;
405 static GLboolean
r700RunTCLRender(GLcontext
* ctx
, /*----------------------*/
406 struct tnl_pipeline_stage
*stage
)
408 GLboolean bRet
= GL_FALSE
;
410 /* TODO : sw fallback */
413 * Ensure all enabled and complete textures are uploaded along with any buffers being used.
415 if(!r600ValidateBuffers(ctx
))
420 context_t
*context
= R700_CONTEXT(ctx
);
422 r700UpdateShaders(ctx
);
424 bRet
= r700RunRender(ctx
, stage
);
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.
431 const struct tnl_pipeline_stage _r700_render_stage
= {
432 "r700 Hardware Rasterization",
440 const struct tnl_pipeline_stage _r700_tcl_stage
= {
441 "r700 Hardware Transform, Clipping and Lighting",
449 const struct tnl_pipeline_stage
*r700_pipeline
[] =
452 &_tnl_vertex_transform_stage
,
453 &_tnl_normal_transform_stage
,
454 &_tnl_lighting_stage
,
455 &_tnl_fog_coordinate_stage
,
457 &_tnl_texture_transform_stage
,
458 &_tnl_vertex_program_stage
,