14a49301eSmrg/**************************************************************************
27ec681f3Smrg *
3af69d88dSmrg * Copyright 2003 VMware, Inc.
44a49301eSmrg * All Rights Reserved.
57ec681f3Smrg *
64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a
74a49301eSmrg * copy of this software and associated documentation files (the
84a49301eSmrg * "Software"), to deal in the Software without restriction, including
94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish,
104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to
114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to
124a49301eSmrg * the following conditions:
137ec681f3Smrg *
144a49301eSmrg * The above copyright notice and this permission notice (including the
154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions
164a49301eSmrg * of the Software.
177ec681f3Smrg *
184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
257ec681f3Smrg *
264a49301eSmrg **************************************************************************/
274a49301eSmrg
284a49301eSmrg#include "i915_context.h"
294a49301eSmrg#include "i915_batch.h"
307ec681f3Smrg#include "i915_debug.h"
317ec681f3Smrg#include "i915_query.h"
323464ebd5Sriastradh#include "i915_resource.h"
337ec681f3Smrg#include "i915_screen.h"
347ec681f3Smrg#include "i915_state.h"
357ec681f3Smrg#include "i915_surface.h"
364a49301eSmrg
374a49301eSmrg#include "draw/draw_context.h"
384a49301eSmrg#include "pipe/p_defines.h"
397ec681f3Smrg#include "pipe/p_screen.h"
407ec681f3Smrg#include "util/u_draw.h"
41cdc920a0Smrg#include "util/u_inlines.h"
424a49301eSmrg#include "util/u_memory.h"
4301e04c3fSmrg#include "util/u_prim.h"
4401e04c3fSmrg#include "util/u_upload_mgr.h"
453464ebd5Sriastradh
464a49301eSmrg/*
474a49301eSmrg * Draw functions
484a49301eSmrg */
494a49301eSmrg
50cdc920a0Smrgstatic void
517ec681f3Smrgi915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
527ec681f3Smrg              unsigned drawid_offset,
537ec681f3Smrg              const struct pipe_draw_indirect_info *indirect,
547ec681f3Smrg              const struct pipe_draw_start_count_bias *draws,
557ec681f3Smrg              unsigned num_draws)
564a49301eSmrg{
577ec681f3Smrg   if (num_draws > 1) {
587ec681f3Smrg      util_draw_multi(pipe, info, drawid_offset, indirect, draws, num_draws);
597ec681f3Smrg      return;
607ec681f3Smrg   }
617ec681f3Smrg
624a49301eSmrg   struct i915_context *i915 = i915_context(pipe);
634a49301eSmrg   struct draw_context *draw = i915->draw;
64af69d88dSmrg   const void *mapped_indices = NULL;
65af69d88dSmrg   unsigned i;
664a49301eSmrg
677ec681f3Smrg   if (!u_trim_pipe_prim(info->mode, (unsigned *)&draws[0].count))
6801e04c3fSmrg      return;
6901e04c3fSmrg
704a49301eSmrg   /*
713464ebd5Sriastradh    * Ack vs contants here, helps ipers a lot.
724a49301eSmrg    */
733464ebd5Sriastradh   i915->dirty &= ~I915_NEW_VS_CONSTANTS;
743464ebd5Sriastradh
753464ebd5Sriastradh   if (i915->dirty)
763464ebd5Sriastradh      i915_update_derived(i915);
774a49301eSmrg
78af69d88dSmrg   /*
79af69d88dSmrg    * Map vertex buffers
80af69d88dSmrg    */
81af69d88dSmrg   for (i = 0; i < i915->nr_vertex_buffers; i++) {
827ec681f3Smrg      const void *buf = i915->vertex_buffers[i].is_user_buffer
837ec681f3Smrg                           ? i915->vertex_buffers[i].buffer.user
847ec681f3Smrg                           : NULL;
859f464c52Smaya      if (!buf) {
869f464c52Smaya         if (!i915->vertex_buffers[i].buffer.resource)
879f464c52Smaya            continue;
889f464c52Smaya         buf = i915_buffer(i915->vertex_buffers[i].buffer.resource)->data;
899f464c52Smaya      }
90af69d88dSmrg      draw_set_mapped_vertex_buffer(draw, i, buf, ~0);
91af69d88dSmrg   }
92af69d88dSmrg
934a49301eSmrg   /*
944a49301eSmrg    * Map index buffer, if present
954a49301eSmrg    */
9601e04c3fSmrg   if (info->index_size) {
9701e04c3fSmrg      mapped_indices = info->has_user_indices ? info->index.user : NULL;
98af69d88dSmrg      if (!mapped_indices)
9901e04c3fSmrg         mapped_indices = i915_buffer(info->index.resource)->data;
1007ec681f3Smrg      draw_set_indexes(draw, (ubyte *)mapped_indices, info->index_size, ~0);
101af69d88dSmrg   }
1023464ebd5Sriastradh
1033464ebd5Sriastradh   if (i915->constants[PIPE_SHADER_VERTEX])
1047ec681f3Smrg      draw_set_mapped_constant_buffer(
1057ec681f3Smrg         draw, PIPE_SHADER_VERTEX, 0,
1067ec681f3Smrg         i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data,
1077ec681f3Smrg         (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * 4 *
1087ec681f3Smrg          sizeof(float)));
1093464ebd5Sriastradh   else
1103464ebd5Sriastradh      draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0);
1114a49301eSmrg
1124a49301eSmrg   /*
1134a49301eSmrg    * Do the drawing
1144a49301eSmrg    */
1157ec681f3Smrg   draw_vbo(i915->draw, info, drawid_offset, NULL, draws, num_draws, 0);
1164a49301eSmrg
117af69d88dSmrg   /*
118af69d88dSmrg    * unmap vertex/index buffers
119af69d88dSmrg    */
120af69d88dSmrg   for (i = 0; i < i915->nr_vertex_buffers; i++) {
121af69d88dSmrg      draw_set_mapped_vertex_buffer(i915->draw, i, NULL, 0);
122af69d88dSmrg   }
1233464ebd5Sriastradh   if (mapped_indices)
124af69d88dSmrg      draw_set_indexes(draw, NULL, 0, 0);
125af69d88dSmrg
126af69d88dSmrg   /*
127af69d88dSmrg    * Instead of flushing on every state change, we flush once here
128af69d88dSmrg    * when we fire the vbo.
129af69d88dSmrg    */
130af69d88dSmrg   draw_flush(i915->draw);
1314a49301eSmrg}
1324a49301eSmrg
1334a49301eSmrg/*
1344a49301eSmrg * Generic context functions
1354a49301eSmrg */
1364a49301eSmrg
1377ec681f3Smrgstatic void
1387ec681f3Smrgi915_destroy(struct pipe_context *pipe)
1394a49301eSmrg{
1404a49301eSmrg   struct i915_context *i915 = i915_context(pipe);
1414a49301eSmrg   int i;
1424a49301eSmrg
1433464ebd5Sriastradh   if (i915->blitter)
1443464ebd5Sriastradh      util_blitter_destroy(i915->blitter);
1453464ebd5Sriastradh
146af69d88dSmrg   draw_destroy(i915->draw);
147af69d88dSmrg
14801e04c3fSmrg   if (i915->base.stream_uploader)
14901e04c3fSmrg      u_upload_destroy(i915->base.stream_uploader);
15001e04c3fSmrg
1517ec681f3Smrg   if (i915->batch)
1524a49301eSmrg      i915->iws->batchbuffer_destroy(i915->batch);
1534a49301eSmrg
1544a49301eSmrg   /* unbind framebuffer */
1554a49301eSmrg   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
1564a49301eSmrg      pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL);
1574a49301eSmrg   }
1584a49301eSmrg   pipe_surface_reference(&i915->framebuffer.zsbuf, NULL);
1594a49301eSmrg
1603464ebd5Sriastradh   /* unbind constant buffers */
1613464ebd5Sriastradh   for (i = 0; i < PIPE_SHADER_TYPES; i++) {
1623464ebd5Sriastradh      pipe_resource_reference(&i915->constants[i], NULL);
1633464ebd5Sriastradh   }
1643464ebd5Sriastradh
1654a49301eSmrg   FREE(i915);
1664a49301eSmrg}
1674a49301eSmrg
1687ec681f3Smrgstatic void
1697ec681f3Smrgi915_set_debug_callback(struct pipe_context *pipe,
1707ec681f3Smrg                        const struct pipe_debug_callback *cb)
1717ec681f3Smrg{
1727ec681f3Smrg   struct i915_context *i915 = i915_context(pipe);
1737ec681f3Smrg
1747ec681f3Smrg   if (cb)
1757ec681f3Smrg      i915->debug = *cb;
1767ec681f3Smrg   else
1777ec681f3Smrg      memset(&i915->debug, 0, sizeof(i915->debug));
1787ec681f3Smrg}
1797ec681f3Smrg
1804a49301eSmrgstruct pipe_context *
18101e04c3fSmrgi915_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
1824a49301eSmrg{
1834a49301eSmrg   struct i915_context *i915;
1844a49301eSmrg
1854a49301eSmrg   i915 = CALLOC_STRUCT(i915_context);
18601e04c3fSmrg   if (!i915)
1874a49301eSmrg      return NULL;
1884a49301eSmrg
1894a49301eSmrg   i915->iws = i915_screen(screen)->iws;
1904a49301eSmrg   i915->base.screen = screen;
191cdc920a0Smrg   i915->base.priv = priv;
19201e04c3fSmrg   i915->base.stream_uploader = u_upload_create_default(&i915->base);
19301e04c3fSmrg   i915->base.const_uploader = i915->base.stream_uploader;
1947ec681f3Smrg   i915->base.set_debug_callback = i915_set_debug_callback;
1954a49301eSmrg
1964a49301eSmrg   i915->base.destroy = i915_destroy;
1974a49301eSmrg
1983464ebd5Sriastradh   if (i915_screen(screen)->debug.use_blitter)
1993464ebd5Sriastradh      i915->base.clear = i915_clear_blitter;
2003464ebd5Sriastradh   else
2013464ebd5Sriastradh      i915->base.clear = i915_clear_render;
2023464ebd5Sriastradh
2033464ebd5Sriastradh   i915->base.draw_vbo = i915_draw_vbo;
2044a49301eSmrg
2053464ebd5Sriastradh   /* init this before draw */
2067ec681f3Smrg   slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer), 16);
2077ec681f3Smrg   slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer), 16);
2084a49301eSmrg
2093464ebd5Sriastradh   /* Batch stream debugging is a bit hacked up at the moment:
2103464ebd5Sriastradh    */
2113464ebd5Sriastradh   i915->batch = i915->iws->batchbuffer_create(i915->iws);
2124a49301eSmrg
2134a49301eSmrg   /*
2144a49301eSmrg    * Create drawing context and plug our rendering stage into it.
2154a49301eSmrg    */
216cdc920a0Smrg   i915->draw = draw_create(&i915->base);
2174a49301eSmrg   assert(i915->draw);
2187ec681f3Smrg   if (i915_debug & DBG_VBUF) {
2194a49301eSmrg      draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
2204a49301eSmrg   } else {
2214a49301eSmrg      draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915));
2224a49301eSmrg   }
2234a49301eSmrg
2244a49301eSmrg   i915_init_surface_functions(i915);
2254a49301eSmrg   i915_init_state_functions(i915);
2264a49301eSmrg   i915_init_flush_functions(i915);
2273464ebd5Sriastradh   i915_init_resource_functions(i915);
2283464ebd5Sriastradh   i915_init_query_functions(i915);
2294a49301eSmrg
230af69d88dSmrg   /* Create blitter. */
231af69d88dSmrg   i915->blitter = util_blitter_create(&i915->base);
232af69d88dSmrg   assert(i915->blitter);
233af69d88dSmrg
234af69d88dSmrg   /* must be done before installing Draw stages */
2357ec681f3Smrg   i915->no_log_program_errors = true;
236af69d88dSmrg   util_blitter_cache_all_shaders(i915->blitter);
2377ec681f3Smrg   i915->no_log_program_errors = false;
238af69d88dSmrg
2394a49301eSmrg   draw_install_aaline_stage(i915->draw, &i915->base);
2404a49301eSmrg   draw_install_aapoint_stage(i915->draw, &i915->base);
2417ec681f3Smrg   draw_enable_point_sprites(i915->draw, true);
2423464ebd5Sriastradh
2434a49301eSmrg   i915->dirty = ~0;
2444a49301eSmrg   i915->hardware_dirty = ~0;
2453464ebd5Sriastradh   i915->immediate_dirty = ~0;
2463464ebd5Sriastradh   i915->dynamic_dirty = ~0;
2473464ebd5Sriastradh   i915->static_dirty = ~0;
2483464ebd5Sriastradh   i915->flush_dirty = 0;
2494a49301eSmrg
2507ec681f3Smrg   i915->current.fixup_swizzle = ~0;
2517ec681f3Smrg
2524a49301eSmrg   return &i915->base;
2534a49301eSmrg}
254