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_context.h"
29 #include "i915_state.h"
30 #include "i915_screen.h"
31 #include "i915_surface.h"
32 #include "i915_query.h"
33 #include "i915_batch.h"
34 #include "i915_resource.h"
35 
36 #include "draw/draw_context.h"
37 #include "pipe/p_defines.h"
38 #include "util/u_inlines.h"
39 #include "util/u_memory.h"
40 #include "pipe/p_screen.h"
41 
42 
43 DEBUG_GET_ONCE_BOOL_OPTION(i915_no_vbuf, "I915_NO_VBUF", FALSE)
44 
45 
46 /*
47  * Draw functions
48  */
49 
50 
51 static void
i915_draw_vbo(struct pipe_context * pipe,const struct pipe_draw_info * info)52 i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
53 {
54    struct i915_context *i915 = i915_context(pipe);
55    struct draw_context *draw = i915->draw;
56    const void *mapped_indices = NULL;
57 
58 
59    /*
60     * Ack vs contants here, helps ipers a lot.
61     */
62    i915->dirty &= ~I915_NEW_VS_CONSTANTS;
63 
64    if (i915->dirty)
65       i915_update_derived(i915);
66 
67    /*
68     * Map index buffer, if present
69     */
70    if (info->indexed) {
71       mapped_indices = i915->index_buffer.user_buffer;
72       if (!mapped_indices)
73          mapped_indices = i915_buffer(i915->index_buffer.buffer)->data;
74       draw_set_indexes(draw,
75                        (ubyte *) mapped_indices + i915->index_buffer.offset,
76                        i915->index_buffer.index_size);
77    }
78 
79    if (i915->constants[PIPE_SHADER_VERTEX])
80       draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
81                                       i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data,
82                                       (i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
83                                       4 * sizeof(float)));
84    else
85       draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0);
86 
87    if (i915->num_vertex_sampler_views > 0)
88       i915_prepare_vertex_sampling(i915);
89 
90    /*
91     * Do the drawing
92     */
93    draw_vbo(i915->draw, info);
94 
95    if (mapped_indices)
96       draw_set_indexes(draw, NULL, 0);
97 
98    if (i915->num_vertex_sampler_views > 0)
99       i915_cleanup_vertex_sampling(i915);
100 
101    /*
102     * Instead of flushing on every state change, we flush once here
103     * when we fire the vbo.
104     */
105    draw_flush(i915->draw);
106 }
107 
108 
109 /*
110  * Generic context functions
111  */
112 
113 
i915_destroy(struct pipe_context * pipe)114 static void i915_destroy(struct pipe_context *pipe)
115 {
116    struct i915_context *i915 = i915_context(pipe);
117    int i;
118 
119    if (i915->blitter)
120       util_blitter_destroy(i915->blitter);
121 
122    draw_destroy(i915->draw);
123 
124    if(i915->batch)
125       i915->iws->batchbuffer_destroy(i915->batch);
126 
127    /* unbind framebuffer */
128    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
129       pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL);
130    }
131    pipe_surface_reference(&i915->framebuffer.zsbuf, NULL);
132 
133    /* unbind constant buffers */
134    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
135       pipe_resource_reference(&i915->constants[i], NULL);
136    }
137 
138    FREE(i915);
139 }
140 
141 struct pipe_context *
i915_create_context(struct pipe_screen * screen,void * priv)142 i915_create_context(struct pipe_screen *screen, void *priv)
143 {
144    struct i915_context *i915;
145 
146    i915 = CALLOC_STRUCT(i915_context);
147    if (i915 == NULL)
148       return NULL;
149 
150    i915->iws = i915_screen(screen)->iws;
151    i915->base.screen = screen;
152    i915->base.priv = priv;
153 
154    i915->base.destroy = i915_destroy;
155 
156    if (i915_screen(screen)->debug.use_blitter)
157       i915->base.clear = i915_clear_blitter;
158    else
159       i915->base.clear = i915_clear_render;
160 
161    i915->base.draw_vbo = i915_draw_vbo;
162 
163    /* init this before draw */
164    util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer),
165                     16, UTIL_SLAB_SINGLETHREADED);
166    util_slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer),
167                     16, UTIL_SLAB_SINGLETHREADED);
168 
169    /* Batch stream debugging is a bit hacked up at the moment:
170     */
171    i915->batch = i915->iws->batchbuffer_create(i915->iws);
172 
173    /*
174     * Create drawing context and plug our rendering stage into it.
175     */
176    i915->draw = draw_create(&i915->base);
177    assert(i915->draw);
178    if (!debug_get_option_i915_no_vbuf()) {
179       draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
180    } else {
181       draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915));
182    }
183 
184    i915_init_surface_functions(i915);
185    i915_init_state_functions(i915);
186    i915_init_flush_functions(i915);
187    i915_init_resource_functions(i915);
188    i915_init_query_functions(i915);
189 
190    draw_install_aaline_stage(i915->draw, &i915->base);
191    draw_install_aapoint_stage(i915->draw, &i915->base);
192    draw_enable_point_sprites(i915->draw, TRUE);
193 
194    /* augmented draw pipeline clobbers state functions */
195    i915_init_fixup_state_functions(i915);
196 
197    /* Create blitter last - calls state creation functions. */
198    i915->blitter = util_blitter_create(&i915->base);
199    assert(i915->blitter);
200 
201    i915->dirty = ~0;
202    i915->hardware_dirty = ~0;
203    i915->immediate_dirty = ~0;
204    i915->dynamic_dirty = ~0;
205    i915->static_dirty = ~0;
206    i915->flush_dirty = 0;
207 
208    return &i915->base;
209 }
210