dri/nouveau: Split out array handling to its own file.

This commit is contained in:
Francisco Jerez 2010-10-29 22:31:34 +02:00
parent 9d1f1fcf13
commit 57382e71ef
9 changed files with 244 additions and 165 deletions

View file

@ -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 \

View file

@ -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);
}

View file

@ -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

View file

@ -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). */

View file

@ -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;

View file

@ -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);

View file

@ -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,

View file

@ -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),

View file

@ -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),