~ubuntu-branches/ubuntu/precise/mesa-lts-quantal/precise-updates

« back to all changes in this revision

Viewing changes to src/gallium/drivers/i915/i915_surface.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2012-11-30 20:58:34 UTC
  • Revision ID: package-import@ubuntu.com-20121130205834-gazuvne3fpwlf012
Tags: upstream-9.0
ImportĀ upstreamĀ versionĀ 9.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "i915_surface.h"
 
29
#include "i915_resource.h"
 
30
#include "i915_state.h"
 
31
#include "i915_blit.h"
 
32
#include "i915_reg.h"
 
33
#include "i915_screen.h"
 
34
#include "pipe/p_defines.h"
 
35
#include "util/u_inlines.h"
 
36
#include "util/u_math.h"
 
37
#include "util/u_format.h"
 
38
#include "util/u_memory.h"
 
39
#include "util/u_pack_color.h"
 
40
#include "util/u_surface.h"
 
41
 
 
42
/*
 
43
 * surface functions using the render engine
 
44
 */
 
45
 
 
46
static void
 
47
i915_surface_copy_render(struct pipe_context *pipe,
 
48
                         struct pipe_resource *dst, unsigned dst_level,
 
49
                         unsigned dstx, unsigned dsty, unsigned dstz,
 
50
                         struct pipe_resource *src, unsigned src_level,
 
51
                         const struct pipe_box *src_box)
 
52
{
 
53
   struct i915_context *i915 = i915_context(pipe);
 
54
 
 
55
   /* Fallback for buffers. */
 
56
   if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
 
57
      util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
 
58
                                src, src_level, src_box);
 
59
      return;
 
60
   }
 
61
 
 
62
   if (!util_blitter_is_copy_supported(i915->blitter, dst, src,
 
63
                                       PIPE_MASK_RGBAZS)) {
 
64
      util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
 
65
                                src, src_level, src_box);
 
66
      return;
 
67
   }
 
68
 
 
69
   util_blitter_save_blend(i915->blitter, (void *)i915->blend);
 
70
   util_blitter_save_depth_stencil_alpha(i915->blitter, (void *)i915->depth_stencil);
 
71
   util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref);
 
72
   util_blitter_save_rasterizer(i915->blitter, (void *)i915->rasterizer);
 
73
   util_blitter_save_fragment_shader(i915->blitter, i915->saved_fs);
 
74
   util_blitter_save_vertex_shader(i915->blitter, i915->saved_vs);
 
75
   util_blitter_save_viewport(i915->blitter, &i915->viewport);
 
76
   util_blitter_save_vertex_elements(i915->blitter, i915->saved_velems);
 
77
   util_blitter_save_vertex_buffers(i915->blitter, i915->saved_nr_vertex_buffers,
 
78
                                    i915->saved_vertex_buffers);
 
79
 
 
80
   util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
 
81
 
 
82
   util_blitter_save_fragment_sampler_states(i915->blitter,
 
83
                                             i915->saved_nr_samplers,
 
84
                                             i915->saved_samplers);
 
85
   util_blitter_save_fragment_sampler_views(i915->blitter,
 
86
                                            i915->saved_nr_sampler_views,
 
87
                                            i915->saved_sampler_views);
 
88
 
 
89
   util_blitter_copy_texture(i915->blitter, dst, dst_level, ~0, dstx, dsty, dstz,
 
90
                            src, src_level, 0, src_box);
 
91
}
 
92
 
 
93
static void
 
94
i915_clear_render_target_render(struct pipe_context *pipe,
 
95
                                struct pipe_surface *dst,
 
96
                                const union pipe_color_union *color,
 
97
                                unsigned dstx, unsigned dsty,
 
98
                                unsigned width, unsigned height)
 
99
{
 
100
   struct i915_context *i915 = i915_context(pipe);
 
101
   struct pipe_framebuffer_state fb_state;
 
102
 
 
103
   util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
 
104
 
 
105
   fb_state.width = dst->width;
 
106
   fb_state.height = dst->height;
 
107
   fb_state.nr_cbufs = 1;
 
108
   fb_state.cbufs[0] = dst;
 
109
   fb_state.zsbuf = NULL;
 
110
   pipe->set_framebuffer_state(pipe, &fb_state);
 
111
 
 
112
   if (i915->dirty)
 
113
      i915_update_derived(i915);
 
114
 
 
115
   i915_clear_emit(pipe, PIPE_CLEAR_COLOR, color, 0.0, 0x0,
 
116
                   dstx, dsty, width, height);
 
117
 
 
118
   pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state);
 
119
   util_unreference_framebuffer_state(&i915->blitter->saved_fb_state);
 
120
   i915->blitter->saved_fb_state.nr_cbufs = ~0;
 
121
}
 
122
 
 
123
static void
 
