Merge branch 'nouveau-gallium-0.1' into darktama-gallium-0.1
[mesa.git] / src / mesa / pipe / nv50 / nv50_surface.c
1
2 /**************************************************************************
3 *
4 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29 #include "nv50_context.h"
30 #include "pipe/p_defines.h"
31 #include "pipe/p_util.h"
32 #include "pipe/p_winsys.h"
33 #include "pipe/p_inlines.h"
34
35
36 #define CLIP_TILE \
37 do { \
38 if (x >= ps->width) \
39 return; \
40 if (y >= ps->height) \
41 return; \
42 if (x + w > ps->width) \
43 w = ps->width - x; \
44 if (y + h > ps->height) \
45 h = ps->height -y; \
46 } while(0)
47
48
49 /**
50 * Note: this is exactly like a8r8g8b8_get_tile() in sp_surface.c
51 * Share it someday.
52 */
53 static void
54 nv50_get_tile_rgba(struct pipe_context *pipe,
55 struct pipe_surface *ps,
56 uint x, uint y, uint w, uint h, float *p)
57 {
58 const unsigned *src
59 = ((const unsigned *) (ps->map + ps->offset))
60 + y * ps->pitch + x;
61 unsigned i, j;
62 unsigned w0 = w;
63
64 CLIP_TILE;
65
66 switch (ps->format) {
67 case PIPE_FORMAT_A8R8G8B8_UNORM:
68 for (i = 0; i < h; i++) {
69 float *pRow = p;
70 for (j = 0; j < w; j++) {
71 const unsigned pixel = src[j];
72 pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff);
73 pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff);
74 pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff);
75 pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff);
76 pRow += 4;
77 }
78 src += ps->pitch;
79 p += w0 * 4;
80 }
81 break;
82 case PIPE_FORMAT_Z24S8_UNORM:
83 {
84 const float scale = 1.0 / (float) 0xffffff;
85 for (i = 0; i < h; i++) {
86 float *pRow = p;
87 for (j = 0; j < w; j++) {
88 const unsigned pixel = src[j];
89 pRow[0] =
90 pRow[1] =
91 pRow[2] =
92 pRow[3] = ((pixel & 0xffffff) >> 8) * scale;
93 pRow += 4;
94 }
95 src += ps->pitch;
96 p += w0 * 4;
97 }
98 }
99 break;
100 default:
101 assert(0);
102 }
103 }
104
105
106 static void
107 nv50_put_tile_rgba(struct pipe_context *pipe,
108 struct pipe_surface *ps,
109 uint x, uint y, uint w, uint h, const float *p)
110 {
111 /* TODO */
112 assert(0);
113 }
114
115
116 /*
117 * XXX note: same as code in sp_surface.c
118 */
119 static void
120 nv50_get_tile(struct pipe_context *pipe,
121 struct pipe_surface *ps,
122 uint x, uint y, uint w, uint h,
123 void *p, int dst_stride)
124 {
125 const uint cpp = ps->cpp;
126 const uint w0 = w;
127 const ubyte *pSrc;
128 ubyte *pDest;
129 uint i;
130
131 assert(ps->map);
132
133 CLIP_TILE;
134
135 if (dst_stride == 0) {
136 dst_stride = w0 * cpp;
137 }
138
139 pSrc = ps->map + ps->offset + (y * ps->pitch + x) * cpp;
140 pDest = (ubyte *) p;
141
142 for (i = 0; i < h; i++) {
143 memcpy(pDest, pSrc, w0 * cpp);
144 pDest += dst_stride;
145 pSrc += ps->pitch * cpp;
146 }
147 }
148
149
150 /*
151 * XXX note: same as code in sp_surface.c
152 */
153 static void
154 nv50_put_tile(struct pipe_context *pipe,
155 struct pipe_surface *ps,
156 uint x, uint y, uint w, uint h,
157 const void *p, int src_stride)
158 {
159 const uint cpp = ps->cpp;
160 const uint w0 = w;
161 const ubyte *pSrc;
162 ubyte *pDest;
163 uint i;
164
165 assert(ps->map);
166
167 CLIP_TILE;
168
169 if (src_stride == 0) {
170 src_stride = w0 * cpp;
171 }
172
173 pSrc = (const ubyte *) p;
174 pDest = ps->map + ps->offset + (y * ps->pitch + x) * cpp;
175
176 for (i = 0; i < h; i++) {
177 memcpy(pDest, pSrc, w0 * cpp);
178 pDest += ps->pitch * cpp;
179 pSrc += src_stride;
180 }
181 }
182
183
184 static struct pipe_surface *
185 nv50_get_tex_surface(struct pipe_context *pipe,
186 struct pipe_texture *pt,
187 unsigned face, unsigned level, unsigned zslice)
188 {
189 NOUVEAU_ERR("unimplemented\n");
190 return NULL;
191 }
192
193 static void
194 nv50_surface_data(struct pipe_context *pipe, struct pipe_surface *dest,
195 unsigned destx, unsigned desty, const void *src,
196 unsigned src_stride, unsigned srcx, unsigned srcy,
197 unsigned width, unsigned height)
198 {
199 struct nv50_context *nv50 = (struct nv50_context *)pipe;
200 struct nouveau_winsys *nvws = nv50->nvws;
201
202 nvws->surface_data(nvws, dest, destx, desty, src, src_stride,
203 srcx, srcy, width, height);
204 }
205
206 static void
207 nv50_surface_copy(struct pipe_context *pipe, struct pipe_surface *dest,
208 unsigned destx, unsigned desty, struct pipe_surface *src,
209 unsigned srcx, unsigned srcy, unsigned width, unsigned height)
210 {
211 struct nv50_context *nv50 = (struct nv50_context *)pipe;
212 struct nouveau_winsys *nvws = nv50->nvws;
213
214 nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy,
215 width, height);
216 }
217
218 static void
219 nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
220 unsigned destx, unsigned desty, unsigned width,
221 unsigned height, unsigned value)
222 {
223 struct nv50_context *nv50 = (struct nv50_context *)pipe;
224 struct nouveau_winsys *nvws = nv50->nvws;
225
226 nvws->surface_fill(nvws, dest, destx, desty, width, height, value);
227 }
228
229 void
230 nv50_init_surface_functions(struct nv50_context *nv50)
231 {
232 nv50->pipe.get_tex_surface = nv50_get_tex_surface;
233 nv50->pipe.get_tile = nv50_get_tile;
234 nv50->pipe.put_tile = nv50_put_tile;
235 nv50->pipe.get_tile_rgba = nv50_get_tile_rgba;
236 nv50->pipe.put_tile_rgba = nv50_put_tile_rgba;
237 nv50->pipe.surface_data = nv50_surface_data;
238 nv50->pipe.surface_copy = nv50_surface_copy;
239 nv50->pipe.surface_fill = nv50_surface_fill;
240 }