r300g: Use r300compiler for vertex shaders
[mesa.git] / src / gallium / drivers / r300 / r300_surface.c
1 /*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 * Joakim Sindholt <opensource@zhasha.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23
24 #include "r300_surface.h"
25
26 static void r300_surface_setup(struct r300_context* r300,
27 struct r300_texture* dest,
28 unsigned x, unsigned y,
29 unsigned w, unsigned h)
30 {
31 struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
32 unsigned pixpitch = dest->stride / dest->tex.block.size;
33 CS_LOCALS(r300);
34
35 r300_emit_blend_state(r300, &blend_clear_state);
36 r300_emit_blend_color_state(r300, &blend_color_clear_state);
37 r300_emit_dsa_state(r300, &dsa_clear_state);
38 r300_emit_rs_state(r300, &rs_clear_state);
39
40 BEGIN_CS(24);
41
42 /* Viewport setup */
43 OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
44 OUT_CS_32F((float)w);
45 OUT_CS_32F((float)x);
46 OUT_CS_32F((float)h);
47 OUT_CS_32F((float)y);
48 OUT_CS_32F(1.0);
49 OUT_CS_32F(0.0);
50
51 OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VPORT_X_SCALE_ENA |
52 R300_VPORT_X_OFFSET_ENA |
53 R300_VPORT_Y_SCALE_ENA |
54 R300_VPORT_Y_OFFSET_ENA |
55 R300_VTX_XY_FMT | R300_VTX_Z_FMT);
56
57 /* Pixel scissors. */
58 OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
59 if (caps->is_r500) {
60 OUT_CS((x << R300_SCISSORS_X_SHIFT) | (y << R300_SCISSORS_Y_SHIFT));
61 OUT_CS((w << R300_SCISSORS_X_SHIFT) | (h << R300_SCISSORS_Y_SHIFT));
62 } else {
63 /* Non-R500 chipsets have an offset of 1440 in their scissors. */
64 OUT_CS(((x + 1440) << R300_SCISSORS_X_SHIFT) |
65 ((y + 1440) << R300_SCISSORS_Y_SHIFT));
66 OUT_CS(((w + 1440) << R300_SCISSORS_X_SHIFT) |
67 ((h + 1440) << R300_SCISSORS_Y_SHIFT));
68 }
69
70 /* Flush colorbuffer and blend caches. */
71 OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
72 R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D |
73 R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_SIGNAL);
74 OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
75 R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
76 R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
77
78 /* Setup colorbuffer. */
79 OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1);
80 OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
81 OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch |
82 r300_translate_colorformat(dest->tex.format));
83 OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf);
84
85 END_CS;
86 }
87
88 /* Provides pipe_context's "surface_fill". Commonly used for clearing
89 * buffers. */
90 static void r300_surface_fill(struct pipe_context* pipe,
91 struct pipe_surface* dest,
92 unsigned x, unsigned y,
93 unsigned w, unsigned h,
94 unsigned color)
95 {
96 int i;
97 float r, g, b, a, depth;
98 struct r300_context* r300 = r300_context(pipe);
99 struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;
100 struct r300_texture* tex = (struct r300_texture*)dest->texture;
101 unsigned pixpitch = tex->stride / tex->tex.block.size;
102 boolean invalid = FALSE;
103 CS_LOCALS(r300);
104
105 a = (float)((color >> 24) & 0xff) / 255.0f;
106 r = (float)((color >> 16) & 0xff) / 255.0f;
107 g = (float)((color >> 8) & 0xff) / 255.0f;
108 b = (float)((color >> 0) & 0xff) / 255.0f;
109 debug_printf("r300: Filling surface %p at (%d,%d),"
110 " dimensions %dx%d (pixel pitch %d), color 0x%x\n",
111 dest, x, y, w, h, pixpitch, color);
112
113 /* Fallback? */
114 if (FALSE) {
115 fallback:
116 debug_printf("r300: Falling back on surface clear...");
117 util_surface_fill(pipe, dest, x, y, w, h, color);
118 return;
119 }
120
121 /* Make sure our target BO is okay. */
122 validate:
123 if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
124 0, RADEON_GEM_DOMAIN_VRAM)) {
125 r300->context.flush(&r300->context, 0, NULL);
126 goto validate;
127 }
128 if (!r300->winsys->validate(r300->winsys)) {
129 r300->context.flush(&r300->context, 0, NULL);
130 if (invalid) {
131 debug_printf("r300: Stuck in validation loop, gonna fallback.");
132 goto fallback;
133 }
134 invalid = TRUE;
135 goto validate;
136 }
137
138 r300_surface_setup(r300, tex, x, y, w, h);
139
140 /* Vertex shader setup */
141 if (caps->has_tcl) {
142 r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);
143 } else {
144 BEGIN_CS(4);
145 OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
146 OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |
147 R300_PVS_NUM_CNTLRS(5) |
148 R300_PVS_NUM_FPUS(caps->num_vert_fpus) |
149 R300_PVS_VF_MAX_VTX_NUM(12));
150 END_CS;
151 }
152
153 /* Fragment shader setup */
154 if (caps->is_r500) {
155 r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader);
156 r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);
157 } else {
158 r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader);
159 r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);
160 }
161
162 BEGIN_CS(26);
163
164 /* VAP stream control, mapping from input memory to PVS/RS memory */
165 if (caps->has_tcl) {
166 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
167 (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) |
168 ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) |
169 R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT));
170 } else {
171 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
172 (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) |
173 ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) |
174 R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT));
175 }
176 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
177 (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) |
178 (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT));
179
180 /* VAP format controls */
181 OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0,
182 R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT |
183 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT);
184 OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x0);
185
186 /* Disable textures */
187 OUT_CS_REG(R300_TX_ENABLE, 0x0);
188
189 /* The size of the point we're about to draw, in sixths of pixels */
190 OUT_CS_REG(R300_GA_POINT_SIZE,
191 ((h * 6) & R300_POINTSIZE_Y_MASK) |
192 ((w * 6) << R300_POINTSIZE_X_SHIFT));
193
194 /* Vertex size. */
195 OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8);
196
197 /* Packet3 with our point vertex */
198 OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8);
199 OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
200 (1 << R300_PRIM_NUM_VERTICES_SHIFT));
201 /* Position */
202 OUT_CS_32F(0.5);
203 OUT_CS_32F(0.5);
204 OUT_CS_32F(1.0);
205 OUT_CS_32F(1.0);
206 /* Color */
207 OUT_CS_32F(r);
208 OUT_CS_32F(g);
209 OUT_CS_32F(b);
210 OUT_CS_32F(a);
211
212 OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
213
214 END_CS;
215
216 r300->dirty_hw++;
217 }
218
219 static void r300_surface_copy(struct pipe_context* pipe,
220 struct pipe_surface* dest,
221 unsigned destx, unsigned desty,
222 struct pipe_surface* src,
223 unsigned srcx, unsigned srcy,
224 unsigned w, unsigned h)
225 {
226 struct r300_context* r300 = r300_context(pipe);
227 struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;
228 struct r300_texture* srctex = (struct r300_texture*)src->texture;
229 struct r300_texture* desttex = (struct r300_texture*)dest->texture;
230 unsigned pixpitch = srctex->stride / srctex->tex.block.size;
231 boolean invalid = FALSE;
232 float fsrcx = srcx, fsrcy = srcy, fdestx = destx, fdesty = desty;
233 CS_LOCALS(r300);
234
235 debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d),"
236 " dimensions %dx%d (pixel pitch %d)\n",
237 src, srcx, srcy, dest, destx, desty, w, h, pixpitch);
238
239 if ((srctex->buffer == desttex->buffer) &&
240 ((destx < srcx + w) || (srcx < destx + w)) &&
241 ((desty < srcy + h) || (srcy < desty + h))) {
242 fallback:
243 debug_printf("r300: Falling back on surface_copy\n");
244 util_surface_copy(pipe, FALSE, dest, destx, desty, src,
245 srcx, srcy, w, h);
246 }
247
248 /* Add our target BOs to the list. */
249 validate:
250 if (!r300->winsys->add_buffer(r300->winsys, srctex->buffer,
251 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
252 r300->context.flush(&r300->context, 0, NULL);
253 goto validate;
254 }
255 if (!r300->winsys->add_buffer(r300->winsys, desttex->buffer,
256 0, RADEON_GEM_DOMAIN_VRAM)) {
257 r300->context.flush(&r300->context, 0, NULL);
258 goto validate;
259 }
260 if (!r300->winsys->validate(r300->winsys)) {
261 r300->context.flush(&r300->context, 0, NULL);
262 if (invalid) {
263 debug_printf("r300: Stuck in validation loop, gonna fallback.");
264 goto fallback;
265 }
266 invalid = TRUE;
267 goto validate;
268 }
269
270 r300_surface_setup(r300, desttex, destx, desty, w, h);
271
272 /* Setup the texture. */
273 r300_emit_texture(r300, &r300_sampler_copy_state, srctex, 0);
274
275 /* Flush and enable. */
276 r300_flush_textures(r300);
277
278 /* Vertex shader setup */
279 if (caps->has_tcl) {
280 r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);
281 } else {
282 BEGIN_CS(4);
283 OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
284 OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |
285 R300_PVS_NUM_CNTLRS(5) |
286 R300_PVS_NUM_FPUS(caps->num_vert_fpus) |
287 R300_PVS_VF_MAX_VTX_NUM(12));
288 END_CS;
289 }
290
291 /* Fragment shader setup */
292 if (caps->is_r500) {
293 r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader);
294 r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);
295 } else {
296 r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader);
297 r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);
298 }
299
300 BEGIN_CS(30);
301 /* VAP stream control, mapping from input memory to PVS/RS memory */
302 if (caps->has_tcl) {
303 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
304 (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
305 ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) |
306 R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT));
307 } else {
308 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
309 (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) |
310 ((R300_LAST_VEC | (6 << R300_DST_VEC_LOC_SHIFT) |
311 R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT));
312 }
313 OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
314 (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) |
315 (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT));
316
317 /* VAP format controls */
318 OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0,
319 R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT);
320 /* Two components of texture 0 */
321 OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x2);
322
323 /* Vertex size. */
324 OUT_CS_REG(R300_VAP_VTX_SIZE, 0x4);
325
326 /* Packet3 with our texcoords */
327 OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 16);
328 OUT_CS(R300_PRIM_TYPE_QUADS | R300_PRIM_WALK_RING |
329 (4 << R300_PRIM_NUM_VERTICES_SHIFT));
330 /* (x , y ) */
331 OUT_CS_32F(fdestx / dest->width);
332 OUT_CS_32F(fdesty / dest->height);
333 OUT_CS_32F(fsrcx / src->width);
334 OUT_CS_32F(fsrcy / src->height);
335 /* (x , y + h) */
336 OUT_CS_32F(fdestx / dest->width);
337 OUT_CS_32F((fdesty + h) / dest->height);
338 OUT_CS_32F(fsrcx / src->width);
339 OUT_CS_32F((fsrcy + h) / src->height);
340 /* (x + w, y + h) */
341 OUT_CS_32F((fdestx + w) / dest->width);
342 OUT_CS_32F((fdesty + h) / dest->height);
343 OUT_CS_32F((fsrcx + w) / src->width);
344 OUT_CS_32F((fsrcy + h) / src->height);
345 /* (x + w, y ) */
346 OUT_CS_32F((fdestx + w) / dest->width);
347 OUT_CS_32F(fdesty / dest->height);
348 OUT_CS_32F((fsrcx + w) / src->width);
349 OUT_CS_32F(fsrcy / src->height);
350
351 OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
352
353 END_CS;
354
355 r300->dirty_hw++;
356 }
357
358 void r300_init_surface_functions(struct r300_context* r300)
359 {
360 r300->context.surface_fill = r300_surface_fill;
361 r300->context.surface_copy = r300_surface_copy;
362 }