1bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* 2bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Copyright (C) 2009-2010 Francisco Jerez. 3bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * All Rights Reserved. 4bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * 5bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Permission is hereby granted, free of charge, to any person obtaining 6bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * a copy of this software and associated documentation files (the 7bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * "Software"), to deal in the Software without restriction, including 8bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * without limitation the rights to use, copy, modify, merge, publish, 9bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * distribute, sublicense, and/or sell copies of the Software, and to 10bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * permit persons to whom the Software is furnished to do so, subject to 11bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * the following conditions: 12bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * 13bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * The above copyright notice and this permission notice (including the 14bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * next paragraph) shall be included in all copies or substantial 15bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * portions of the Software. 16bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * 17bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * 25bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez */ 26bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 272e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs#include "nouveau_driver.h" 28bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_bufferobj.h" 2943c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez#include "nouveau_util.h" 3043c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez 3143c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez#include "main/bufferobj.h" 321f9239ec8d67c3e8ee64e6f5306499b6d97ea136Brian Paul#include "main/glformats.h" 3343c347c63ee10db95bd912fc39b1127fa35305a4Francisco Jerez#include "main/image.h" 34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 35bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Arbitrary pushbuf length we can assume we can get with a single 3657382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez * call to WAIT_RING. */ 37c25fcf5aa5beccd7731706b8f85682170a2eca56Francisco Jerez#define PUSHBUF_DWORDS 65536 38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 3957382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez/* Functions to turn GL arrays or index buffers into nouveau_array 4057382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez * structures. */ 41bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 427f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerezstatic int 43f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergget_array_stride(struct gl_context *ctx, const struct gl_client_array *a) 447f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez{ 457f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 467f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez 477f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez if (render->mode == VBO && !_mesa_is_bufferobj(a->BufferObj)) 487f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez /* Pack client buffers. */ 497f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez return align(_mesa_sizeof_type(a->Type) * a->Size, 4); 507f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez else 517f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez return a->StrideB; 527f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez} 537f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerez 54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 55f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_init_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib, 56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct gl_client_array **arrays) 57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 599d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez GLboolean imm = (render->mode == IMM); 609d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez int i, attr; 61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 62bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (ib) 6357382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez nouveau_init_array(&render->ib, 0, 0, ib->count, ib->type, 642e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs ib->obj, ib->ptr, GL_TRUE, ctx); 65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 669d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez FOR_EACH_BOUND_ATTR(render, i, attr) { 679d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez const struct gl_client_array *array = arrays[attr]; 68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 6957382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez nouveau_init_array(&render->attrs[attr], attr, 7057382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez get_array_stride(ctx, array), 7157382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez array->Size, array->Type, 72e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez imm ? array->BufferObj : NULL, 732e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs array->Ptr, imm, ctx); 74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 77bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 78f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_deinit_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib, 799d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez const struct gl_client_array **arrays) 80bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 81bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 829d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez int i, attr; 83bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (ib) 8557382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez nouveau_cleanup_array(&render->ib); 86bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 879d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez FOR_EACH_BOUND_ATTR(render, i, attr) { 8857382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez struct nouveau_array *a = &render->attrs[attr]; 89bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 90e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez if (render->mode == IMM) 91e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez nouveau_bo_ref(NULL, &a->bo); 92e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 9357382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez nouveau_deinit_array(a); 949d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez render->map[i] = -1; 95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 96bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez render->attr_count = 0; 98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Make some rendering decisions from the GL context. */ 101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 103f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_choose_render_mode(struct gl_context *ctx, const struct gl_client_array **arrays) 104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez int i; 107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez render->mode = VBO; 109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (ctx->Light.Enabled) { 111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez for (i = 0; i < MAT_ATTRIB_MAX; i++) { 112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (arrays[VERT_ATTRIB_GENERIC0 + i]->StrideB) { 113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez render->mode = IMM; 114bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez break; 115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 118bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 12157382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerezvbo_emit_attr(struct gl_context *ctx, const struct gl_client_array **arrays, 12257382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez int attr) 123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 1242e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs struct nouveau_pushbuf *push = context_push(ctx); 125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct gl_client_array *array = arrays[attr]; 12757382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez struct nouveau_array *a = &render->attrs[attr]; 128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez RENDER_LOCALS(ctx); 129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 130bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (!array->StrideB) { 131bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (attr >= VERT_ATTRIB_GENERIC0) 132bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez /* nouveau_update_state takes care of materials. */ 133bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez return; 134bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 135bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez /* Constant attribute. */ 13657382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez nouveau_init_array(a, attr, array->StrideB, array->Size, 13757382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez array->Type, array->BufferObj, array->Ptr, 1382e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs GL_TRUE, ctx); 139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez EMIT_IMM(ctx, a, 0); 14057382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez nouveau_deinit_array(a); 141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } else { 143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez /* Varying attribute. */ 144bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_attr_info *info = &TAG(vertex_attrs)[attr]; 145bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 146bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (render->mode == VBO) { 147bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez render->map[info->vbo_index] = attr; 148bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez render->vertex_size += array->_ElementSize; 1499d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez render->attr_count = MAX2(render->attr_count, 1509d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez info->vbo_index + 1); 151bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } else { 152bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez render->map[render->attr_count++] = attr; 153bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez render->vertex_size += 4 * info->imm_fields; 154bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 155bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 156bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 157bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 158bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#define MAT(a) (VERT_ATTRIB_GENERIC0 + MAT_ATTRIB_##a) 159bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 160bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 161f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_choose_attrs(struct gl_context *ctx, const struct gl_client_array **arrays) 162bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 163bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 164bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez int i; 165bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 166bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez /* Reset the vertex size. */ 167bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez render->vertex_size = 0; 1689d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez render->attr_count = 0; 169bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 170bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR0); 171bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (ctx->Fog.ColorSumEnabled && !ctx->Light.Enabled) 172bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR1); 173bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 174bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 175bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (ctx->Texture._EnabledCoordUnits & (1 << i)) 176bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, VERT_ATTRIB_TEX0 + i); 177bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 178bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 179bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (ctx->Fog.Enabled && ctx->Fog.FogCoordinateSource == GL_FOG_COORD) 180bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, VERT_ATTRIB_FOG); 181bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 182c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez if (ctx->Light.Enabled || 183c944fb5ffe7cf16154d6395001f43a6c965cab1fFrancisco Jerez (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)) 184bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, VERT_ATTRIB_NORMAL); 185bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 186e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez if (ctx->Light.Enabled && render->mode == IMM) { 187bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, MAT(FRONT_AMBIENT)); 188bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, MAT(FRONT_DIFFUSE)); 189bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, MAT(FRONT_SPECULAR)); 190bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, MAT(FRONT_SHININESS)); 191bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 192bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (ctx->Light.Model.TwoSide) { 193bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, MAT(BACK_AMBIENT)); 194bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, MAT(BACK_DIFFUSE)); 195bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, MAT(BACK_SPECULAR)); 196bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, MAT(BACK_SHININESS)); 197bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 198bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 199bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 200bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_emit_attr(ctx, arrays, VERT_ATTRIB_POS); 201bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 202bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 2037f1f4c14eced51bf3f43764e2864693ba1c4a6d5Francisco Jerezstatic int 204f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergget_max_client_stride(struct gl_context *ctx, const struct gl_client_array **arrays) 20580316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez{ 20680316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 2079d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez int i, attr, s = 0; 20880316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez 2099d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez FOR_EACH_BOUND_ATTR(render, i, attr) { 2109d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez const struct gl_client_array *a = arrays[attr]; 21180316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez 2129d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez if (!_mesa_is_bufferobj(a->BufferObj)) 2139d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez s = MAX2(s, get_array_stride(ctx, a)); 21480316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez } 21580316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez 21680316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez return s; 21780316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez} 21880316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez 219bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 22050f7e75f9e945cfbb2ae868cc961a2205a0b6e73Marek OlšákTAG(vbo_render_prims)(struct gl_context *ctx, 221bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_prim *prims, GLuint nr_prims, 222bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_index_buffer *ib, 223bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez GLboolean index_bounds_valid, 22414bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák GLuint min_index, GLuint max_index, 22514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák struct gl_transform_feedback_object *tfb_vertcount); 226bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 227bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic GLboolean 228f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_maybe_split(struct gl_context *ctx, const struct gl_client_array **arrays, 229bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_prim *prims, GLuint nr_prims, 230bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_index_buffer *ib, 231bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez GLuint min_index, GLuint max_index) 232bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 233bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_context *nctx = to_nouveau_context(ctx); 23480316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 2352e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs struct nouveau_bufctx *bufctx = nctx->hw.bufctx; 2362e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs unsigned pushbuf_avail = PUSHBUF_DWORDS - 2 * (bufctx->relocs + 237d475eae50b15646efd83fa7f73ad7f2b40dd5206Francisco Jerez render->attr_count), 238bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vert_avail = get_max_vertices(ctx, NULL, pushbuf_avail), 239bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez idx_avail = get_max_vertices(ctx, ib, pushbuf_avail); 24080316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez int stride; 24180316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez 24280316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez /* Try to keep client buffers smaller than the scratch BOs. */ 243ea027bda8e4a7cdd8f131e01ab4ff80d6c6a3ab7Francisco Jerez if (render->mode == VBO && 244d475eae50b15646efd83fa7f73ad7f2b40dd5206Francisco Jerez (stride = get_max_client_stride(ctx, arrays))) 24580316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez vert_avail = MIN2(vert_avail, 246f2098e0fefbbcd72df4c8283d195beae4a113f35Francisco Jerez NOUVEAU_SCRATCH_SIZE / stride); 24780316cbefaa28454ab9d6da44ac93805608c3685Francisco Jerez 248ea027bda8e4a7cdd8f131e01ab4ff80d6c6a3ab7Francisco Jerez if (max_index - min_index > vert_avail || 249ea027bda8e4a7cdd8f131e01ab4ff80d6c6a3ab7Francisco Jerez (ib && ib->count > idx_avail)) { 250bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct split_limits limits = { 251bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez .max_verts = vert_avail, 252bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez .max_indices = idx_avail, 253bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez .max_vb_size = ~0, 254bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez }; 255bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 256bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_split_prims(ctx, arrays, prims, nr_prims, ib, min_index, 257bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez max_index, TAG(vbo_render_prims), &limits); 258bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez return GL_TRUE; 259bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 260bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 261bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez return GL_FALSE; 262bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 263bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 264bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* VBO rendering path. */ 265bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 266e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerezstatic GLboolean 267e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerezcheck_update_array(struct nouveau_array *a, unsigned offset, 268e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez struct nouveau_bo *bo, int *pdelta) 269e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez{ 270e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez int delta = *pdelta; 271e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez GLboolean dirty; 272e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 273e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez if (a->bo == bo) { 274e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez if (delta < 0) 275453b71855294508fce8358134f9bf5316043b834Francisco Jerez delta = ((int)offset - (int)a->offset) / a->stride; 276e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 277e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez dirty = (delta < 0 || 278e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez offset != (a->offset + delta * a->stride)); 279e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez } else { 280e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez dirty = GL_TRUE; 281e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez } 282e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 283e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez *pdelta = (dirty ? 0 : delta); 284e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez return dirty; 285e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez} 286e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 287bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 288f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_bind_vertices(struct gl_context *ctx, const struct gl_client_array **arrays, 289e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez int base, unsigned min_index, unsigned max_index, int *pdelta) 290bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 291bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 2922e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs struct nouveau_pushbuf *push = context_push(ctx); 293e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez struct nouveau_bo *bo[NUM_VERTEX_ATTRS]; 294e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez unsigned offset[NUM_VERTEX_ATTRS]; 295e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez GLboolean dirty = GL_FALSE; 296e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez int i, j, attr; 297e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez RENDER_LOCALS(ctx); 298e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 299e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez *pdelta = -1; 300bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 3019d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez FOR_EACH_BOUND_ATTR(render, i, attr) { 3029d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez const struct gl_client_array *array = arrays[attr]; 303f67fa5229331f6d4920175dd0d6e1e6a2c69c060Francisco Jerez struct gl_buffer_object *obj = array->BufferObj; 30457382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez struct nouveau_array *a = &render->attrs[attr]; 305e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez unsigned delta = (base + min_index) * array->StrideB; 306e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 307e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez bo[i] = NULL; 308e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 309f67fa5229331f6d4920175dd0d6e1e6a2c69c060Francisco Jerez if (nouveau_bufferobj_hw(obj)) { 3109d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez /* Array in a buffer obj. */ 311f67fa5229331f6d4920175dd0d6e1e6a2c69c060Francisco Jerez nouveau_bo_ref(to_nouveau_bufferobj(obj)->bo, &bo[i]); 312e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez offset[i] = delta + (intptr_t)array->Ptr; 313e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 3149d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez } else { 315e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez int n = max_index - min_index + 1; 316f67fa5229331f6d4920175dd0d6e1e6a2c69c060Francisco Jerez char *sp = (char *)ADD_POINTERS( 317f67fa5229331f6d4920175dd0d6e1e6a2c69c060Francisco Jerez nouveau_bufferobj_sys(obj), array->Ptr) + delta; 318e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez char *dp = nouveau_get_scratch(ctx, n * a->stride, 319e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez &bo[i], &offset[i]); 3209d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez 321e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez /* Array in client memory, move it to a 322e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez * scratch buffer obj. */ 3239d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez for (j = 0; j < n; j++) 3249d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez memcpy(dp + j * a->stride, 3259d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez sp + j * array->StrideB, 3269d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez a->stride); 327bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 328e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 329e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez dirty |= check_update_array(a, offset[i], bo[i], pdelta); 330e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez } 331e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 332e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez *pdelta -= min_index; 333e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 334e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez if (dirty) { 335e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez /* Buffers changed, update the attribute binding. */ 336e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez FOR_EACH_BOUND_ATTR(render, i, attr) { 337e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez struct nouveau_array *a = &render->attrs[attr]; 338e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 339e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez nouveau_bo_ref(NULL, &a->bo); 340e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez a->offset = offset[i]; 341e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez a->bo = bo[i]; 342e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez } 343e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez 3442e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs TAG(render_release_vertices)(ctx); 345e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez TAG(render_bind_vertices)(ctx); 346e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez } else { 347e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez /* Just cleanup. */ 348e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez FOR_EACH_BOUND_ATTR(render, i, attr) 349e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez nouveau_bo_ref(NULL, &bo[i]); 350bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 351bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 352e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez BATCH_VALIDATE(); 353bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 354bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 355bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 356f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_draw_vbo(struct gl_context *ctx, const struct gl_client_array **arrays, 357bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_prim *prims, GLuint nr_prims, 358bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_index_buffer *ib, GLuint min_index, 359bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez GLuint max_index) 360bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 3612e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs struct nouveau_context *nctx = to_nouveau_context(ctx); 3622e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs struct nouveau_pushbuf *push = context_push(ctx); 36357382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerez dispatch_t dispatch = get_array_dispatch(&to_render_state(ctx)->ib); 364e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez int i, delta = 0, basevertex = 0; 365bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez RENDER_LOCALS(ctx); 366bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 367bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez TAG(render_set_format)(ctx); 368bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 369bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez for (i = 0; i < nr_prims; i++) { 370bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez unsigned start = prims[i].start, 371bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez count = prims[i].count; 372bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 373bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (i == 0 || basevertex != prims[i].basevertex) { 374bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez basevertex = prims[i].basevertex; 375e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez vbo_bind_vertices(ctx, arrays, basevertex, min_index, 376e89af209261e51988b99d954d09f2cbc59e55358Francisco Jerez max_index, &delta); 3772e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs 3782e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs nouveau_pushbuf_bufctx(push, nctx->hw.bufctx); 3792e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs if (nouveau_pushbuf_validate(push)) { 3802e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs nouveau_pushbuf_bufctx(push, NULL); 3812e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs return; 3822e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs } 383bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 384bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 3852e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs if (count > get_max_vertices(ctx, ib, PUSH_AVAIL(push))) 3862e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs PUSH_SPACE(push, PUSHBUF_DWORDS); 387bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 388bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez BATCH_BEGIN(nvgl_primitive(prims[i].mode)); 389bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez dispatch(ctx, start, delta, count); 390bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez BATCH_END(); 391bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 3922e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs 3932e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs nouveau_pushbuf_bufctx(push, NULL); 3942e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs TAG(render_release_vertices)(ctx); 395bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 396bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 397bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* Immediate rendering path. */ 398bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 399bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic unsigned 40057382e71ef892a36ca2171fe8758aba6c9c885e6Francisco Jerezextract_id(struct nouveau_array *a, int i, int j) 401bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 402bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez return j; 403bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 404bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 405bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 406f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvbo_draw_imm(struct gl_context *ctx, const struct gl_client_array **arrays, 407bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_prim *prims, GLuint nr_prims, 408bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_index_buffer *ib, GLuint min_index, 409bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez GLuint max_index) 410bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 411bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 4122e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs struct nouveau_context *nctx = to_nouveau_context(ctx); 4132e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs struct nouveau_pushbuf *push = context_push(ctx); 414bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez extract_u_t extract = ib ? render->ib.extract_u : extract_id; 4159d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez int i, j, k, attr; 416bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez RENDER_LOCALS(ctx); 417bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 4182e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs nouveau_pushbuf_bufctx(push, nctx->hw.bufctx); 4192e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs if (nouveau_pushbuf_validate(push)) { 4202e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs nouveau_pushbuf_bufctx(push, NULL); 4212e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs return; 4222e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs } 4232e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs 424bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez for (i = 0; i < nr_prims; i++) { 425bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez unsigned start = prims[i].start, 426bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez end = start + prims[i].count; 427bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 428bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (prims[i].count > get_max_vertices(ctx, ib, 4292e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs PUSH_AVAIL(push))) 4302e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs PUSH_SPACE(push, PUSHBUF_DWORDS); 431bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 432bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez BATCH_BEGIN(nvgl_primitive(prims[i].mode)); 433bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 434bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez for (; start < end; start++) { 435bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez j = prims[i].basevertex + 436bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez extract(&render->ib, 0, start); 437bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 4389d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez FOR_EACH_BOUND_ATTR(render, k, attr) 4399d1f1fcf136e8f5f427ae203128ff641cc9e7197Francisco Jerez EMIT_IMM(ctx, &render->attrs[attr], j); 440bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 441bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 442bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez BATCH_END(); 443bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 4442e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs 4452e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs nouveau_pushbuf_bufctx(push, NULL); 446bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 447bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 448bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* draw_prims entry point when we're doing hw-tnl. */ 449bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 450bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 45157382e71ef892a36ca2171fe8758aba6c9c885e6Francisco JerezTAG(vbo_render_prims)(struct gl_context *ctx, 452bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_prim *prims, GLuint nr_prims, 453bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez const struct _mesa_index_buffer *ib, 454bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez GLboolean index_bounds_valid, 45514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák GLuint min_index, GLuint max_index, 45614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák struct gl_transform_feedback_object *tfb_vertcount) 457bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 458bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 45950f7e75f9e945cfbb2ae868cc961a2205a0b6e73Marek Olšák const struct gl_client_array **arrays = ctx->Array._DrawArrays; 460bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 461bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (!index_bounds_valid) 46242d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, 46342d4972bf0b147b0241c2be7e6579fd64cf2c216Yuanhan Liu nr_prims); 464bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 465bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_choose_render_mode(ctx, arrays); 466bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_choose_attrs(ctx, arrays); 467bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 468bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (vbo_maybe_split(ctx, arrays, prims, nr_prims, ib, min_index, 469bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez max_index)) 470bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez return; 471bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 472bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_init_arrays(ctx, ib, arrays); 473bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 474bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (render->mode == VBO) 475bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_draw_vbo(ctx, arrays, prims, nr_prims, ib, min_index, 476bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez max_index); 477bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez else 478bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_draw_imm(ctx, arrays, prims, nr_prims, ib, min_index, 479bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez max_index); 480bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 481bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez vbo_deinit_arrays(ctx, ib, arrays); 482bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 483cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez 484cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez/* VBO rendering entry points. */ 485cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez 486cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerezstatic void 487cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco JerezTAG(vbo_check_render_prims)(struct gl_context *ctx, 488cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez const struct _mesa_prim *prims, GLuint nr_prims, 489cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez const struct _mesa_index_buffer *ib, 490cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez GLboolean index_bounds_valid, 49114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák GLuint min_index, GLuint max_index, 49214bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák struct gl_transform_feedback_object *tfb_vertcount) 493cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez{ 494cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez struct nouveau_context *nctx = to_nouveau_context(ctx); 495cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez 496cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez nouveau_validate_framebuffer(ctx); 497cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez 498cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez if (nctx->fallback == HWTNL) 49950f7e75f9e945cfbb2ae868cc961a2205a0b6e73Marek Olšák TAG(vbo_render_prims)(ctx, prims, nr_prims, ib, 50014bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák index_bounds_valid, min_index, max_index, 50114bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák tfb_vertcount); 502cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez 503cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez if (nctx->fallback == SWTNL) 50450f7e75f9e945cfbb2ae868cc961a2205a0b6e73Marek Olšák _tnl_vbo_draw_prims(ctx, prims, nr_prims, ib, 50514bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák index_bounds_valid, min_index, max_index, 50614bb957b996dcc5392b8fa589bd3ffa5c55cb6b4Marek Olšák tfb_vertcount); 507cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez} 508cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez 509cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerezvoid 510cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco JerezTAG(vbo_init)(struct gl_context *ctx) 511cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez{ 512cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez struct nouveau_render_state *render = to_render_state(ctx); 513cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez int i; 514cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez 515cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez for (i = 0; i < VERT_ATTRIB_MAX; i++) 516cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez render->map[i] = -1; 517cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez 518cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez vbo_set_draw_func(ctx, TAG(vbo_check_render_prims)); 519cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez vbo_use_buffer_objects(ctx); 520cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez} 521cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez 522cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerezvoid 523cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco JerezTAG(vbo_destroy)(struct gl_context *ctx) 524cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez{ 525cdb38b5d3d1b93a90a91ad06c0f03efdfde6b525Francisco Jerez} 526