124
i915_clear_depth_stencil_render(struct pipe_context *pipe,
 
125
                                struct pipe_surface *dst,
 
126
                                unsigned clear_flags,
 
127
                                double depth,
 
128
                                unsigned stencil,
 
129
                                unsigned dstx, unsigned dsty,
 
130
                                unsigned width, unsigned height)
 
131
{
 
132
   struct i915_context *i915 = i915_context(pipe);
 
133
   struct pipe_framebuffer_state fb_state;
 
134
 
 
135
   util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
 
136
 
 
137
   fb_state.width = dst->width;
 
138
   fb_state.height = dst->height;
 
139
   fb_state.nr_cbufs = 0;
 
140
   fb_state.zsbuf = dst;
 
141
   pipe->set_framebuffer_state(pipe, &fb_state);
 
142
 
 
143
   if (i915->dirty)
 
144
      i915_update_derived(i915);
 
145
 
 
146
   i915_clear_emit(pipe, clear_flags & PIPE_CLEAR_DEPTHSTENCIL,
 
147
                   NULL, depth, stencil,
 
148
                   dstx, dsty, width, height);
 
149
 
 
150
   pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state);
 
151
   util_unreference_framebuffer_state(&i915->blitter->saved_fb_state);
 
152
   i915->blitter->saved_fb_state.nr_cbufs = ~0;
 
153
}
 
154
 
 
155
/*
 
156
 * surface functions using the blitter
 
157
 */
 
158
 
 
159
/* Assumes all values are within bounds -- no checking at this level -
 
160
 * do it higher up if required.
 
161
 */
 
162
static void
 
163
i915_surface_copy_blitter(struct pipe_context *pipe,
 
164
                          struct pipe_resource *dst, unsigned dst_level,
 
165
                          unsigned dstx, unsigned dsty, unsigned dstz,
 
166
                          struct pipe_resource *src, unsigned src_level,
 
167
                          const struct pipe_box *src_box)
 
168
{
 
169
   struct i915_texture *dst_tex = i915_texture(dst);
 
170
   struct i915_texture *src_tex = i915_texture(src);
 
171
   struct pipe_resource *dpt = &dst_tex->b.b;
 
172
   struct pipe_resource *spt = &src_tex->b.b;
 
173
   unsigned dst_offset, src_offset;  /* in bytes */
 
174
 
 
175
   /* Fallback for buffers. */
 
176
   if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
 
177
      util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
 
178
                                src, src_level, src_box);
 
179
      return;
 
180
   }
 
181
 
 
182
   /* XXX cannot copy 3d regions at this time */
 
183
   assert(src_box->depth == 1);
 
184
   if (dst->target != PIPE_TEXTURE_CUBE &&
 
185
       dst->target != PIPE_TEXTURE_3D)
 
186
      assert(dstz == 0);
 
187
   dst_offset = i915_texture_offset(dst_tex, dst_level, dstz);
 
188
 
 
189
   if (src->target != PIPE_TEXTURE_CUBE &&
 
190
       src->target != PIPE_TEXTURE_3D)
 
191
      assert(src_box->z == 0);
 
192
   src_offset = i915_texture_offset(src_tex, src_level, src_box->z);
 
193
 
 
194
   assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) );
 
195
   assert( util_format_get_blockwidth(dpt->format) == util_format_get_blockwidth(spt->format) );
 
196
   assert( util_format_get_blockheight(dpt->format) == util_format_get_blockheight(spt->format) );
 
197
   assert( util_format_get_blockwidth(dpt->format) == 1 );
 
198
   assert( util_format_get_blockheight(dpt->format) == 1 );
 
199
 
 
200
   i915_copy_blit( i915_context(pipe),
 
201
                   util_format_get_blocksize(dpt->format),
 
202
                   (unsigned short) src_tex->stride, src_tex->buffer, src_offset,
 
203
                   (unsigned short) dst_tex->stride, dst_tex->buffer, dst_offset,
 
204
                   (short) src_box->x, (short) src_box->y, (short) dstx, (short) dsty,
 
205
                   (short) src_box->width, (short) src_box->height );
 
206
}
 
207
 
 
208
static void
 
209
i915_clear_render_target_blitter(struct pipe_context *pipe,
 
210
                                 struct pipe_surface *dst,
 
211
                                 const union pipe_color_union *color,
 
212
                                 unsigned dstx, unsigned dsty,
 
213
                                 unsigned width, unsigned height)
 
214
{
 
215
   struct i915_texture *tex = i915_texture(dst->texture);
 
216
   struct pipe_resource *pt = &tex->b.b;
 
217
   union util_color uc;
 
218
   unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer);
 
219
 
 
220
   assert(util_format_get_blockwidth(pt->format) == 1);
 
221
   assert(util_format_get_blockheight(pt->format) == 1);
 
