e2571626dc64057a0fee8e4d53dc18deadd28f11
[mesa.git] / src / mesa / drivers / dri / r600 / r700_clear.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/context.h"
30 #include "main/macros.h"
31 #include "main/imports.h"
32 #include "main/mtypes.h"
33 #include "main/enums.h"
34
35 #include "r600_context.h"
36 #include "r700_chip.h"
37
38 #include "r700_shaderinst.h"
39 #include "r600_emit.h"
40
41 extern void r700InitState (GLcontext * ctx);
42
43 extern GLboolean r700SyncSurf(context_t *context);
44
45 static GLboolean r700ClearFast(context_t *context, GLbitfield mask)
46 {
47 /* TODO, fast clear need implementation */
48 return GL_FALSE;
49 }
50
51 static GLboolean r700ClearWithDraw(context_t *context, GLbitfield mask)
52 {
53 GLcontext *ctx = GL_CONTEXT(context);
54
55 BATCH_LOCALS(&context->radeon);
56
57 R700_CHIP_CONTEXT r700Saved;
58 R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(context->chipobj.pvChipObj);
59
60 void * pbo_vs;
61 void * pbo_fs;
62 struct radeon_aos aos_vb;
63
64 unsigned int ui;
65 GLfloat fTemp;
66 GLfloat fVb[] = { 1.0f, 1.0f, 1.0f, 1.0f,
67 -1.0f, -1.0f, 1.0f, 1.0f,
68 1.0f, -1.0f, 1.0f, 1.0f,
69 1.0f, 1.0f, 1.0f, 1.0f,
70 -1.0f, 1.0f, 1.0f, 1.0f,
71 -1.0f, -1.0f, 1.0f, 1.0f}; /* TODO : Z set here */
72 unsigned int uVs[] = { 0xC, 0x81000000, 0x4, 0xA01C0000,
73 0xC001203C, 0x94000688, 0xC001C000, 0x94200688,
74 0x10000001, 0x540C90, 0x10000401, 0x20540C90,
75 0x10000801, 0x40540C90, 0x90000C01, 0x60400C90,
76 0x10000100, 0x600C90, 0x10000500, 0x20600C90,
77 0x10000900, 0x40600C90, 0x90000D00, 0x60680C90,
78 0x7C000000, 0x2D1001, 0x80000, 0xBEADEAF };
79 unsigned int uFs[] = { 0x2, 0xA00C0000, 0xC0008000, 0x94200688,
80 0x10000000, 0x340C90, 0x10000400, 0x20340C90,
81 0x10000800, 0x40340C90, 0x90000C00, 0x60200C90};
82
83 if (context->radeon.radeonScreen->chip_family <= CHIP_FAMILY_RV670)
84 {
85 uVs[9] = 0x541910;
86 uVs[11] = 0x20541910;
87 uVs[13] = 0x40541910;
88 uVs[15] = 0x60401910;
89 uVs[17] = 0x601910;
90 uVs[19] = 0x20601910;
91 uVs[21] = 0x40601910;
92 uVs[23] = 0x60681910;
93 uFs[5] = 0x341910;
94 uFs[7] = 0x20341910;
95 uFs[9] = 0x40341910;
96 uFs[11] = 0x60201910;
97 }
98
99 r700SyncSurf(context);
100
101 /* Save current chip object. */
102 memcpy(&r700Saved, r700, sizeof(R700_CHIP_CONTEXT));
103
104 r700InitState(ctx);
105
106 r700SetRenderTarget(context);
107
108 /* Turn off perspective divid. */
109 SETbit(r700->PA_CL_VTE_CNTL.u32All, VTX_XY_FMT_bit);
110 SETbit(r700->PA_CL_VTE_CNTL.u32All, VTX_Z_FMT_bit);
111 SETbit(r700->PA_CL_VTE_CNTL.u32All, VTX_W0_FMT_bit);
112
113 if( (mask & BUFFER_BIT_FRONT_LEFT) || (mask & BUFFER_BIT_BACK_LEFT) )
114 { /* Enable render target output. */
115 SETfield(r700->CB_TARGET_MASK.u32All, 0xF, TARGET0_ENABLE_shift, TARGET0_ENABLE_mask);
116 }
117 else
118 { /* Disable render target output. */
119 CLEARfield(r700->CB_TARGET_MASK.u32All, TARGET0_ENABLE_mask); /* TODO : OGL need 4 rt. */
120 }
121 if (mask & BUFFER_BIT_DEPTH)
122 {
123 /* Set correct Z to clear. */
124 SETbit(r700->DB_DEPTH_CONTROL.u32All, Z_WRITE_ENABLE_bit);
125 SETbit(r700->DB_DEPTH_CONTROL.u32All, Z_ENABLE_bit);
126 SETfield(r700->DB_DEPTH_CONTROL.u32All, FRAG_ALWAYS, ZFUNC_shift, ZFUNC_mask);
127 fTemp = ctx->Depth.Clear;
128 for(ui=2; ui<24;)
129 {
130 fVb[ui] = fTemp;
131 ui += 4;
132 }
133 }
134 else
135 {
136 /* Disable Z write. */
137 CLEARbit(r700->DB_DEPTH_CONTROL.u32All, Z_WRITE_ENABLE_bit);
138 CLEARbit(r700->DB_DEPTH_CONTROL.u32All, Z_ENABLE_bit);
139 }
140
141 /* Setup vb */
142 BEGIN_BATCH_NO_AUTOSTATE(6);
143 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1));
144 R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
145 R600_OUT_BATCH(0);
146
147 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1));
148 R600_OUT_BATCH(mmSQ_VTX_START_INST_LOC - ASIC_CTL_CONST_BASE_INDEX);
149 R600_OUT_BATCH(0);
150 END_BATCH();
151 COMMIT_BATCH();
152
153 (context->chipobj.EmitVec)(ctx, &aos_vb, (GLvoid *)fVb, 4, 16, 6);
154
155 r700SetupVTXConstans(ctx, VERT_ATTRIB_POS, &aos_vb, 4, 16, 6);
156
157 /* Setup shaders, copied from dump */
158 r700->SQ_PGM_RESOURCES_PS.u32All = 0;
159 r700->SQ_PGM_RESOURCES_VS.u32All = 0;
160 SETbit(r700->SQ_PGM_RESOURCES_PS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
161 SETbit(r700->SQ_PGM_RESOURCES_VS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
162 /* vs */
163 if(0 == r700->pbo_vs_clear)
164 {
165 (context->chipobj.EmitShader)(ctx, &(r700->pbo_vs_clear), (GLvoid *)(&uVs[0]), 28, "Clr VS");
166 }
167
168 r700->SQ_PGM_START_VS.u32All = 0;
169 r700->SQ_PGM_RESOURCES_VS.u32All = 0x00800004;
170
171 /* vs const */ /* TODO : Set color here */
172 BEGIN_BATCH_NO_AUTOSTATE(4 + 2);
173 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, 4));
174 R600_OUT_BATCH(SQ_ALU_CONSTANT_VS_OFFSET * 4);
175 R600_OUT_BATCH(*((unsigned int*)&(ctx->Color.ClearColor[0])));
176 R600_OUT_BATCH(*((unsigned int*)&(ctx->Color.ClearColor[1])));
177 R600_OUT_BATCH(*((unsigned int*)&(ctx->Color.ClearColor[2])));
178 R600_OUT_BATCH(*((unsigned int*)&(ctx->Color.ClearColor[3])));
179 END_BATCH();
180 COMMIT_BATCH();
181
182 r700->SPI_VS_OUT_CONFIG.u32All = 0x00000000;
183 r700->SPI_PS_IN_CONTROL_0.u32All = 0x20000001;
184 /* ps */
185 if(0 == r700->pbo_fs_clear)
186 {
187 (context->chipobj.EmitShader)(ctx, &(r700->pbo_fs_clear), (GLvoid *)(&uFs[0]), 12, "Clr PS");
188 }
189
190 r700->SQ_PGM_START_PS.u32All = 0;
191 r700->SQ_PGM_RESOURCES_PS.u32All = 0x00800002;
192 r700->SQ_PGM_EXPORTS_PS.u32All = 0x00000002;
193 r700->DB_SHADER_CONTROL.u32All = 0x00000200;
194
195 r700->CB_SHADER_CONTROL.u32All = 0x00000001;
196
197 /* set a valid base address to make the command checker happy */
198 r700->SQ_PGM_START_FS.u32All = 0;
199 r700->SQ_PGM_START_ES.u32All = 0;
200 r700->SQ_PGM_START_GS.u32All = 0;
201
202 /* Now, send the states */
203 r700SendContextStates(context, GL_TRUE);
204
205 /* Draw */
206 GLuint numEntires, j;
207 GLuint numIndices = 6;
208 unsigned int VGT_DRAW_INITIATOR = 0;
209 unsigned int VGT_INDEX_TYPE = 0;
210 unsigned int VGT_PRIMITIVE_TYPE = 0;
211 unsigned int VGT_NUM_INDICES = 0;
212
213 numEntires = 2 /* VGT_INDEX_TYPE */
214 + 3 /* VGT_PRIMITIVE_TYPE */
215 + numIndices + 3; /* DRAW_INDEX_IMMD */
216
217 BEGIN_BATCH_NO_AUTOSTATE(numEntires);
218
219 SETfield(VGT_INDEX_TYPE, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
220
221 R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
222 R600_OUT_BATCH(VGT_INDEX_TYPE);
223
224 VGT_NUM_INDICES = numIndices;
225
226 SETfield(VGT_PRIMITIVE_TYPE, DI_PT_TRILIST, VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
227
228 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
229 R600_OUT_BATCH(mmVGT_PRIMITIVE_TYPE - ASIC_CONFIG_BASE_INDEX);
230 R600_OUT_BATCH(VGT_PRIMITIVE_TYPE);
231
232 SETfield(VGT_DRAW_INITIATOR, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
233 SETfield(VGT_DRAW_INITIATOR, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
234
235 R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (numIndices + 1)));
236 R600_OUT_BATCH(VGT_NUM_INDICES);
237 R600_OUT_BATCH(VGT_DRAW_INITIATOR);
238
239 for (j=0; j<numIndices; j++)
240 {
241 R600_OUT_BATCH(j);
242 }
243 END_BATCH();
244 COMMIT_BATCH();
245
246 (context->chipobj.FlushCmdBuffer)(context);
247
248 (context->chipobj.FreeDmaRegion)(context, aos_vb.bo);
249
250 /* Restore chip object. */
251 memcpy(r700, &r700Saved, sizeof(R700_CHIP_CONTEXT));
252
253 return GL_TRUE;
254 }
255
256 void r700Clear(GLcontext * ctx, GLbitfield mask)
257 {
258 context_t *context = R700_CONTEXT(ctx);
259
260 if( GL_TRUE == r700ClearFast(context, mask) )
261 {
262 return;
263 }
264
265 //r700ClearWithDraw(context, mask);
266 }
267
268