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
);
279 BATCH_LOCALS(&context
->radeon
);
282 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
283 struct vertex_buffer
*vb
= &tnl
->vb
;
285 r700Start3D(context
); /* TODO : this is too much. */
287 r700SendSQConfig(context
);
289 r700UpdateShaders(ctx
);
291 r700SetScissor(context
);
292 r700SetRenderTarget(context
, 0);
293 r700SetDepthTarget(context
);
295 if(r700SetupStreams(ctx
))
300 r600UpdateTextureState(ctx
);
301 r700SendTextureState(context
);
303 r700SetupShaders(ctx
);
305 r700SendFSState(context
); // FIXME just a place holder for now
306 r700SendPSState(context
);
307 r700SendVSState(context
);
309 r700SendUCPState(context
);
310 r700SendContextStates(context
);
311 r700SendViewportState(context
, 0);
312 r700SendRenderTargetState(context
, 0);
313 r700SendDepthTargetState(context
);
315 /* richard test code */
316 for (i
= 0; i
< vb
->PrimitiveCount
; i
++)
318 GLuint prim
= _tnl_translate_prim(&vb
->Primitive
[i
]);
319 GLuint start
= vb
->Primitive
[i
].start
;
320 GLuint end
= vb
->Primitive
[i
].start
+ vb
->Primitive
[i
].count
;
321 GLuint numIndices
= vb
->Primitive
[i
].count
;
324 unsigned int VGT_DRAW_INITIATOR
= 0;
325 unsigned int VGT_INDEX_TYPE
= 0;
326 unsigned int VGT_PRIMITIVE_TYPE
= 0;
327 unsigned int VGT_NUM_INDICES
= 0;
332 numEntires
= 3 /* VGT_PRIMITIVE_TYPE */
333 + 2 /* VGT_INDEX_TYPE */
334 + 2 /* NUM_INSTANCES */
335 + numIndices
+ 3; /* DRAW_INDEX_IMMD */
337 BEGIN_BATCH_NO_AUTOSTATE(numEntires
);
340 VGT_PRIMITIVE_TYPE
|= r700PrimitiveType(prim
) << VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift
;
341 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG
, 1));
342 R600_OUT_BATCH(mmVGT_PRIMITIVE_TYPE
- ASIC_CONFIG_BASE_INDEX
);
343 R600_OUT_BATCH(VGT_PRIMITIVE_TYPE
);
346 VGT_INDEX_TYPE
|= DI_INDEX_SIZE_32_BIT
<< INDEX_TYPE_shift
;
347 R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE
, 0));
348 R600_OUT_BATCH(VGT_INDEX_TYPE
);
351 R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES
, 0));
355 VGT_NUM_INDICES
= numIndices
;
356 VGT_DRAW_INITIATOR
|= DI_SRC_SEL_IMMEDIATE
<< SOURCE_SELECT_shift
;
357 VGT_DRAW_INITIATOR
|= DI_MAJOR_MODE_0
<< MAJOR_MODE_shift
;
359 R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD
, (numIndices
+ 1)));
360 R600_OUT_BATCH(VGT_NUM_INDICES
);
361 R600_OUT_BATCH(VGT_DRAW_INITIATOR
);
363 for (j
= lastIndex
; j
< lastIndex
+ numIndices
; j
++)
367 lastIndex
+= numIndices
;
373 /* Flush render op cached for last several quads. */
374 r700WaitForIdleClean(context
);
376 radeonReleaseArrays(ctx
, 0);
378 rcommonFlushCmdBuf( &context
->radeon
, __FUNCTION__
);
383 static GLboolean
r700RunNonTCLRender(GLcontext
* ctx
,
384 struct tnl_pipeline_stage
*stage
) /* -------------------- */
386 GLboolean bRet
= GL_TRUE
;
391 static GLboolean
r700RunTCLRender(GLcontext
* ctx
, /*----------------------*/
392 struct tnl_pipeline_stage
*stage
)
394 GLboolean bRet
= GL_FALSE
;
396 /* TODO : sw fallback */
399 * Ensure all enabled and complete textures are uploaded along with any buffers being used.
401 if(!r600ValidateBuffers(ctx
))
406 context_t
*context
= R700_CONTEXT(ctx
);
408 r700UpdateShaders(ctx
);
410 bRet
= r700RunRender(ctx
, stage
);
413 //GL_FALSE will stop to do other pipe stage in _tnl_run_pipeline
414 //The render here DOES finish the whole pipe, so GL_FALSE should be returned for success.
417 const struct tnl_pipeline_stage _r700_render_stage
= {
418 "r700 Hardware Rasterization",
426 const struct tnl_pipeline_stage _r700_tcl_stage
= {
427 "r700 Hardware Transform, Clipping and Lighting",
435 const struct tnl_pipeline_stage
*r700_pipeline
[] =
438 &_tnl_vertex_transform_stage
,
439 &_tnl_normal_transform_stage
,
440 &_tnl_lighting_stage
,
441 &_tnl_fog_coordinate_stage
,
443 &_tnl_texture_transform_stage
,
444 &_tnl_vertex_program_stage
,