1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2003 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "i915_context.h" 29bf215546Sopenharmony_ci#include "i915_batch.h" 30bf215546Sopenharmony_ci#include "i915_debug.h" 31bf215546Sopenharmony_ci#include "i915_query.h" 32bf215546Sopenharmony_ci#include "i915_resource.h" 33bf215546Sopenharmony_ci#include "i915_screen.h" 34bf215546Sopenharmony_ci#include "i915_state.h" 35bf215546Sopenharmony_ci#include "i915_surface.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "draw/draw_context.h" 38bf215546Sopenharmony_ci#include "pipe/p_defines.h" 39bf215546Sopenharmony_ci#include "pipe/p_screen.h" 40bf215546Sopenharmony_ci#include "util/u_draw.h" 41bf215546Sopenharmony_ci#include "util/u_inlines.h" 42bf215546Sopenharmony_ci#include "util/u_memory.h" 43bf215546Sopenharmony_ci#include "util/u_prim.h" 44bf215546Sopenharmony_ci#include "util/u_upload_mgr.h" 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci/* 47bf215546Sopenharmony_ci * Draw functions 48bf215546Sopenharmony_ci */ 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cistatic void 51bf215546Sopenharmony_cii915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, 52bf215546Sopenharmony_ci unsigned drawid_offset, 53bf215546Sopenharmony_ci const struct pipe_draw_indirect_info *indirect, 54bf215546Sopenharmony_ci const struct pipe_draw_start_count_bias *draws, 55bf215546Sopenharmony_ci unsigned num_draws) 56bf215546Sopenharmony_ci{ 57bf215546Sopenharmony_ci if (num_draws > 1) { 58bf215546Sopenharmony_ci util_draw_multi(pipe, info, drawid_offset, indirect, draws, num_draws); 59bf215546Sopenharmony_ci return; 60bf215546Sopenharmony_ci } 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci struct i915_context *i915 = i915_context(pipe); 63bf215546Sopenharmony_ci struct draw_context *draw = i915->draw; 64bf215546Sopenharmony_ci const void *mapped_indices = NULL; 65bf215546Sopenharmony_ci unsigned i; 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci if (!u_trim_pipe_prim(info->mode, (unsigned *)&draws[0].count)) 68bf215546Sopenharmony_ci return; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci /* 71bf215546Sopenharmony_ci * Ack vs contants here, helps ipers a lot. 72bf215546Sopenharmony_ci */ 73bf215546Sopenharmony_ci i915->dirty &= ~I915_NEW_VS_CONSTANTS; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci if (i915->dirty) 76bf215546Sopenharmony_ci i915_update_derived(i915); 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci /* 79bf215546Sopenharmony_ci * Map vertex buffers 80bf215546Sopenharmony_ci */ 81bf215546Sopenharmony_ci for (i = 0; i < i915->nr_vertex_buffers; i++) { 82bf215546Sopenharmony_ci const void *buf = i915->vertex_buffers[i].is_user_buffer 83bf215546Sopenharmony_ci ? i915->vertex_buffers[i].buffer.user 84bf215546Sopenharmony_ci : NULL; 85bf215546Sopenharmony_ci if (!buf) { 86bf215546Sopenharmony_ci if (!i915->vertex_buffers[i].buffer.resource) 87bf215546Sopenharmony_ci continue; 88bf215546Sopenharmony_ci buf = i915_buffer(i915->vertex_buffers[i].buffer.resource)->data; 89bf215546Sopenharmony_ci } 90bf215546Sopenharmony_ci draw_set_mapped_vertex_buffer(draw, i, buf, ~0); 91bf215546Sopenharmony_ci } 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci /* 94bf215546Sopenharmony_ci * Map index buffer, if present 95bf215546Sopenharmony_ci */ 96bf215546Sopenharmony_ci if (info->index_size) { 97bf215546Sopenharmony_ci mapped_indices = info->has_user_indices ? info->index.user : NULL; 98bf215546Sopenharmony_ci if (!mapped_indices) 99bf215546Sopenharmony_ci mapped_indices = i915_buffer(info->index.resource)->data; 100bf215546Sopenharmony_ci draw_set_indexes(draw, (ubyte *)mapped_indices, info->index_size, ~0); 101bf215546Sopenharmony_ci } 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci if (i915->constants[PIPE_SHADER_VERTEX]) 104bf215546Sopenharmony_ci draw_set_mapped_constant_buffer( 105bf215546Sopenharmony_ci draw, PIPE_SHADER_VERTEX, 0, 106bf215546Sopenharmony_ci i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data, 107bf215546Sopenharmony_ci (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * 4 * 108bf215546Sopenharmony_ci sizeof(float))); 109bf215546Sopenharmony_ci else 110bf215546Sopenharmony_ci draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0); 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci /* 113bf215546Sopenharmony_ci * Do the drawing 114bf215546Sopenharmony_ci */ 115bf215546Sopenharmony_ci draw_vbo(i915->draw, info, drawid_offset, NULL, draws, num_draws, 0); 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci /* 118bf215546Sopenharmony_ci * unmap vertex/index buffers 119bf215546Sopenharmony_ci */ 120bf215546Sopenharmony_ci for (i = 0; i < i915->nr_vertex_buffers; i++) { 121bf215546Sopenharmony_ci draw_set_mapped_vertex_buffer(i915->draw, i, NULL, 0); 122bf215546Sopenharmony_ci } 123bf215546Sopenharmony_ci if (mapped_indices) 124bf215546Sopenharmony_ci draw_set_indexes(draw, NULL, 0, 0); 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci /* 127bf215546Sopenharmony_ci * Instead of flushing on every state change, we flush once here 128bf215546Sopenharmony_ci * when we fire the vbo. 129bf215546Sopenharmony_ci */ 130bf215546Sopenharmony_ci draw_flush(i915->draw); 131bf215546Sopenharmony_ci} 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci/* 134bf215546Sopenharmony_ci * Generic context functions 135bf215546Sopenharmony_ci */ 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_cistatic void 138bf215546Sopenharmony_cii915_destroy(struct pipe_context *pipe) 139bf215546Sopenharmony_ci{ 140bf215546Sopenharmony_ci struct i915_context *i915 = i915_context(pipe); 141bf215546Sopenharmony_ci int i; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci if (i915->blitter) 144bf215546Sopenharmony_ci util_blitter_destroy(i915->blitter); 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci draw_destroy(i915->draw); 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci if (i915->base.stream_uploader) 149bf215546Sopenharmony_ci u_upload_destroy(i915->base.stream_uploader); 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci if (i915->batch) 152bf215546Sopenharmony_ci i915->iws->batchbuffer_destroy(i915->batch); 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci /* unbind framebuffer */ 155bf215546Sopenharmony_ci for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 156bf215546Sopenharmony_ci pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL); 157bf215546Sopenharmony_ci } 158bf215546Sopenharmony_ci pipe_surface_reference(&i915->framebuffer.zsbuf, NULL); 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci /* unbind constant buffers */ 161bf215546Sopenharmony_ci for (i = 0; i < PIPE_SHADER_TYPES; i++) { 162bf215546Sopenharmony_ci pipe_resource_reference(&i915->constants[i], NULL); 163bf215546Sopenharmony_ci } 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci FREE(i915); 166bf215546Sopenharmony_ci} 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_cistatic void 169bf215546Sopenharmony_cii915_set_debug_callback(struct pipe_context *pipe, 170bf215546Sopenharmony_ci const struct util_debug_callback *cb) 171bf215546Sopenharmony_ci{ 172bf215546Sopenharmony_ci struct i915_context *i915 = i915_context(pipe); 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci if (cb) 175bf215546Sopenharmony_ci i915->debug = *cb; 176bf215546Sopenharmony_ci else 177bf215546Sopenharmony_ci memset(&i915->debug, 0, sizeof(i915->debug)); 178bf215546Sopenharmony_ci} 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_cistruct pipe_context * 181bf215546Sopenharmony_cii915_create_context(struct pipe_screen *screen, void *priv, unsigned flags) 182bf215546Sopenharmony_ci{ 183bf215546Sopenharmony_ci struct i915_context *i915; 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci i915 = CALLOC_STRUCT(i915_context); 186bf215546Sopenharmony_ci if (!i915) 187bf215546Sopenharmony_ci return NULL; 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci i915->iws = i915_screen(screen)->iws; 190bf215546Sopenharmony_ci i915->base.screen = screen; 191bf215546Sopenharmony_ci i915->base.priv = priv; 192bf215546Sopenharmony_ci i915->base.stream_uploader = u_upload_create_default(&i915->base); 193bf215546Sopenharmony_ci i915->base.const_uploader = i915->base.stream_uploader; 194bf215546Sopenharmony_ci i915->base.set_debug_callback = i915_set_debug_callback; 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci i915->base.destroy = i915_destroy; 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci if (i915_screen(screen)->debug.use_blitter) 199bf215546Sopenharmony_ci i915->base.clear = i915_clear_blitter; 200bf215546Sopenharmony_ci else 201bf215546Sopenharmony_ci i915->base.clear = i915_clear_render; 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci i915->base.draw_vbo = i915_draw_vbo; 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci /* init this before draw */ 206bf215546Sopenharmony_ci slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer), 16); 207bf215546Sopenharmony_ci slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer), 16); 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci /* Batch stream debugging is a bit hacked up at the moment: 210bf215546Sopenharmony_ci */ 211bf215546Sopenharmony_ci i915->batch = i915->iws->batchbuffer_create(i915->iws); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci /* 214bf215546Sopenharmony_ci * Create drawing context and plug our rendering stage into it. 215bf215546Sopenharmony_ci */ 216bf215546Sopenharmony_ci i915->draw = draw_create(&i915->base); 217bf215546Sopenharmony_ci assert(i915->draw); 218bf215546Sopenharmony_ci if (i915_debug & DBG_VBUF) { 219bf215546Sopenharmony_ci draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915)); 220bf215546Sopenharmony_ci } else { 221bf215546Sopenharmony_ci draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915)); 222bf215546Sopenharmony_ci } 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci i915_init_surface_functions(i915); 225bf215546Sopenharmony_ci i915_init_state_functions(i915); 226bf215546Sopenharmony_ci i915_init_flush_functions(i915); 227bf215546Sopenharmony_ci i915_init_resource_functions(i915); 228bf215546Sopenharmony_ci i915_init_query_functions(i915); 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci /* Create blitter. */ 231bf215546Sopenharmony_ci i915->blitter = util_blitter_create(&i915->base); 232bf215546Sopenharmony_ci assert(i915->blitter); 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci /* must be done before installing Draw stages */ 235bf215546Sopenharmony_ci i915->no_log_program_errors = true; 236bf215546Sopenharmony_ci util_blitter_cache_all_shaders(i915->blitter); 237bf215546Sopenharmony_ci i915->no_log_program_errors = false; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci draw_install_aaline_stage(i915->draw, &i915->base); 240bf215546Sopenharmony_ci draw_install_aapoint_stage(i915->draw, &i915->base); 241bf215546Sopenharmony_ci draw_enable_point_sprites(i915->draw, true); 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci i915->dirty = ~0; 244bf215546Sopenharmony_ci i915->hardware_dirty = ~0; 245bf215546Sopenharmony_ci i915->immediate_dirty = ~0; 246bf215546Sopenharmony_ci i915->dynamic_dirty = ~0; 247bf215546Sopenharmony_ci i915->static_dirty = ~0; 248bf215546Sopenharmony_ci i915->flush_dirty = 0; 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci i915->current.fixup_swizzle = ~0; 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci return &i915->base; 253bf215546Sopenharmony_ci} 254