1 /**************************************************************************
3 * Copyright 2008 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 **************************************************************************/
30 * Copy/blit pixel rect between surfaces
36 #include "pipe/p_context.h"
37 #include "pipe/p_debug.h"
38 #include "pipe/p_defines.h"
39 #include "pipe/p_inlines.h"
40 #include "pipe/p_util.h"
41 #include "pipe/p_winsys.h"
42 #include "pipe/p_shader_tokens.h"
44 #include "util/u_draw_quad.h"
45 #include "util/u_blit.h"
46 #include "util/u_simple_shaders.h"
51 struct pipe_context
*pipe
;
56 void *samplers
[2]; /* one for linear, one for nearest sampling */
58 /*struct pipe_viewport_state viewport;*/
59 struct pipe_sampler_state
*vs
;
60 struct pipe_sampler_state
*fs
;
65 * Create state object for blit.
66 * Intended to be created once and re-used for many blit() calls.
69 util_create_blit(struct pipe_context
*pipe
)
71 struct pipe_blend_state blend
;
72 struct pipe_depth_stencil_alpha_state depthstencil
;
73 struct pipe_rasterizer_state rasterizer
;
74 struct blit_state
*ctx
;
75 struct pipe_sampler_state sampler
;
77 ctx
= CALLOC_STRUCT(blit_state
);
83 /* we don't use blending, but need to set valid values */
84 memset(&blend
, 0, sizeof(blend
));
85 blend
.rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
86 blend
.alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
87 blend
.rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
88 blend
.alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
89 blend
.colormask
= PIPE_MASK_RGBA
;
90 ctx
->blend
= pipe
->create_blend_state(pipe
, &blend
);
92 /* depth/stencil/alpha */
93 memset(&depthstencil
, 0, sizeof(depthstencil
));
94 ctx
->depthstencil
= pipe
->create_depth_stencil_alpha_state(pipe
, &depthstencil
);
97 memset(&rasterizer
, 0, sizeof(rasterizer
));
98 rasterizer
.front_winding
= PIPE_WINDING_CW
;
99 rasterizer
.cull_mode
= PIPE_WINDING_NONE
;
100 rasterizer
.bypass_clipping
= 1; /* bypasses viewport too */
101 /*rasterizer.bypass_vs = 1;*/
102 ctx
->rasterizer
= pipe
->create_rasterizer_state(pipe
, &rasterizer
);
105 memset(&sampler
, 0, sizeof(sampler
));
106 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
107 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
108 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
109 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
110 sampler
.min_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
111 sampler
.mag_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
112 sampler
.normalized_coords
= 1;
113 ctx
->samplers
[0] = pipe
->create_sampler_state(pipe
, &sampler
);
115 sampler
.min_img_filter
= PIPE_TEX_MIPFILTER_LINEAR
;
116 sampler
.mag_img_filter
= PIPE_TEX_MIPFILTER_LINEAR
;
117 ctx
->samplers
[1] = pipe
->create_sampler_state(pipe
, &sampler
);
122 ctx
->viewport
.scale
[0] = 1.0;
123 ctx
->viewport
.scale
[1] = 1.0;
124 ctx
->viewport
.scale
[2] = 1.0;
125 ctx
->viewport
.scale
[3] = 1.0;
126 ctx
->viewport
.translate
[0] = 0.0;
127 ctx
->viewport
.translate
[1] = 0.0;
128 ctx
->viewport
.translate
[2] = 0.0;
129 ctx
->viewport
.translate
[3] = 0.0;
134 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
135 TGSI_SEMANTIC_GENERIC
};
136 const uint semantic_indexes
[] = { 0, 0 };
137 ctx
->vs
= util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
141 /* fragment shader */
142 ctx
->fs
= util_make_fragment_tex_shader(pipe
);
149 * Destroy a blit context
152 util_destroy_blit(struct blit_state
*ctx
)
154 struct pipe_context
*pipe
= ctx
->pipe
;
156 pipe
->delete_blend_state(pipe
, ctx
->blend
);
157 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->depthstencil
);
158 pipe
->delete_rasterizer_state(pipe
, ctx
->rasterizer
);
159 pipe
->delete_sampler_state(pipe
, ctx
->samplers
[0]);
160 pipe
->delete_sampler_state(pipe
, ctx
->samplers
[1]);
162 pipe
->delete_vs_state(pipe
, ctx
->vs
);
163 pipe
->delete_fs_state(pipe
, ctx
->fs
);
170 * Copy pixel block from src surface to dst surface.
171 * Overlapping regions are acceptable.
172 * XXX need some control over blitting Z and/or stencil.
175 util_blit_pixels(struct blit_state
*ctx
,
176 struct pipe_surface
*src
,
177 int srcX0
, int srcY0
,
178 int srcX1
, int srcY1
,
179 struct pipe_surface
*dst
,
180 int dstX0
, int dstY0
,
181 int dstX1
, int dstY1
,
182 float z
, uint filter
)
184 struct pipe_context
*pipe
= ctx
->pipe
;
185 struct pipe_screen
*screen
= pipe
->screen
;
186 struct pipe_texture texTemp
, *tex
;
187 struct pipe_surface
*texSurf
;
188 struct pipe_framebuffer_state fb
;
189 const int srcW
= abs(srcX1
- srcX0
);
190 const int srcH
= abs(srcY1
- srcY0
);
191 const int srcLeft
= MIN2(srcX0
, srcX1
);
192 const int srcTop
= MIN2(srcY0
, srcY1
);
194 assert(filter
== PIPE_TEX_MIPFILTER_NEAREST
||
195 filter
== PIPE_TEX_MIPFILTER_LINEAR
);
197 if (srcLeft
!= srcX0
) {
198 /* left-right flip */
204 if (srcTop
!= srcY0
) {
212 * XXX for now we're always creating a temporary texture.
213 * Strictly speaking that's not always needed.
216 /* create temp texture */
217 memset(&texTemp
, 0, sizeof(texTemp
));
218 texTemp
.target
= PIPE_TEXTURE_2D
;
219 texTemp
.format
= src
->format
;
220 texTemp
.last_level
= 0;
221 texTemp
.width
[0] = srcW
;
222 texTemp
.height
[0] = srcH
;
223 texTemp
.depth
[0] = 1;
224 texTemp
.compressed
= 0;
225 texTemp
.cpp
= pf_get_bits(src
->format
) / 8;
227 tex
= screen
->texture_create(screen
, &texTemp
);
231 texSurf
= screen
->get_tex_surface(screen
, tex
, 0, 0, 0);
233 /* load temp texture */
234 pipe
->surface_copy(pipe
, FALSE
,
235 texSurf
, 0, 0, /* dest */
236 src
, srcLeft
, srcTop
, /* src */
237 srcW
, srcH
); /* size */
240 memset(&fb
, 0, sizeof(fb
));
243 pipe
->set_framebuffer_state(pipe
, &fb
);
246 if (filter
== PIPE_TEX_MIPFILTER_NEAREST
)
247 pipe
->bind_sampler_states(pipe
, 1, &ctx
->samplers
[0]);
249 pipe
->bind_sampler_states(pipe
, 1, &ctx
->samplers
[1]);
252 pipe
->set_sampler_textures(pipe
, 1, &tex
);
255 pipe
->bind_fs_state(pipe
, ctx
->fs
);
256 pipe
->bind_vs_state(pipe
, ctx
->vs
);
259 pipe
->bind_blend_state(pipe
, ctx
->blend
);
260 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->depthstencil
);
261 pipe
->bind_rasterizer_state(pipe
, ctx
->rasterizer
);
264 util_draw_texquad(pipe
, dstX0
, dstY0
, dstX1
, dstY1
, z
);
267 pipe
->set_sampler_textures(pipe
, 0, NULL
);
268 pipe
->bind_sampler_states(pipe
, 0, NULL
);
271 pipe_surface_reference(&texSurf
, NULL
);
272 screen
->texture_release(screen
, &tex
);
274 /* Note: caller must restore pipe/gallium state at this time */