1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 #include "i915_context.h"
29 #include "i915_blit.h"
30 #include "i915_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"
41 if (y >= ps->height) \
43 if (x + w > ps->width) \
45 if (y + h > ps->height) \
51 * Note: this is exactly like a8r8g8b8_get_tile() in sp_surface.c
55 i915_get_tile_rgba(struct pipe_context
*pipe
,
56 struct pipe_surface
*ps
,
57 uint x
, uint y
, uint w
, uint h
, float *p
)
60 = ((const unsigned *) (ps
->region
->map
+ ps
->offset
))
68 case PIPE_FORMAT_U_A8_R8_G8_B8
:
69 for (i
= 0; i
< h
; i
++) {
71 for (j
= 0; j
< w
; j
++) {
72 const unsigned pixel
= src
[j
];
73 pRow
[0] = UBYTE_TO_FLOAT((pixel
>> 16) & 0xff);
74 pRow
[1] = UBYTE_TO_FLOAT((pixel
>> 8) & 0xff);
75 pRow
[2] = UBYTE_TO_FLOAT((pixel
>> 0) & 0xff);
76 pRow
[3] = UBYTE_TO_FLOAT((pixel
>> 24) & 0xff);
83 case PIPE_FORMAT_S8_Z24
:
85 const float scale
= 1.0f
/ (float) 0xffffff;
86 for (i
= 0; i
< h
; i
++) {
88 for (j
= 0; j
< w
; j
++) {
89 const unsigned pixel
= src
[j
];
93 pRow
[3] = (pixel
& 0xffffff) * scale
;
108 i915_put_tile_rgba(struct pipe_context
*pipe
,
109 struct pipe_surface
*ps
,
110 uint x
, uint y
, uint w
, uint h
, const float *p
)
118 * XXX note: same as code in sp_surface.c
121 i915_get_tile(struct pipe_context
*pipe
,
122 struct pipe_surface
*ps
,
123 uint x
, uint y
, uint w
, uint h
,
124 void *p
, int dst_stride
)
126 const uint cpp
= ps
->cpp
;
132 assert(ps
->region
->map
);
136 if (dst_stride
== 0) {
137 dst_stride
= w0
* cpp
;
140 pSrc
= ps
->region
->map
+ ps
->offset
+ (y
* ps
->pitch
+ x
) * cpp
;
143 for (i
= 0; i
< h
; i
++) {
144 memcpy(pDest
, pSrc
, w0
* cpp
);
146 pSrc
+= ps
->pitch
* cpp
;
152 * XXX note: same as code in sp_surface.c
155 i915_put_tile(struct pipe_context
*pipe
,
156 struct pipe_surface
*ps
,
157 uint x
, uint y
, uint w
, uint h
,
158 const void *p
, int src_stride
)
160 const uint cpp
= ps
->cpp
;
166 assert(ps
->region
->map
);
170 if (src_stride
== 0) {
171 src_stride
= w0
* cpp
;
174 pSrc
= (const ubyte
*) p
;
175 pDest
= ps
->region
->map
+ ps
->offset
+ (y
* ps
->pitch
+ x
) * cpp
;
177 for (i
= 0; i
< h
; i
++) {
178 memcpy(pDest
, pSrc
, w0
* cpp
);
179 pDest
+= ps
->pitch
* cpp
;
186 * XXX note: same as code in sp_surface.c
188 static struct pipe_surface
*
189 i915_get_tex_surface(struct pipe_context
*pipe
,
190 struct pipe_texture
*pt
,
191 unsigned face
, unsigned level
, unsigned zslice
)
193 struct i915_texture
*tex
= (struct i915_texture
*)pt
;
194 struct pipe_surface
*ps
;
195 unsigned offset
; /* in bytes */
197 offset
= tex
->level_offset
[level
];
199 if (pt
->target
== PIPE_TEXTURE_CUBE
) {
200 offset
+= tex
->image_offset
[level
][face
] * pt
->cpp
;
202 else if (pt
->target
== PIPE_TEXTURE_3D
) {
203 offset
+= tex
->image_offset
[level
][zslice
] * pt
->cpp
;
210 ps
= pipe
->winsys
->surface_alloc(pipe
->winsys
, pt
->format
);
213 assert(ps
->refcount
);
214 pipe_region_reference(&ps
->region
, tex
->region
);
216 ps
->width
= pt
->width
[level
];
217 ps
->height
= pt
->height
[level
];
218 ps
->pitch
= tex
->pitch
;
226 * XXX Move this into core Mesa?
229 _mesa_copy_rect(ubyte
* dst
,
247 dst
+= dst_y
* dst_pitch
;
248 src
+= src_y
* dst_pitch
;
251 if (width
== dst_pitch
&& width
== src_pitch
)
252 memcpy(dst
, src
, height
* width
);
254 for (i
= 0; i
< height
; i
++) {
255 memcpy(dst
, src
, width
);
263 /* Upload data to a rectangular sub-region. Lots of choices how to do this:
265 * - memcpy by span to current destination
266 * - upload data as new buffer and blit
268 * Currently always memcpy.
271 i915_surface_data(struct pipe_context
*pipe
,
272 struct pipe_surface
*dst
,
273 unsigned dstx
, unsigned dsty
,
274 const void *src
, unsigned src_pitch
,
275 unsigned srcx
, unsigned srcy
, unsigned width
, unsigned height
)
277 _mesa_copy_rect(pipe
->region_map(pipe
, dst
->region
) + dst
->offset
,
280 dstx
, dsty
, width
, height
, src
, src_pitch
, srcx
, srcy
);
282 pipe
->region_unmap(pipe
, dst
->region
);
286 /* Assumes all values are within bounds -- no checking at this level -
287 * do it higher up if required.
290 i915_surface_copy(struct pipe_context
*pipe
,
291 struct pipe_surface
*dst
,
292 unsigned dstx
, unsigned dsty
,
293 struct pipe_surface
*src
,
294 unsigned srcx
, unsigned srcy
, unsigned width
, unsigned height
)
296 assert( dst
!= src
);
297 assert( dst
->cpp
== src
->cpp
);
300 _mesa_copy_rect(pipe
->region_map(pipe
, dst
->region
) + dst
->offset
,
305 pipe
->region_map(pipe
, src
->region
) + src
->offset
,
309 pipe
->region_unmap(pipe
, src
->region
);
310 pipe
->region_unmap(pipe
, dst
->region
);
313 i915_copy_blit( i915_context(pipe
),
315 (short) src
->pitch
, src
->region
->buffer
, src
->offset
,
316 (short) dst
->pitch
, dst
->region
->buffer
, dst
->offset
,
317 (short) srcx
, (short) srcy
, (short) dstx
, (short) dsty
, (short) width
, (short) height
);
321 /* Fill a rectangular sub-region. Need better logic about when to
322 * push buffers into AGP - will currently do so whenever possible.
325 get_pointer(struct pipe_surface
*dst
, unsigned x
, unsigned y
)
327 return dst
->region
->map
+ (y
* dst
->pitch
+ x
) * dst
->cpp
;
332 i915_surface_fill(struct pipe_context
*pipe
,
333 struct pipe_surface
*dst
,
334 unsigned dstx
, unsigned dsty
,
335 unsigned width
, unsigned height
, unsigned value
)
340 (void)pipe
->region_map(pipe
, dst
->region
);
344 ubyte
*row
= get_pointer(dst
, dstx
, dsty
);
345 for (i
= 0; i
< height
; i
++) {
346 memset(row
, value
, width
);
352 ushort
*row
= (ushort
*) get_pointer(dst
, dstx
, dsty
);
353 for (i
= 0; i
< height
; i
++) {
354 for (j
= 0; j
< width
; j
++)
355 row
[j
] = (ushort
) value
;
361 unsigned *row
= (unsigned *) get_pointer(dst
, dstx
, dsty
);
362 for (i
= 0; i
< height
; i
++) {
363 for (j
= 0; j
< width
; j
++)
375 i915_fill_blit( i915_context(pipe
),
378 dst
->region
->buffer
, dst
->offset
,
379 (short) dstx
, (short) dsty
,
380 (short) width
, (short) height
,
387 i915_init_surface_functions(struct i915_context
*i915
)
389 i915
->pipe
.get_tex_surface
= i915_get_tex_surface
;
390 i915
->pipe
.get_tile
= i915_get_tile
;
391 i915
->pipe
.put_tile
= i915_put_tile
;
392 i915
->pipe
.get_tile_rgba
= i915_get_tile_rgba
;
393 i915
->pipe
.put_tile_rgba
= i915_put_tile_rgba
;
394 i915
->pipe
.surface_data
= i915_surface_data
;
395 i915
->pipe
.surface_copy
= i915_surface_copy
;
396 i915
->pipe
.surface_fill
= i915_surface_fill
;