@@ -20,6 +20,7 @@ DRIVER_SOURCES = \ | |||
nouveau_texture.c \ | |||
nouveau_surface.c \ | |||
nouveau_scratch.c \ | |||
nouveau_array.c \ | |||
nv04_context.c \ | |||
nv04_render.c \ | |||
nv04_state_fb.c \ |
@@ -0,0 +1,135 @@ | |||
/* | |||
* Copyright (C) 2009-2010 Francisco Jerez. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sublicense, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial | |||
* portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | |||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
*/ | |||
#include "main/bufferobj.h" | |||
#include "nouveau_driver.h" | |||
#include "nouveau_array.h" | |||
#include "nouveau_bufferobj.h" | |||
static void | |||
get_array_extract(struct nouveau_array *a, extract_u_t *extract_u, | |||
extract_f_t *extract_f) | |||
{ | |||
#define EXTRACT(in_t, out_t, k) \ | |||
({ \ | |||
auto out_t f(struct nouveau_array *, int, int); \ | |||
out_t f(struct nouveau_array *a, int i, int j) { \ | |||
in_t x = ((in_t *)(a->buf + i * a->stride))[j]; \ | |||
\ | |||
return (out_t)x / (k); \ | |||
}; \ | |||
f; \ | |||
}); | |||
switch (a->type) { | |||
case GL_BYTE: | |||
*extract_u = EXTRACT(char, unsigned, 1); | |||
*extract_f = EXTRACT(char, float, SCHAR_MAX); | |||
break; | |||
case GL_UNSIGNED_BYTE: | |||
*extract_u = EXTRACT(unsigned char, unsigned, 1); | |||
*extract_f = EXTRACT(unsigned char, float, UCHAR_MAX); | |||
break; | |||
case GL_SHORT: | |||
*extract_u = EXTRACT(short, unsigned, 1); | |||
*extract_f = EXTRACT(short, float, SHRT_MAX); | |||
break; | |||
case GL_UNSIGNED_SHORT: | |||
*extract_u = EXTRACT(unsigned short, unsigned, 1); | |||
*extract_f = EXTRACT(unsigned short, float, USHRT_MAX); | |||
break; | |||
case GL_INT: | |||
*extract_u = EXTRACT(int, unsigned, 1); | |||
*extract_f = EXTRACT(int, float, INT_MAX); | |||
break; | |||
case GL_UNSIGNED_INT: | |||
*extract_u = EXTRACT(unsigned int, unsigned, 1); | |||
*extract_f = EXTRACT(unsigned int, float, UINT_MAX); | |||
break; | |||
case GL_FLOAT: | |||
*extract_u = EXTRACT(float, unsigned, 1.0 / UINT_MAX); | |||
*extract_f = EXTRACT(float, float, 1); | |||
break; | |||
default: | |||
assert(0); | |||
} | |||
} | |||
void | |||
nouveau_init_array(struct nouveau_array *a, int attr, int stride, | |||
int fields, int type, struct gl_buffer_object *obj, | |||
const void *ptr, GLboolean map) | |||
{ | |||
a->attr = attr; | |||
a->stride = stride; | |||
a->fields = fields; | |||
a->type = type; | |||
a->buf = NULL; | |||
if (obj) { | |||
if (_mesa_is_bufferobj(obj)) { | |||
struct nouveau_bufferobj *nbo = | |||
to_nouveau_bufferobj(obj); | |||
nouveau_bo_ref(nbo->bo, &a->bo); | |||
a->offset = (intptr_t)ptr; | |||
if (map) { | |||
nouveau_bo_map(a->bo, NOUVEAU_BO_RD); | |||
a->buf = a->bo->map + a->offset; | |||
} | |||
} else { | |||
nouveau_bo_ref(NULL, &a->bo); | |||
a->offset = 0; | |||
if (map) | |||
a->buf = ptr; | |||
} | |||
} | |||
if (a->buf) | |||
get_array_extract(a, &a->extract_u, &a->extract_f); | |||
} | |||
void | |||
nouveau_deinit_array(struct nouveau_array *a) | |||
{ | |||
if (a->bo) { | |||
if (a->bo->map) | |||
nouveau_bo_unmap(a->bo); | |||
} | |||
a->buf = NULL; | |||
a->fields = 0; | |||
} | |||
void | |||
nouveau_cleanup_array(struct nouveau_array *a) | |||
{ | |||
nouveau_deinit_array(a); | |||
nouveau_bo_ref(NULL, &a->bo); | |||
} |
@@ -0,0 +1,58 @@ | |||
/* | |||
* Copyright (C) 2009-2010 Francisco Jerez. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sublicense, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial | |||
* portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | |||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
*/ | |||
#ifndef __NOUVEAU_ARRAY_H__ | |||
#define __NOUVEAU_ARRAY_H__ | |||
struct nouveau_array; | |||
typedef unsigned (*extract_u_t)(struct nouveau_array *, int, int); | |||
typedef float (*extract_f_t)(struct nouveau_array *, int, int); | |||
struct nouveau_array { | |||
int attr; | |||
int stride, fields, type; | |||
struct nouveau_bo *bo; | |||
unsigned offset; | |||
const void *buf; | |||
extract_u_t extract_u; | |||
extract_f_t extract_f; | |||
}; | |||
void | |||
nouveau_init_array(struct nouveau_array *a, int attr, int stride, | |||
int fields, int type, struct gl_buffer_object *obj, | |||
const void *ptr, GLboolean map); | |||
void | |||
nouveau_deinit_array(struct nouveau_array *a); | |||
void | |||
nouveau_cleanup_array(struct nouveau_array *a); | |||
#endif |
@@ -28,31 +28,17 @@ | |||
#define __NOUVEAU_RENDER_H__ | |||
#include "vbo/vbo_context.h" | |||
struct nouveau_array_state; | |||
#include "nouveau_array.h" | |||
typedef void (*dispatch_t)(struct gl_context *, unsigned int, int, unsigned int); | |||
typedef unsigned (*extract_u_t)(struct nouveau_array_state *, int, int); | |||
typedef float (*extract_f_t)(struct nouveau_array_state *, int, int); | |||
typedef void (*emit_t)(struct gl_context *, struct nouveau_array *, const void *); | |||
struct nouveau_attr_info { | |||
int vbo_index; | |||
int imm_method; | |||
int imm_fields; | |||
void (*emit)(struct gl_context *, struct nouveau_array_state *, const void *); | |||
}; | |||
struct nouveau_array_state { | |||
int attr; | |||
int stride, fields, type; | |||
struct nouveau_bo *bo; | |||
unsigned offset; | |||
const void *buf; | |||
extract_u_t extract_u; | |||
extract_f_t extract_f; | |||
emit_t emit; | |||
}; | |||
struct nouveau_swtnl_state { | |||
@@ -69,8 +55,8 @@ struct nouveau_render_state { | |||
IMM | |||
} mode; | |||
struct nouveau_array_state ib; | |||
struct nouveau_array_state attrs[VERT_ATTRIB_MAX]; | |||
struct nouveau_array ib; | |||
struct nouveau_array attrs[VERT_ATTRIB_MAX]; | |||
/* Maps a HW VBO index or IMM emission order to an index in | |||
* the attrs array above (or -1 if unused). */ |
@@ -100,8 +100,8 @@ | |||
/* | |||
* Select an appropriate dispatch function for the given index buffer. | |||
*/ | |||
static void | |||
get_array_dispatch(struct nouveau_array_state *a, dispatch_t *dispatch) | |||
static dispatch_t | |||
get_array_dispatch(struct nouveau_array *a) | |||
{ | |||
if (!a->fields) { | |||
auto void f(struct gl_context *, unsigned int, int, unsigned int); | |||
@@ -114,7 +114,7 @@ get_array_dispatch(struct nouveau_array_state *a, dispatch_t *dispatch) | |||
EMIT_VBO(L, ctx, start, delta, n); | |||
}; | |||
*dispatch = f; | |||
return f; | |||
} else if (a->type == GL_UNSIGNED_INT) { | |||
auto void f(struct gl_context *, unsigned int, int, unsigned int); | |||
@@ -127,7 +127,7 @@ get_array_dispatch(struct nouveau_array_state *a, dispatch_t *dispatch) | |||
EMIT_VBO(I32, ctx, start, delta, n); | |||
}; | |||
*dispatch = f; | |||
return f; | |||
} else { | |||
auto void f(struct gl_context *, unsigned int, int, unsigned int); | |||
@@ -141,61 +141,7 @@ get_array_dispatch(struct nouveau_array_state *a, dispatch_t *dispatch) | |||
EMIT_VBO(I16, ctx, start, delta, n & ~1); | |||
}; | |||
*dispatch = f; | |||
} | |||
} | |||
/* | |||
* Select appropriate element extraction functions for the given | |||
* array. | |||
*/ | |||
static void | |||
get_array_extract(struct nouveau_array_state *a, | |||
extract_u_t *extract_u, extract_f_t *extract_f) | |||
{ | |||
#define EXTRACT(in_t, out_t, k) \ | |||
({ \ | |||
auto out_t f(struct nouveau_array_state *, int, int); \ | |||
out_t f(struct nouveau_array_state *a, int i, int j) { \ | |||
in_t x = ((in_t *)(a->buf + i * a->stride))[j]; \ | |||
\ | |||
return (out_t)x / (k); \ | |||
}; \ | |||
f; \ | |||
}); | |||
switch (a->type) { | |||
case GL_BYTE: | |||
*extract_u = EXTRACT(char, unsigned, 1); | |||
*extract_f = EXTRACT(char, float, SCHAR_MAX); | |||
break; | |||
case GL_UNSIGNED_BYTE: | |||
*extract_u = EXTRACT(unsigned char, unsigned, 1); | |||
*extract_f = EXTRACT(unsigned char, float, UCHAR_MAX); | |||
break; | |||
case GL_SHORT: | |||
*extract_u = EXTRACT(short, unsigned, 1); | |||
*extract_f = EXTRACT(short, float, SHRT_MAX); | |||
break; | |||
case GL_UNSIGNED_SHORT: | |||
*extract_u = EXTRACT(unsigned short, unsigned, 1); | |||
*extract_f = EXTRACT(unsigned short, float, USHRT_MAX); | |||
break; | |||
case GL_INT: | |||
*extract_u = EXTRACT(int, unsigned, 1); | |||
*extract_f = EXTRACT(int, float, INT_MAX); | |||
break; | |||
case GL_UNSIGNED_INT: | |||
*extract_u = EXTRACT(unsigned int, unsigned, 1); | |||
*extract_f = EXTRACT(unsigned int, float, UINT_MAX); | |||
break; | |||
case GL_FLOAT: | |||
*extract_u = EXTRACT(float, unsigned, 1.0 / UINT_MAX); | |||
*extract_f = EXTRACT(float, float, 1); | |||
break; | |||
default: | |||
assert(0); | |||
return f; | |||
} | |||
} | |||
@@ -240,7 +186,7 @@ get_max_vertices(struct gl_context *ctx, const struct _mesa_index_buffer *ib, | |||
#include "nouveau_swtnl_t.c" | |||
static void | |||
TAG(emit_material)(struct gl_context *ctx, struct nouveau_array_state *a, | |||
TAG(emit_material)(struct gl_context *ctx, struct nouveau_array *a, | |||
const void *v) | |||
{ | |||
const int attr = a->attr - VERT_ATTRIB_GENERIC0; |
@@ -118,7 +118,7 @@ swtnl_choose_attrs(struct gl_context *ctx) | |||
for (i = 0; i < VERT_ATTRIB_MAX; i++) { | |||
struct nouveau_attr_info *ha = &TAG(vertex_attrs)[i]; | |||
struct swtnl_attr_info *sa = &swtnl_attrs[i]; | |||
struct nouveau_array_state *a = &render->attrs[i]; | |||
struct nouveau_array *a = &render->attrs[i]; | |||
if (!sa->fields) | |||
continue; /* Unsupported attribute. */ | |||
@@ -165,14 +165,15 @@ swtnl_bind_vertices(struct gl_context *ctx) | |||
{ | |||
struct nouveau_render_state *render = to_render_state(ctx); | |||
struct nouveau_swtnl_state *swtnl = &render->swtnl; | |||
struct tnl_clipspace *vtx = &TNL_CONTEXT(ctx)->clipspace; | |||
int i; | |||
for (i = 0; i < render->attr_count; i++) { | |||
int attr = render->map[i]; | |||
for (i = 0; i < vtx->attr_count; i++) { | |||
struct tnl_clipspace_attr *ta = &vtx->attr[i]; | |||
struct nouveau_array *a = &render->attrs[ta->attrib]; | |||
if (attr >= 0) | |||
nouveau_bo_ref(swtnl->vbo, | |||
&render->attrs[attr].bo); | |||
nouveau_bo_ref(swtnl->vbo, &a->bo); | |||
a->offset = swtnl->offset + ta->vertoffset; | |||
} | |||
TAG(render_bind_vertices)(ctx); |
@@ -31,59 +31,11 @@ | |||
#include "main/image.h" | |||
/* Arbitrary pushbuf length we can assume we can get with a single | |||
* WAIT_RING. */ | |||
* call to WAIT_RING. */ | |||
#define PUSHBUF_DWORDS 65536 | |||
/* Functions to set up struct nouveau_array_state from something like | |||
* a GL array or index buffer. */ | |||
static void | |||
vbo_init_array(struct nouveau_array_state *a, int attr, int stride, | |||
int fields, int type, struct gl_buffer_object *obj, | |||
const void *ptr, GLboolean map) | |||
{ | |||
a->attr = attr; | |||
a->stride = stride; | |||
a->fields = fields; | |||
a->type = type; | |||
if (_mesa_is_bufferobj(obj)) { | |||
nouveau_bo_ref(to_nouveau_bufferobj(obj)->bo, &a->bo); | |||
a->offset = (intptr_t)ptr; | |||
if (map) { | |||
nouveau_bo_map(a->bo, NOUVEAU_BO_RD); | |||
a->buf = a->bo->map + a->offset; | |||
} else { | |||
a->buf = NULL; | |||
} | |||
} else { | |||
nouveau_bo_ref(NULL, &a->bo); | |||
a->offset = 0; | |||
if (map) | |||
a->buf = ptr; | |||
else | |||
a->buf = NULL; | |||
} | |||
if (a->buf) | |||
get_array_extract(a, &a->extract_u, &a->extract_f); | |||
} | |||
static void | |||
vbo_deinit_array(struct nouveau_array_state *a) | |||
{ | |||
if (a->bo) { | |||
if (a->bo->map) | |||
nouveau_bo_unmap(a->bo); | |||
nouveau_bo_ref(NULL, &a->bo); | |||
} | |||
a->buf = NULL; | |||
a->fields = 0; | |||
} | |||
/* Functions to turn GL arrays or index buffers into nouveau_array | |||
* structures. */ | |||
static int | |||
get_array_stride(struct gl_context *ctx, const struct gl_client_array *a) | |||
@@ -106,17 +58,17 @@ vbo_init_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib, | |||
int i, attr; | |||
if (ib) | |||
vbo_init_array(&render->ib, 0, 0, ib->count, ib->type, | |||
ib->obj, ib->ptr, GL_TRUE); | |||
nouveau_init_array(&render->ib, 0, 0, ib->count, ib->type, | |||
ib->obj, ib->ptr, GL_TRUE); | |||
FOR_EACH_BOUND_ATTR(render, i, attr) { | |||
const struct gl_client_array *array = arrays[attr]; | |||
vbo_init_array(&render->attrs[attr], attr, | |||
get_array_stride(ctx, array), | |||
array->Size, array->Type, | |||
array->BufferObj, | |||
array->Ptr, imm); | |||
nouveau_init_array(&render->attrs[attr], attr, | |||
get_array_stride(ctx, array), | |||
array->Size, array->Type, | |||
array->BufferObj, | |||
array->Ptr, imm); | |||
} | |||
} | |||
@@ -128,12 +80,12 @@ vbo_deinit_arrays(struct gl_context *ctx, const struct _mesa_index_buffer *ib, | |||
int i, attr; | |||
if (ib) | |||
vbo_deinit_array(&render->ib); | |||
nouveau_cleanup_array(&render->ib); | |||
FOR_EACH_BOUND_ATTR(render, i, attr) { | |||
struct nouveau_array_state *a = &render->attrs[attr]; | |||
struct nouveau_array *a = &render->attrs[attr]; | |||
vbo_deinit_array(a); | |||
nouveau_deinit_array(a); | |||
render->map[i] = -1; | |||
} | |||
@@ -162,12 +114,13 @@ vbo_choose_render_mode(struct gl_context *ctx, const struct gl_client_array **ar | |||
} | |||
static void | |||
vbo_emit_attr(struct gl_context *ctx, const struct gl_client_array **arrays, int attr) | |||
vbo_emit_attr(struct gl_context *ctx, const struct gl_client_array **arrays, | |||
int attr) | |||
{ | |||
struct nouveau_channel *chan = context_chan(ctx); | |||
struct nouveau_render_state *render = to_render_state(ctx); | |||
const struct gl_client_array *array = arrays[attr]; | |||
struct nouveau_array_state *a = &render->attrs[attr]; | |||
struct nouveau_array *a = &render->attrs[attr]; | |||
RENDER_LOCALS(ctx); | |||
if (!array->StrideB) { | |||
@@ -176,11 +129,11 @@ vbo_emit_attr(struct gl_context *ctx, const struct gl_client_array **arrays, int | |||
return; | |||
/* Constant attribute. */ | |||
vbo_init_array(a, attr, array->StrideB, array->Size, | |||
array->Type, array->BufferObj, array->Ptr, | |||
GL_TRUE); | |||
nouveau_init_array(a, attr, array->StrideB, array->Size, | |||
array->Type, array->BufferObj, array->Ptr, | |||
GL_TRUE); | |||
EMIT_IMM(ctx, a, 0); | |||
vbo_deinit_array(a); | |||
nouveau_deinit_array(a); | |||
} else { | |||
/* Varying attribute. */ | |||
@@ -314,7 +267,7 @@ vbo_bind_vertices(struct gl_context *ctx, const struct gl_client_array **arrays, | |||
FOR_EACH_BOUND_ATTR(render, i, attr) { | |||
const struct gl_client_array *array = arrays[attr]; | |||
struct nouveau_array_state *a = &render->attrs[attr]; | |||
struct nouveau_array *a = &render->attrs[attr]; | |||
unsigned delta = (basevertex + min_index) | |||
* array->StrideB; | |||
@@ -346,12 +299,10 @@ vbo_draw_vbo(struct gl_context *ctx, const struct gl_client_array **arrays, | |||
GLuint max_index) | |||
{ | |||
struct nouveau_channel *chan = context_chan(ctx); | |||
dispatch_t dispatch; | |||
int delta = -min_index, basevertex = 0, i; | |||
dispatch_t dispatch = get_array_dispatch(&to_render_state(ctx)->ib); | |||
int i, delta = -min_index, basevertex = 0; | |||
RENDER_LOCALS(ctx); | |||
get_array_dispatch(&to_render_state(ctx)->ib, &dispatch); | |||
TAG(render_set_format)(ctx); | |||
for (i = 0; i < nr_prims; i++) { | |||
@@ -376,7 +327,7 @@ vbo_draw_vbo(struct gl_context *ctx, const struct gl_client_array **arrays, | |||
/* Immediate rendering path. */ | |||
static unsigned | |||
extract_id(struct nouveau_array_state *a, int i, int j) | |||
extract_id(struct nouveau_array *a, int i, int j) | |||
{ | |||
return j; | |||
} | |||
@@ -418,7 +369,8 @@ vbo_draw_imm(struct gl_context *ctx, const struct gl_client_array **arrays, | |||
/* draw_prims entry point when we're doing hw-tnl. */ | |||
static void | |||
TAG(vbo_render_prims)(struct gl_context *ctx, const struct gl_client_array **arrays, | |||
TAG(vbo_render_prims)(struct gl_context *ctx, | |||
const struct gl_client_array **arrays, | |||
const struct _mesa_prim *prims, GLuint nr_prims, | |||
const struct _mesa_index_buffer *ib, | |||
GLboolean index_bounds_valid, |
@@ -32,7 +32,7 @@ | |||
#define NUM_VERTEX_ATTRS 8 | |||
static void | |||
nv10_emit_material(struct gl_context *ctx, struct nouveau_array_state *a, | |||
nv10_emit_material(struct gl_context *ctx, struct nouveau_array *a, | |||
const void *v); | |||
/* Vertex attribute format. */ | |||
@@ -115,7 +115,7 @@ nv10_render_set_format(struct gl_context *ctx) | |||
FOR_EACH_ATTR(render, i, attr) { | |||
if (attr >= 0) { | |||
struct nouveau_array_state *a = &render->attrs[attr]; | |||
struct nouveau_array *a = &render->attrs[attr]; | |||
hw_format = a->stride << 8 | | |||
a->fields << 4 | | |||
@@ -143,7 +143,7 @@ nv10_render_bind_vertices(struct gl_context *ctx) | |||
int i, attr; | |||
FOR_EACH_BOUND_ATTR(render, i, attr) { | |||
struct nouveau_array_state *a = &render->attrs[attr]; | |||
struct nouveau_array *a = &render->attrs[attr]; | |||
nouveau_bo_markl(bctx, celsius, | |||
NV10TCL_VTXBUF_ADDRESS(i), |
@@ -32,7 +32,7 @@ | |||
#define NUM_VERTEX_ATTRS 16 | |||
static void | |||
nv20_emit_material(struct gl_context *ctx, struct nouveau_array_state *a, | |||
nv20_emit_material(struct gl_context *ctx, struct nouveau_array *a, | |||
const void *v); | |||
/* Vertex attribute format. */ | |||
@@ -139,7 +139,7 @@ nv20_render_set_format(struct gl_context *ctx) | |||
FOR_EACH_ATTR(render, i, attr) { | |||
if (attr >= 0) { | |||
struct nouveau_array_state *a = &render->attrs[attr]; | |||
struct nouveau_array *a = &render->attrs[attr]; | |||
hw_format = a->stride << 8 | | |||
a->fields << 4 | | |||
@@ -165,7 +165,7 @@ nv20_render_bind_vertices(struct gl_context *ctx) | |||
int i, attr; | |||
FOR_EACH_BOUND_ATTR(render, i, attr) { | |||
struct nouveau_array_state *a = &render->attrs[attr]; | |||
struct nouveau_array *a = &render->attrs[attr]; | |||
nouveau_bo_mark(bctx, kelvin, | |||
NV20TCL_VTXBUF_ADDRESS(i), |