222
 
 
223
   util_pack_color(color->f, dst->format, &uc);
 
224
   i915_fill_blit( i915_context(pipe),
 
225
                   util_format_get_blocksize(pt->format),
 
226
                   XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB,
 
227
                   (unsigned short) tex->stride,
 
228
                   tex->buffer, offset,
 
229
                   (short) dstx, (short) dsty,
 
230
                   (short) width, (short) height,
 
231
                   uc.ui );
 
232
}
 
233
 
 
234
static void
 
235
i915_clear_depth_stencil_blitter(struct pipe_context *pipe,
 
236
                                 struct pipe_surface *dst,
 
237
                                 unsigned clear_flags,
 
238
                                 double depth,
 
239
                                 unsigned stencil,
 
240
                                 unsigned dstx, unsigned dsty,
 
241
                                 unsigned width, unsigned height)
 
242
{
 
243
   struct i915_texture *tex = i915_texture(dst->texture);
 
244
   struct pipe_resource *pt = &tex->b.b;
 
245
   unsigned packedds;
 
246
   unsigned mask = 0;
 
247
   unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer);
 
248
 
 
249
   assert(util_format_get_blockwidth(pt->format) == 1);
 
250
   assert(util_format_get_blockheight(pt->format) == 1);
 
251
 
 
252
   packedds = util_pack_z_stencil(dst->format, depth, stencil);
 
253
 
 
254
   if (clear_flags & PIPE_CLEAR_DEPTH)
 
255
      mask |= XY_COLOR_BLT_WRITE_RGB;
 
256
   /* XXX presumably this does read-modify-write
 
257
      (otherwise this won't work anyway). Hence will only want to
 
258
      do it if really have stencil and it isn't cleared */
 
259
   if ((clear_flags & PIPE_CLEAR_STENCIL) ||
 
260
       (dst->format != PIPE_FORMAT_Z24_UNORM_S8_UINT))
 
261
      mask |= XY_COLOR_BLT_WRITE_ALPHA;
 
262
 
 
263
   i915_fill_blit( i915_context(pipe),
 
264
                   util_format_get_blocksize(pt->format),
 
265
                   mask,
 
266
                   (unsigned short) tex->stride,
 
267
                   tex->buffer, offset,
 
268
                   (short) dstx, (short) dsty,
 
269
                   (short) width, (short) height,
 
270
                   packedds );
 
271
}
 
272
 
 
273
/*
 
274
 * Screen surface functions
 
275
 */
 
276
 
 
277
 
 
278
static struct pipe_surface *
 
279
i915_create_surface(struct pipe_context *ctx,
 
280
                    struct pipe_resource *pt,
 
281
                    const struct pipe_surface *surf_tmpl)
 
282
{
 
283
   struct pipe_surface *ps;
 
284
 
 
285
   assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
 
286
   if (pt->target != PIPE_TEXTURE_CUBE &&
 
287
       pt->target != PIPE_TEXTURE_3D)
 
288
      assert(surf_tmpl->u.tex.first_layer == 0);
 
289
 
 
290
   ps = CALLOC_STRUCT(pipe_surface);
 
291
   if (ps) {
 
292
      /* could subclass pipe_surface and store offset as it used to do */
 
293
      pipe_reference_init(&ps->reference, 1);
 
294
      pipe_resource_reference(&ps->texture, pt);
 
295
      ps->format = surf_tmpl->format;
 
296
      ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
 
297
      ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
 
298
      ps->u.tex.level = surf_tmpl->u.tex.level;
 
299
      ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
 
300
      ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
 
301
      ps->usage = surf_tmpl->usage;
 
302
      ps->context = ctx;
 
303
   }
 
304
   return ps;
 
305
}
 
306
 
 
307
static void
 
308
i915_surface_destroy(struct pipe_context *ctx,
 
309
                     struct pipe_surface *surf)
 
310
{
 
311
   pipe_resource_reference(&surf->texture, NULL);
 
312
   FREE(surf);
 
313
}
 
314
 
 
315
 
 
316
void
 
317
i915_init_surface_functions(struct i915_context *i915)
 
318
{
 
319
   if (i915_screen(i915->base.screen)->debug.use_blitter) {
 
320
      i915->base.resource_copy_region = i915_surface_copy_blitter;
 
321
      i915->base.clear_render_target = i915_clear_render_target_blitter;
 
322
      i915->base.clear_depth_stencil = i915_clear_depth_stencil_blitter;
 
323
   } else {
 
324
      i915->base.resource_copy_region = i915_surface_copy_render;
 
325
      i915->base.clear_render_target = i915_clear_render_target_render;
 
326
      i915->base.clear_depth_stencil = i915_clear_depth_stencil_render;
 
327
   }
 
328
   i915->base.create_surface = i915_create_surface;
 
329
   i915->base.surface_destroy = i915_surface_destroy;
 
330
}