1 /**************************************************************************
3 * Copyright 2006 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 /* Provide additional functionality on top of bufmgr buffers:
29 * - 2d semantics and blit operations (XXX: remove/simplify blits??)
30 * - refcounting of buffers for multiple images in a buffer.
31 * - refcounting of buffer mappings.
34 #include "pipe/p_defines.h"
35 #include "pipe/p_winsys.h"
36 #include "i915_context.h"
37 #include "i915_blit.h"
43 i915_region_map(struct pipe_context
*pipe
, struct pipe_region
*region
)
45 struct i915_context
*i915
= i915_context( pipe
);
47 if (!region
->map_refcount
++) {
48 region
->map
= i915
->pipe
.winsys
->buffer_map( i915
->pipe
.winsys
,
50 PIPE_BUFFER_FLAG_WRITE
|
51 PIPE_BUFFER_FLAG_READ
);
58 i915_region_unmap(struct pipe_context
*pipe
, struct pipe_region
*region
)
60 struct i915_context
*i915
= i915_context( pipe
);
62 if (region
->map_refcount
> 0) {
64 if (!--region
->map_refcount
) {
65 i915
->pipe
.winsys
->buffer_unmap( i915
->pipe
.winsys
,
74 * XXX Move this into core Mesa?
77 _mesa_copy_rect(ubyte
* dst
,
95 dst
+= dst_y
* dst_pitch
;
96 src
+= src_y
* dst_pitch
;
99 if (width
== dst_pitch
&& width
== src_pitch
)
100 memcpy(dst
, src
, height
* width
);
102 for (i
= 0; i
< height
; i
++) {
103 memcpy(dst
, src
, width
);
111 /* Upload data to a rectangular sub-region. Lots of choices how to do this:
113 * - memcpy by span to current destination
114 * - upload data as new buffer and blit
116 * Currently always memcpy.
119 i915_region_data(struct pipe_context
*pipe
,
120 struct pipe_region
*dst
,
122 unsigned dstx
, unsigned dsty
,
123 const void *src
, unsigned src_pitch
,
124 unsigned srcx
, unsigned srcy
, unsigned width
, unsigned height
)
126 _mesa_copy_rect(pipe
->region_map(pipe
, dst
) + dst_offset
,
129 dstx
, dsty
, width
, height
, src
, src_pitch
, srcx
, srcy
);
131 pipe
->region_unmap(pipe
, dst
);
135 /* Assumes all values are within bounds -- no checking at this level -
136 * do it higher up if required.
139 i915_region_copy(struct pipe_context
*pipe
,
140 struct pipe_region
*dst
,
142 unsigned dstx
, unsigned dsty
,
143 struct pipe_region
*src
,
145 unsigned srcx
, unsigned srcy
, unsigned width
, unsigned height
)
147 assert( dst
!= src
);
148 assert( dst
->cpp
== src
->cpp
);
151 _mesa_copy_rect(pipe
->region_map(pipe
, dst
) + dst_offset
,
156 pipe
->region_map(pipe
, src
) + src_offset
,
160 pipe
->region_unmap(pipe
, src
);
161 pipe
->region_unmap(pipe
, dst
);
164 i915_copy_blit( i915_context(pipe
),
166 src
->pitch
, src
->buffer
, src_offset
,
167 dst
->pitch
, dst
->buffer
, dst_offset
,
168 srcx
, srcy
, dstx
, dsty
, width
, height
);
172 /* Fill a rectangular sub-region. Need better logic about when to
173 * push buffers into AGP - will currently do so whenever possible.
176 get_pointer(struct pipe_region
*dst
, unsigned x
, unsigned y
)
178 return dst
->map
+ (y
* dst
->pitch
+ x
) * dst
->cpp
;
183 i915_region_fill(struct pipe_context
*pipe
,
184 struct pipe_region
*dst
,
186 unsigned dstx
, unsigned dsty
,
187 unsigned width
, unsigned height
, unsigned value
)
192 (void)pipe
->region_map(pipe
, dst
);
196 ubyte
*row
= get_pointer(dst
, dstx
, dsty
);
197 for (i
= 0; i
< height
; i
++) {
198 memset(row
, value
, width
);
204 ushort
*row
= (ushort
*) get_pointer(dst
, dstx
, dsty
);
205 for (i
= 0; i
< height
; i
++) {
206 for (j
= 0; j
< width
; j
++)
213 unsigned *row
= (unsigned *) get_pointer(dst
, dstx
, dsty
);
214 for (i
= 0; i
< height
; i
++) {
215 for (j
= 0; j
< width
; j
++)
227 i915_fill_blit( i915_context(pipe
),
230 dst
->buffer
, dst_offset
,
242 i915_init_region_functions(struct i915_context
*i915
)
244 i915
->pipe
.region_map
= i915_region_map
;
245 i915
->pipe
.region_unmap
= i915_region_unmap
;
246 i915
->pipe
.region_data
= i915_region_data
;
247 i915
->pipe
.region_copy
= i915_region_copy
;
248 i915
->pipe
.region_fill
= i915_region_fill
;