1/*
2 * mesa 3-D graphics library
3 * Version:  6.5
4 *
5 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions 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 MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25/**
26 * \file vbo_context.h
27 * \brief VBO builder module datatypes and definitions.
28 * \author Keith Whitwell
29 */
30
31
32/**
33 * \mainpage The VBO builder module
34 *
35 * This module hooks into the GL dispatch table and catches all vertex
36 * building and drawing commands, such as glVertex3f, glBegin and
37 * glDrawArrays.  The module stores all incoming vertex data as arrays
38 * in GL vertex buffer objects (VBOs), and translates all drawing
39 * commands into calls to a driver supplied DrawPrimitives() callback.
40 *
41 * The module captures both immediate mode and display list drawing,
42 * and manages the allocation, reference counting and deallocation of
43 * vertex buffer objects itself.
44 *
45 * The DrawPrimitives() callback can be either implemented by the
46 * driver itself or hooked to the tnl module's _tnl_draw_primitives()
47 * function for hardware without tnl capablilties or during fallbacks.
48 */
49
50
51#ifndef _VBO_CONTEXT_H
52#define _VBO_CONTEXT_H
53
54#include "main/mfeatures.h"
55#include "vbo.h"
56#include "vbo_attrib.h"
57#include "vbo_exec.h"
58#include "vbo_save.h"
59
60
61/** Used to signal when transitioning from one kind of drawing method
62 * to another.
63 */
64enum draw_method
65{
66   DRAW_NONE,          /**< Initial value only */
67   DRAW_BEGIN_END,
68   DRAW_DISPLAY_LIST,
69   DRAW_ARRAYS
70};
71
72
73struct vbo_context {
74   struct gl_client_array currval[VBO_ATTRIB_MAX];
75
76   /** Map VERT_ATTRIB_x to VBO_ATTRIB_y */
77   GLuint map_vp_none[VERT_ATTRIB_MAX];
78   GLuint map_vp_arb[VERT_ATTRIB_MAX];
79
80   struct vbo_exec_context exec;
81#if FEATURE_dlist
82   struct vbo_save_context save;
83#endif
84
85   /* Callback into the driver.  This must always succeed, the driver
86    * is responsible for initiating any fallback actions required:
87    */
88   vbo_draw_func draw_prims;
89
90   enum draw_method last_draw_method;
91};
92
93
94static inline struct vbo_context *vbo_context(struct gl_context *ctx)
95{
96   return (struct vbo_context *)(ctx->swtnl_im);
97}
98
99
100/**
101 * Return VP_x token to indicate whether we're running fixed-function
102 * vertex transformation, an NV vertex program or ARB vertex program/shader.
103 */
104static inline enum vp_mode
105get_program_mode( struct gl_context *ctx )
106{
107   if (!ctx->VertexProgram._Current)
108      return VP_NONE;
109   else if (ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram)
110      return VP_NONE;
111   else if (ctx->VertexProgram._Current->IsNVProgram)
112      return VP_NV;
113   else
114      return VP_ARB;
115}
116
117
118/**
119 * This is called by glBegin, glDrawArrays and glDrawElements (and
120 * variations of those calls).  When we transition from immediate mode
121 * drawing to array drawing we need to invalidate the array state.
122 *
123 * glBegin/End builds vertex arrays.  Those arrays may look identical
124 * to glDrawArrays arrays except that the position of the elements may
125 * be different.  For example, arrays of (position3v, normal3f) vs. arrays
126 * of (normal3f, position3f).  So we need to make sure we notify drivers
127 * that arrays may be changing.
128 */
129static inline void
130vbo_draw_method(struct vbo_context *vbo, enum draw_method method)
131{
132   if (vbo->last_draw_method != method) {
133      struct gl_context *ctx = vbo->exec.ctx;
134
135      switch (method) {
136      case DRAW_ARRAYS:
137         ctx->Array._DrawArrays = vbo->exec.array.inputs;
138         break;
139      case DRAW_BEGIN_END:
140         ctx->Array._DrawArrays = vbo->exec.vtx.inputs;
141         break;
142      case DRAW_DISPLAY_LIST:
143         ctx->Array._DrawArrays = vbo->save.inputs;
144         break;
145      default:
146         ASSERT(0);
147      }
148
149      ctx->NewDriverState |= ctx->DriverFlags.NewArray;
150      vbo->last_draw_method = method;
151   }
152}
153
154/**
155 * Return if format is integer. The immediate mode commands only emit floats
156 * for non-integer types, thus everything else is integer.
157 */
158static inline GLboolean
159vbo_attrtype_to_integer_flag(GLenum format)
160{
161   switch (format) {
162   case GL_FLOAT:
163      return GL_FALSE;
164   case GL_INT:
165   case GL_UNSIGNED_INT:
166      return GL_TRUE;
167   default:
168      ASSERT(0);
169      return GL_FALSE;
170   }
171}
172
173
174/**
175 * Return default component values for the given format.
176 * The return type is an array of floats, because that's how we declare
177 * the vertex storage despite the fact we sometimes store integers in there.
178 */
179static inline const GLfloat *
180vbo_get_default_vals_as_float(GLenum format)
181{
182   static const GLfloat default_float[4] = { 0, 0, 0, 1 };
183   static const GLint default_int[4] = { 0, 0, 0, 1 };
184
185   switch (format) {
186   case GL_FLOAT:
187      return default_float;
188   case GL_INT:
189   case GL_UNSIGNED_INT:
190      return (const GLfloat*)default_int;
191   default:
192      ASSERT(0);
193      return NULL;
194   }
195}
196
197#endif
198