Merge commit 'origin/gallium-master-merge'
[mesa.git] / src / gallium / drivers / i965simple / brw_blit.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29 #include <stdio.h>
30 #include <errno.h>
31
32 #include "brw_batch.h"
33 #include "brw_blit.h"
34 #include "brw_context.h"
35 #include "brw_reg.h"
36
37 #include "pipe/p_context.h"
38 #include "pipe/internal/p_winsys_screen.h"
39
40 #define FILE_DEBUG_FLAG DEBUG_BLIT
41
42 void brw_fill_blit(struct brw_context *brw,
43 unsigned cpp,
44 short dst_pitch,
45 struct pipe_buffer *dst_buffer,
46 unsigned dst_offset,
47 boolean dst_tiled,
48 short x, short y,
49 short w, short h,
50 unsigned color)
51 {
52 unsigned BR13, CMD;
53 BATCH_LOCALS;
54
55 dst_pitch *= cpp;
56
57 switch(cpp) {
58 case 1:
59 case 2:
60 case 3:
61 BR13 = (0xF0 << 16) | (1<<24);
62 CMD = XY_COLOR_BLT_CMD;
63 break;
64 case 4:
65 BR13 = (0xF0 << 16) | (1<<24) | (1<<25);
66 CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
67 break;
68 default:
69 return;
70 }
71
72 if (dst_tiled) {
73 CMD |= XY_DST_TILED;
74 dst_pitch /= 4;
75 }
76
77 BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
78 OUT_BATCH( CMD );
79 OUT_BATCH( dst_pitch | BR13 );
80 OUT_BATCH( (y << 16) | x );
81 OUT_BATCH( ((y+h) << 16) | (x+w) );
82 OUT_RELOC( dst_buffer, BRW_BUFFER_ACCESS_WRITE, dst_offset );
83 OUT_BATCH( color );
84 ADVANCE_BATCH();
85 }
86
87 static unsigned translate_raster_op(unsigned logicop)
88 {
89 switch(logicop) {
90 case PIPE_LOGICOP_CLEAR: return 0x00;
91 case PIPE_LOGICOP_AND: return 0x88;
92 case PIPE_LOGICOP_AND_REVERSE: return 0x44;
93 case PIPE_LOGICOP_COPY: return 0xCC;
94 case PIPE_LOGICOP_AND_INVERTED: return 0x22;
95 case PIPE_LOGICOP_NOOP: return 0xAA;
96 case PIPE_LOGICOP_XOR: return 0x66;
97 case PIPE_LOGICOP_OR: return 0xEE;
98 case PIPE_LOGICOP_NOR: return 0x11;
99 case PIPE_LOGICOP_EQUIV: return 0x99;
100 case PIPE_LOGICOP_INVERT: return 0x55;
101 case PIPE_LOGICOP_OR_REVERSE: return 0xDD;
102 case PIPE_LOGICOP_COPY_INVERTED: return 0x33;
103 case PIPE_LOGICOP_OR_INVERTED: return 0xBB;
104 case PIPE_LOGICOP_NAND: return 0x77;
105 case PIPE_LOGICOP_SET: return 0xFF;
106 default: return 0;
107 }
108 }
109
110
111 /* Copy BitBlt
112 */
113 void brw_copy_blit(struct brw_context *brw,
114 unsigned do_flip,
115 unsigned cpp,
116 short src_pitch,
117 struct pipe_buffer *src_buffer,
118 unsigned src_offset,
119 boolean src_tiled,
120 short dst_pitch,
121 struct pipe_buffer *dst_buffer,
122 unsigned dst_offset,
123 boolean dst_tiled,
124 short src_x, short src_y,
125 short dst_x, short dst_y,
126 short w, short h,
127 unsigned logic_op)
128 {
129 unsigned CMD, BR13;
130 int dst_y2 = dst_y + h;
131 int dst_x2 = dst_x + w;
132 BATCH_LOCALS;
133
134
135 DBG("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d op:%d\n",
136 __FUNCTION__,
137 src_buffer, src_pitch, src_x, src_y,
138 dst_buffer, dst_pitch, dst_x, dst_y,
139 w,h,logic_op);
140
141 assert( logic_op - PIPE_LOGICOP_CLEAR >= 0 );
142 assert( logic_op - PIPE_LOGICOP_CLEAR < 0x10 );
143
144 src_pitch *= cpp;
145 dst_pitch *= cpp;
146
147 switch(cpp) {
148 case 1:
149 case 2:
150 case 3:
151 BR13 = (translate_raster_op(logic_op) << 16) | (1<<24);
152 CMD = XY_SRC_COPY_BLT_CMD;
153 break;
154 case 4:
155 BR13 = (translate_raster_op(logic_op) << 16) | (1<<24) |
156 (1<<25);
157 CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
158 break;
159 default:
160 return;
161 }
162
163 if (src_tiled) {
164 CMD |= XY_SRC_TILED;
165 src_pitch /= 4;
166 }
167
168 if (dst_tiled) {
169 CMD |= XY_DST_TILED;
170 dst_pitch /= 4;
171 }
172
173 if (dst_y2 < dst_y ||
174 dst_x2 < dst_x) {
175 return;
176 }
177
178 dst_pitch &= 0xffff;
179 src_pitch &= 0xffff;
180
181 /* Initial y values don't seem to work with negative pitches. If
182 * we adjust the offsets manually (below), it seems to work fine.
183 *
184 * On the other hand, if we always adjust, the hardware doesn't
185 * know which blit directions to use, so overlapping copypixels get
186 * the wrong result.
187 */
188 if (dst_pitch > 0 && src_pitch > 0) {
189 BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
190 OUT_BATCH( CMD );
191 OUT_BATCH( dst_pitch | BR13 );
192 OUT_BATCH( (dst_y << 16) | dst_x );
193 OUT_BATCH( (dst_y2 << 16) | dst_x2 );
194 OUT_RELOC( dst_buffer, BRW_BUFFER_ACCESS_WRITE,
195 dst_offset );
196 OUT_BATCH( (src_y << 16) | src_x );
197 OUT_BATCH( src_pitch );
198 OUT_RELOC( src_buffer, BRW_BUFFER_ACCESS_READ,
199 src_offset );
200 ADVANCE_BATCH();
201 }
202 else {
203 BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
204 OUT_BATCH( CMD );
205 OUT_BATCH( (dst_pitch & 0xffff) | BR13 );
206 OUT_BATCH( (0 << 16) | dst_x );
207 OUT_BATCH( (h << 16) | dst_x2 );
208 OUT_RELOC( dst_buffer, BRW_BUFFER_ACCESS_WRITE,
209 dst_offset + dst_y * dst_pitch );
210 OUT_BATCH( (src_pitch & 0xffff) );
211 OUT_RELOC( src_buffer, BRW_BUFFER_ACCESS_READ,
212 src_offset + src_y * src_pitch );
213 ADVANCE_BATCH();
214 }
215 }
216
217
218