Remove mapping fields from struct pipe_surface.
[mesa.git] / src / mesa / pipe / i965simple / brw_surface.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 #include "brw_blit.h"
29 #include "brw_context.h"
30 #include "brw_state.h"
31 #include "pipe/p_defines.h"
32 #include "pipe/p_util.h"
33 #include "pipe/p_inlines.h"
34 #include "pipe/p_winsys.h"
35 #include "pipe/util/p_tile.h"
36
37
38 /*
39 * XXX note: same as code in sp_surface.c
40 */
41 static struct pipe_surface *
42 brw_get_tex_surface(struct pipe_context *pipe,
43 struct pipe_texture *pt,
44 unsigned face, unsigned level, unsigned zslice)
45 {
46 struct brw_texture *tex = (struct brw_texture *)pt;
47 struct pipe_surface *ps;
48 unsigned offset; /* in bytes */
49
50 offset = tex->level_offset[level];
51
52 if (pt->target == PIPE_TEXTURE_CUBE) {
53 offset += tex->image_offset[level][face] * pt->cpp;
54 }
55 else if (pt->target == PIPE_TEXTURE_3D) {
56 offset += tex->image_offset[level][zslice] * pt->cpp;
57 }
58 else {
59 assert(face == 0);
60 assert(zslice == 0);
61 }
62
63 ps = pipe->winsys->surface_alloc(pipe->winsys);
64 if (ps) {
65 assert(ps->format);
66 assert(ps->refcount);
67 pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, tex->buffer);
68 ps->format = pt->format;
69 ps->cpp = pt->cpp;
70 ps->width = pt->width[level];
71 ps->height = pt->height[level];
72 ps->pitch = tex->pitch;
73 ps->offset = offset;
74 }
75 return ps;
76 }
77
78
79 static void
80 copy_rect(ubyte * dst,
81 unsigned cpp,
82 unsigned dst_pitch,
83 unsigned dst_x,
84 unsigned dst_y,
85 unsigned width,
86 unsigned height,
87 const ubyte *src,
88 unsigned src_pitch,
89 unsigned src_x,
90 unsigned src_y)
91 {
92 unsigned i;
93
94 dst_pitch *= cpp;
95 src_pitch *= cpp;
96 dst += dst_x * cpp;
97 src += src_x * cpp;
98 dst += dst_y * dst_pitch;
99 src += src_y * dst_pitch;
100 width *= cpp;
101
102 if (width == dst_pitch && width == src_pitch)
103 memcpy(dst, src, height * width);
104 else {
105 for (i = 0; i < height; i++) {
106 memcpy(dst, src, width);
107 dst += dst_pitch;
108 src += src_pitch;
109 }
110 }
111 }
112
113 /* Upload data to a rectangular sub-region. Lots of choices how to do this:
114 *
115 * - memcpy by span to current destination
116 * - upload data as new buffer and blit
117 *
118 * Currently always memcpy.
119 */
120 static void
121 brw_surface_data(struct pipe_context *pipe,
122 struct pipe_surface *dst,
123 unsigned dstx, unsigned dsty,
124 const void *src, unsigned src_pitch,
125 unsigned srcx, unsigned srcy, unsigned width, unsigned height)
126 {
127 copy_rect(pipe_surface_map(dst) + dst->offset,
128 dst->cpp, dst->pitch,
129 dstx, dsty, width, height, src, src_pitch, srcx, srcy);
130
131 pipe_surface_unmap(dst);
132 }
133
134
135 /* Assumes all values are within bounds -- no checking at this level -
136 * do it higher up if required.
137 */
138 static void
139 brw_surface_copy(struct pipe_context *pipe,
140 struct pipe_surface *dst,
141 unsigned dstx, unsigned dsty,
142 struct pipe_surface *src,
143 unsigned srcx, unsigned srcy, unsigned width, unsigned height)
144 {
145 assert(dst != src);
146 assert(dst->cpp == src->cpp);
147
148 if (0) {
149 copy_rect(pipe_surface_map(dst) + dst->offset,
150 dst->cpp,
151 dst->pitch,
152 dstx, dsty,
153 width, height,
154 pipe_surface_map(src) + src->offset,
155 src->pitch,
156 srcx, srcy);
157
158 pipe_surface_unmap(src);
159 pipe_surface_unmap(dst);
160 }
161 else {
162 brw_copy_blit(brw_context(pipe),
163 dst->cpp,
164 (short) src->pitch, src->buffer, src->offset, FALSE,
165 (short) dst->pitch, dst->buffer, dst->offset, FALSE,
166 (short) srcx, (short) srcy, (short) dstx, (short) dsty,
167 (short) width, (short) height, PIPE_LOGICOP_COPY);
168 }
169 }
170
171 /* Fill a rectangular sub-region. Need better logic about when to
172 * push buffers into AGP - will currently do so whenever possible.
173 */
174 static void *
175 get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
176 {
177 return (char *)dst_map + (y * dst->pitch + x) * dst->cpp;
178 }
179
180
181 static void
182 brw_surface_fill(struct pipe_context *pipe,
183 struct pipe_surface *dst,
184 unsigned dstx, unsigned dsty,
185 unsigned width, unsigned height, unsigned value)
186 {
187 if (0) {
188 unsigned i, j;
189 void *dst_map = pipe_surface_map(dst);
190
191 switch (dst->cpp) {
192 case 1: {
193 ubyte *row = get_pointer(dst, dst_map, dstx, dsty);
194 for (i = 0; i < height; i++) {
195 memset(row, value, width);
196 row += dst->pitch;
197 }
198 }
199 break;
200 case 2: {
201 ushort *row = get_pointer(dst, dst_map, dstx, dsty);
202 for (i = 0; i < height; i++) {
203 for (j = 0; j < width; j++)
204 row[j] = (ushort) value;
205 row += dst->pitch;
206 }
207 }
208 break;
209 case 4: {
210 unsigned *row = get_pointer(dst, dst_map, dstx, dsty);
211 for (i = 0; i < height; i++) {
212 for (j = 0; j < width; j++)
213 row[j] = value;
214 row += dst->pitch;
215 }
216 }
217 break;
218 default:
219 assert(0);
220 break;
221 }
222
223 pipe_surface_unmap( dst );
224 }
225 else {
226 brw_fill_blit(brw_context(pipe),
227 dst->cpp,
228 (short) dst->pitch,
229 dst->buffer, dst->offset, FALSE,
230 (short) dstx, (short) dsty,
231 (short) width, (short) height,
232 value);
233 }
234 }
235
236 void
237 brw_init_surface_functions(struct brw_context *brw)
238 {
239 brw->pipe.get_tex_surface = brw_get_tex_surface;
240 brw->pipe.get_tile = pipe_get_tile_raw;
241 brw->pipe.put_tile = pipe_put_tile_raw;
242 brw->pipe.get_tile_rgba = pipe_get_tile_rgba;
243 brw->pipe.put_tile_rgba = pipe_put_tile_rgba;
244
245 brw->pipe.surface_data = brw_surface_data;
246 brw->pipe.surface_copy = brw_surface_copy;
247 brw->pipe.surface_fill = brw_surface_fill;
248 }