Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / i965 / brw_wm_surface_state.c
1 /*
2  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4  develop this 3D driver.
5  
6  Permission is hereby granted, free of charge, to any person obtaining
7  a 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, sublicense, 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
16  portions of the Software.
17  
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  
26  **********************************************************************/
27  /*
28   * Authors:
29   *   Keith Whitwell <keith@tungstengraphics.com>
30   */
31                    
32 #include "pipe/p_format.h"
33
34 #include "brw_batchbuffer.h"
35 #include "brw_context.h"
36 #include "brw_state.h"
37 #include "brw_resource.h"
38
39
40
41
42 static enum pipe_error
43 brw_update_texture_surface( struct brw_context *brw,
44                             struct brw_texture *tex,
45                             struct brw_winsys_buffer **bo_out)
46 {
47    struct brw_winsys_reloc reloc[1];
48    enum pipe_error ret;
49
50    /* Emit relocation to surface contents */
51    make_reloc(&reloc[0],
52               BRW_USAGE_SAMPLER,
53               0,
54               offsetof(struct brw_surface_state, ss1),
55               tex->bo);
56
57    if (brw_search_cache(&brw->surface_cache,
58                         BRW_SS_SURFACE,
59                         &tex->ss, sizeof tex->ss,
60                         reloc, Elements(reloc),
61                         NULL,
62                         bo_out))
63       return PIPE_OK;
64
65    ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
66                           &tex->ss, sizeof tex->ss,
67                           reloc, Elements(reloc),
68                           &tex->ss, sizeof tex->ss,
69                           NULL, NULL,
70                           bo_out);
71    if (ret)
72       return ret;
73
74    return PIPE_OK;
75 }
76
77
78
79
80
81
82
83
84 /**
85  * Sets up a surface state structure to point at the given region.
86  * While it is only used for the front/back buffer currently, it should be
87  * usable for further buffers when doing ARB_draw_buffer support.
88  */
89 static enum pipe_error
90 brw_update_render_surface(struct brw_context *brw,
91                           struct brw_surface *surface,
92                           struct brw_winsys_buffer **bo_out)
93 {
94    struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0;
95    struct brw_surface_state ss;
96    struct brw_winsys_reloc reloc[1];
97    enum pipe_error ret;
98
99    /* XXX: we will only be rendering to this surface:
100     */
101    make_reloc(&reloc[0],
102               BRW_USAGE_RENDER_TARGET,
103               0,
104               offsetof(struct brw_surface_state, ss1),
105               surface->bo);
106
107    /* Surfaces are potentially shared between contexts, so can't
108     * scribble the in-place ss0 value in the surface.
109     */
110    memcpy(&ss, &surface->ss, sizeof ss);
111
112    ss.ss0.color_blend        = blend_ss0.color_blend;
113    ss.ss0.writedisable_blue  = blend_ss0.writedisable_blue;
114    ss.ss0.writedisable_green = blend_ss0.writedisable_green;
115    ss.ss0.writedisable_red   = blend_ss0.writedisable_red;
116    ss.ss0.writedisable_alpha = blend_ss0.writedisable_alpha;
117
118    if (brw_search_cache(&brw->surface_cache,
119                         BRW_SS_SURFACE,
120                         &ss, sizeof(ss),
121                         reloc, Elements(reloc),
122                         NULL,
123                         bo_out))
124       return PIPE_OK;
125        
126    ret = brw_upload_cache(&brw->surface_cache,
127                           BRW_SS_SURFACE,
128                           &ss, sizeof ss,
129                           reloc, Elements(reloc),
130                           &ss, sizeof ss,
131                           NULL, NULL,
132                           bo_out);
133    if (ret)
134       return ret;
135
136    return PIPE_OK;
137 }
138
139
140 /**
141  * Constructs the binding table for the WM surface state, which maps unit
142  * numbers to surface state objects.
143  */
144 static enum pipe_error
145 brw_wm_get_binding_table(struct brw_context *brw,
146                          struct brw_winsys_buffer **bo_out )
147 {
148    enum pipe_error ret;
149    struct brw_winsys_reloc reloc[BRW_WM_MAX_SURF];
150    uint32_t data[BRW_WM_MAX_SURF];
151    GLuint nr_relocs = 0;
152    GLuint data_size = brw->wm.nr_surfaces * sizeof data[0];
153    int i;
154
155    assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
156    assert(brw->wm.nr_surfaces > 0);
157
158    /* Emit binding table relocations to surface state 
159     */
160    for (i = 0; i < brw->wm.nr_surfaces; i++) {
161       if (brw->wm.surf_bo[i]) {
162          make_reloc(&reloc[nr_relocs++],
163                     BRW_USAGE_STATE,
164                     0,
165                     i * sizeof(GLuint),
166                     brw->wm.surf_bo[i]);
167       }
168    }
169
170    /* Note there is no key for this search beyond the values in the
171     * relocation array:
172     */
173    if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
174                         NULL, 0,
175                         reloc, nr_relocs,
176                         NULL,
177                         bo_out))
178       return PIPE_OK;
179
180    /* Upload zero data, will all be overwitten with relocation
181     * offsets:
182     */
183    for (i = 0; i < brw->wm.nr_surfaces; i++)
184       data[i] = 0;
185
186    ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
187                            NULL, 0,
188                            reloc, nr_relocs,
189                            data, data_size,
190                            NULL, NULL,
191                            bo_out);
192    if (ret)
193       return ret;
194
195    return PIPE_OK;
196 }
197
198 static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )
199 {
200    enum pipe_error ret;
201    int nr_surfaces = 0;
202    GLuint i;
203
204    /* PIPE_NEW_COLOR_BUFFERS | PIPE_NEW_BLEND
205     *
206     * Update surfaces for drawing buffers.  Mixes in colormask and
207     * blend state.
208     *
209     * XXX: no color buffer case
210     */
211    for (i = 0; i < brw->curr.fb.nr_cbufs; i++) {
212       ret = brw_update_render_surface(brw, 
213                                       brw_surface(brw->curr.fb.cbufs[i]), 
214                                       &brw->wm.surf_bo[BTI_COLOR_BUF(i)]);
215       if (ret)
216          return ret;
217       
218       nr_surfaces = BTI_COLOR_BUF(i) + 1;
219    }
220
221
222
223    /* PIPE_NEW_FRAGMENT_CONSTANTS
224     */
225 #if 0
226    if (brw->curr.fragment_constants) {
227       ret = brw_update_fragment_constant_surface(
228          brw, 
229          brw->curr.fragment_constants, 
230          &brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS]);
231
232       if (ret)
233          return ret;
234
235       nr_surfaces = BTI_FRAGMENT_CONSTANTS + 1;
236    }
237    else {
238       bo_reference(&brw->wm.surf_bo[SURF_FRAG_CONSTANTS], NULL);      
239    }
240 #endif
241
242
243    /* PIPE_NEW_TEXTURE 
244     */
245    for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) {
246       ret = brw_update_texture_surface(brw, 
247                                        brw_texture(brw->curr.fragment_sampler_views[i]->texture),
248                                        &brw->wm.surf_bo[BTI_TEXTURE(i)]);
249       if (ret)
250          return ret;
251
252       nr_surfaces = BTI_TEXTURE(i) + 1;
253    }
254
255    /* Clear any inactive entries:
256     */
257    for (i = brw->curr.fb.nr_cbufs; i < BRW_MAX_DRAW_BUFFERS; i++) 
258       bo_reference(&brw->wm.surf_bo[BTI_COLOR_BUF(i)], NULL);
259
260    if (!brw->curr.fragment_constants)
261       bo_reference(&brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS], NULL);      
262
263    /* XXX: no pipe_max_textures define?? */
264    for (i = brw->curr.num_fragment_sampler_views; i < PIPE_MAX_SAMPLERS; i++)
265       bo_reference(&brw->wm.surf_bo[BTI_TEXTURE(i)], NULL);
266
267    if (brw->wm.nr_surfaces != nr_surfaces) {
268       brw->wm.nr_surfaces = nr_surfaces;
269       brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
270    }
271
272    ret = brw_wm_get_binding_table(brw, &brw->wm.bind_bo);
273    if (ret)
274       return ret;
275
276    return PIPE_OK;
277 }
278
279 const struct brw_tracked_state brw_wm_surfaces = {
280    .dirty = {
281       .mesa = (PIPE_NEW_COLOR_BUFFERS |
282                PIPE_NEW_BOUND_TEXTURES |
283                PIPE_NEW_FRAGMENT_CONSTANTS |
284                PIPE_NEW_BLEND),
285       .brw = (BRW_NEW_CONTEXT |
286               BRW_NEW_WM_SURFACES),
287       .cache = 0
288    },
289    .prepare = prepare_wm_surfaces,
290 };
291
292
293