浏览代码

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

tags/snb-magic
Francisco Jerez 15 年前
父节点
当前提交
57382e71ef

+ 1
- 0
src/mesa/drivers/dri/nouveau/Makefile 查看文件

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

+ 135
- 0
src/mesa/drivers/dri/nouveau/nouveau_array.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);
}

+ 58
- 0
src/mesa/drivers/dri/nouveau/nouveau_array.h 查看文件

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

+ 5
- 19
src/mesa/drivers/dri/nouveau/nouveau_render.h 查看文件

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

+ 6
- 60
src/mesa/drivers/dri/nouveau/nouveau_render_t.c 查看文件

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

+ 7
- 6
src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c 查看文件

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

+ 26
- 74
src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c 查看文件

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

+ 3
- 3
src/mesa/drivers/dri/nouveau/nv10_render.c 查看文件

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

+ 3
- 3
src/mesa/drivers/dri/nouveau/nv20_render.c 查看文件

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

正在加载...
取消
保存