OSDN Git Service

llvmpipe: added debug option to disable LLVM optimization passes
[android-x86/external-mesa.git] / src / gallium / auxiliary / util / u_surface.c
1 /**************************************************************************
2  *
3  * Copyright 2009 VMware, Inc.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 /**
28  * @file
29  * Surface utility functions.
30  *  
31  * @author Brian Paul
32  */
33
34
35 #include "pipe/p_screen.h"
36 #include "pipe/p_state.h"
37 #include "pipe/p_defines.h"
38
39 #include "util/u_memory.h"
40 #include "util/u_format.h"
41 #include "util/u_surface.h"
42
43
44 /**
45  * Helper to quickly create an RGBA rendering surface of a certain size.
46  * \param textureOut  returns the new texture
47  * \param surfaceOut  returns the new surface
48  * \return TRUE for success, FALSE if failure
49  */
50 boolean
51 util_create_rgba_surface(struct pipe_screen *screen,
52                          uint width, uint height,
53                          struct pipe_texture **textureOut,
54                          struct pipe_surface **surfaceOut)
55 {
56    static const enum pipe_format rgbaFormats[] = {
57       PIPE_FORMAT_A8R8G8B8_UNORM,
58       PIPE_FORMAT_B8G8R8A8_UNORM,
59       PIPE_FORMAT_R8G8B8A8_UNORM,
60       PIPE_FORMAT_NONE
61    };
62    const uint target = PIPE_TEXTURE_2D;
63    const uint usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
64    enum pipe_format format = PIPE_FORMAT_NONE;
65    struct pipe_texture templ;
66    uint i;
67
68    /* Choose surface format */
69    for (i = 0; rgbaFormats[i]; i++) {
70       if (screen->is_format_supported(screen, rgbaFormats[i],
71                                       target, usage, 0)) {
72          format = rgbaFormats[i];
73          break;
74       }
75    }
76    if (format == PIPE_FORMAT_NONE)
77       return FALSE;  /* unable to get an rgba format!?! */
78
79    /* create texture */
80    memset(&templ, 0, sizeof(templ));
81    templ.target = target;
82    templ.format = format;
83    templ.last_level = 0;
84    templ.width0 = width;
85    templ.height0 = height;
86    templ.depth0 = 1;
87    templ.tex_usage = usage;
88
89    *textureOut = screen->texture_create(screen, &templ);
90    if (!*textureOut)
91       return FALSE;
92
93    /* create surface / view into texture */
94    *surfaceOut = screen->get_tex_surface(screen, *textureOut, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
95    if (!*surfaceOut) {
96       pipe_texture_reference(textureOut, NULL);
97       return FALSE;
98    }
99
100    return TRUE;
101 }
102
103
104 /**
105  * Release the surface and texture from util_create_rgba_surface().
106  */
107 void
108 util_destroy_rgba_surface(struct pipe_texture *texture,
109                           struct pipe_surface *surface)
110 {
111    pipe_surface_reference(&surface, NULL);
112    pipe_texture_reference(&texture, NULL);
113 }
114
115
116
117 /**
118  * Compare pipe_framebuffer_state objects.
119  * \return TRUE if same, FALSE if different
120  */
121 boolean
122 util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst,
123                              const struct pipe_framebuffer_state *src)
124 {
125    unsigned i;
126
127    if (dst->width != src->width ||
128        dst->height != src->height)
129       return FALSE;
130
131    for (i = 0; i < Elements(src->cbufs); i++) {
132       if (dst->cbufs[i] != src->cbufs[i]) {
133          return FALSE;
134       }
135    }
136
137    if (dst->nr_cbufs != src->nr_cbufs) {
138       return FALSE;
139    }
140
141    if (dst->zsbuf != src->zsbuf) {
142       return FALSE;
143    }
144
145    return TRUE;
146 }
147
148
149 /**
150  * Copy framebuffer state from src to dst, updating refcounts.
151  */
152 void
153 util_copy_framebuffer_state(struct pipe_framebuffer_state *dst,
154                             const struct pipe_framebuffer_state *src)
155 {
156    unsigned i;
157
158    dst->width = src->width;
159    dst->height = src->height;
160
161    for (i = 0; i < Elements(src->cbufs); i++) {
162       pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
163    }
164
165    dst->nr_cbufs = src->nr_cbufs;
166
167    pipe_surface_reference(&dst->zsbuf, src->zsbuf);
168 }
169
170
171 void
172 util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb)
173 {
174    unsigned i;
175
176    for (i = 0; i < fb->nr_cbufs; i++) {
177       pipe_surface_reference(&fb->cbufs[i], NULL);
178    }
179
180    pipe_surface_reference(&fb->zsbuf, NULL);
181
182    fb->width = fb->height = 0;
183    fb->nr_cbufs = 0;
184 }