mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 18:10:11 +01:00
Merge commit 'fj/mesa-next'
This commit is contained in:
commit
c036d13d7d
118 changed files with 10856 additions and 8683 deletions
|
|
@ -1324,7 +1324,7 @@ AC_ARG_ENABLE([gallium-nouveau],
|
||||||
[enable_gallium_nouveau=no])
|
[enable_gallium_nouveau=no])
|
||||||
if test "x$enable_gallium_nouveau" = xyes; then
|
if test "x$enable_gallium_nouveau" = xyes; then
|
||||||
GALLIUM_WINSYS_DRM_DIRS="$GALLIUM_WINSYS_DRM_DIRS nouveau"
|
GALLIUM_WINSYS_DRM_DIRS="$GALLIUM_WINSYS_DRM_DIRS nouveau"
|
||||||
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nv04 nv10 nv20 nv30 nv40 nv50"
|
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nv30 nv40 nv50"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
|
|
|
||||||
|
|
@ -31,21 +31,6 @@ Wrapper driver.
|
||||||
LLVM Softpipe
|
LLVM Softpipe
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
nVidia nv04
|
|
||||||
^^^^^^^^^^^
|
|
||||||
|
|
||||||
Deprecated.
|
|
||||||
|
|
||||||
nVidia nv10
|
|
||||||
^^^^^^^^^^^
|
|
||||||
|
|
||||||
Deprecated.
|
|
||||||
|
|
||||||
nVidia nv20
|
|
||||||
^^^^^^^^^^^
|
|
||||||
|
|
||||||
Deprecated.
|
|
||||||
|
|
||||||
nVidia nv30
|
nVidia nv30
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ include $(TOP)/configs/current
|
||||||
LIBNAME = nouveau
|
LIBNAME = nouveau
|
||||||
|
|
||||||
C_SOURCES = nouveau_screen.c \
|
C_SOURCES = nouveau_screen.c \
|
||||||
nouveau_context.c
|
nouveau_context.c \
|
||||||
|
nv04_surface_2d.c
|
||||||
|
|
||||||
include ../../Makefile.template
|
include ../../Makefile.template
|
||||||
|
|
|
||||||
|
|
@ -26,24 +26,6 @@
|
||||||
/* use along with GPU_WRITE for 2D-only writes */
|
/* use along with GPU_WRITE for 2D-only writes */
|
||||||
#define NOUVEAU_BUFFER_USAGE_NO_RENDER (1 << 19)
|
#define NOUVEAU_BUFFER_USAGE_NO_RENDER (1 << 19)
|
||||||
|
|
||||||
extern struct pipe_screen *
|
|
||||||
nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
|
|
||||||
|
|
||||||
extern struct pipe_context *
|
|
||||||
nv04_create(struct pipe_screen *, unsigned pctx_id);
|
|
||||||
|
|
||||||
extern struct pipe_screen *
|
|
||||||
nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
|
|
||||||
|
|
||||||
extern struct pipe_context *
|
|
||||||
nv10_create(struct pipe_screen *, unsigned pctx_id);
|
|
||||||
|
|
||||||
extern struct pipe_screen *
|
|
||||||
nv20_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
|
|
||||||
|
|
||||||
extern struct pipe_context *
|
|
||||||
nv20_create(struct pipe_screen *, unsigned pctx_id);
|
|
||||||
|
|
||||||
extern struct pipe_screen *
|
extern struct pipe_screen *
|
||||||
nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
|
nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
TOP = ../../../..
|
|
||||||
include $(TOP)/configs/current
|
|
||||||
|
|
||||||
LIBNAME = nv04
|
|
||||||
|
|
||||||
C_SOURCES = \
|
|
||||||
nv04_surface_2d.c \
|
|
||||||
nv04_clear.c \
|
|
||||||
nv04_context.c \
|
|
||||||
nv04_fragprog.c \
|
|
||||||
nv04_fragtex.c \
|
|
||||||
nv04_miptree.c \
|
|
||||||
nv04_prim_vbuf.c \
|
|
||||||
nv04_screen.c \
|
|
||||||
nv04_state.c \
|
|
||||||
nv04_state_emit.c \
|
|
||||||
nv04_surface.c \
|
|
||||||
nv04_transfer.c \
|
|
||||||
nv04_vbo.c
|
|
||||||
|
|
||||||
include ../../Makefile.template
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
|
|
||||||
#include "nv04_context.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_clear(struct pipe_context *pipe, struct pipe_surface *ps,
|
|
||||||
unsigned clearValue)
|
|
||||||
{
|
|
||||||
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
|
|
||||||
}
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
#include "draw/draw_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "util/u_simple_screen.h"
|
|
||||||
|
|
||||||
#include "nv04_context.h"
|
|
||||||
#include "nv04_screen.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_flush(struct pipe_context *pipe, unsigned flags,
|
|
||||||
struct pipe_fence_handle **fence)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
|
|
||||||
draw_flush(nv04->draw);
|
|
||||||
|
|
||||||
FIRE_RING(chan);
|
|
||||||
if (fence)
|
|
||||||
*fence = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_destroy(struct pipe_context *pipe)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
if (nv04->draw)
|
|
||||||
draw_destroy(nv04->draw);
|
|
||||||
|
|
||||||
FREE(nv04);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv04_init_hwctx(struct nv04_context *nv04)
|
|
||||||
{
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
|
|
||||||
// requires a valid handle
|
|
||||||
// BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_NOTIFY, 1);
|
|
||||||
// OUT_RING(0);
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_NOP, 1);
|
|
||||||
OUT_RING(chan, 0);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1);
|
|
||||||
OUT_RING(chan, 0x40182800);
|
|
||||||
// OUT_RING(1<<20/*no cull*/);
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1);
|
|
||||||
// OUT_RING(0x24|(1<<6)|(1<<8));
|
|
||||||
OUT_RING(chan, 0x120001a4);
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FORMAT, 1);
|
|
||||||
OUT_RING(chan, 0x332213a1);
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1);
|
|
||||||
OUT_RING(chan, 0x11001010);
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1);
|
|
||||||
OUT_RING(chan, 0x0);
|
|
||||||
// BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 1);
|
|
||||||
// OUT_RING(SCREEN_OFFSET);
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FOGCOLOR, 1);
|
|
||||||
OUT_RING(chan, 0xff000000);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FIRE_RING (chan);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pipe_context *
|
|
||||||
nv04_create(struct pipe_screen *pscreen, unsigned pctx_id)
|
|
||||||
{
|
|
||||||
struct nv04_screen *screen = nv04_screen(pscreen);
|
|
||||||
struct pipe_winsys *ws = pscreen->winsys;
|
|
||||||
struct nv04_context *nv04;
|
|
||||||
struct nouveau_winsys *nvws = screen->nvws;
|
|
||||||
|
|
||||||
nv04 = CALLOC(1, sizeof(struct nv04_context));
|
|
||||||
if (!nv04)
|
|
||||||
return NULL;
|
|
||||||
nv04->screen = screen;
|
|
||||||
nv04->pctx_id = pctx_id;
|
|
||||||
|
|
||||||
nv04->nvws = nvws;
|
|
||||||
|
|
||||||
nv04->pipe.winsys = ws;
|
|
||||||
nv04->pipe.screen = pscreen;
|
|
||||||
nv04->pipe.destroy = nv04_destroy;
|
|
||||||
nv04->pipe.draw_arrays = nv04_draw_arrays;
|
|
||||||
nv04->pipe.draw_elements = nv04_draw_elements;
|
|
||||||
nv04->pipe.clear = nv04_clear;
|
|
||||||
nv04->pipe.flush = nv04_flush;
|
|
||||||
|
|
||||||
nv04->pipe.is_texture_referenced = nouveau_is_texture_referenced;
|
|
||||||
nv04->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
|
|
||||||
|
|
||||||
nv04_init_surface_functions(nv04);
|
|
||||||
nv04_init_state_functions(nv04);
|
|
||||||
|
|
||||||
nv04->draw = draw_create();
|
|
||||||
assert(nv04->draw);
|
|
||||||
draw_wide_point_threshold(nv04->draw, 0.0);
|
|
||||||
draw_wide_line_threshold(nv04->draw, 0.0);
|
|
||||||
draw_enable_line_stipple(nv04->draw, FALSE);
|
|
||||||
draw_enable_point_sprites(nv04->draw, FALSE);
|
|
||||||
draw_set_rasterize_stage(nv04->draw, nv04_draw_vbuf_stage(nv04));
|
|
||||||
|
|
||||||
nv04_init_hwctx(nv04);
|
|
||||||
|
|
||||||
return &nv04->pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,151 +0,0 @@
|
||||||
#ifndef __NV04_CONTEXT_H__
|
|
||||||
#define __NV04_CONTEXT_H__
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "pipe/p_compiler.h"
|
|
||||||
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "draw/draw_vertex.h"
|
|
||||||
|
|
||||||
#include "nouveau/nouveau_winsys.h"
|
|
||||||
#include "nouveau/nouveau_gldefs.h"
|
|
||||||
#include "nouveau/nouveau_context.h"
|
|
||||||
|
|
||||||
#include "nv04_state.h"
|
|
||||||
|
|
||||||
#define NOUVEAU_ERR(fmt, args...) \
|
|
||||||
fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args);
|
|
||||||
#define NOUVEAU_MSG(fmt, args...) \
|
|
||||||
fprintf(stderr, "nouveau: "fmt, ##args);
|
|
||||||
|
|
||||||
#include "nv04_screen.h"
|
|
||||||
|
|
||||||
#define NV04_NEW_VERTPROG (1 << 1)
|
|
||||||
#define NV04_NEW_FRAGPROG (1 << 2)
|
|
||||||
#define NV04_NEW_BLEND (1 << 3)
|
|
||||||
#define NV04_NEW_RAST (1 << 4)
|
|
||||||
#define NV04_NEW_CONTROL (1 << 5)
|
|
||||||
#define NV04_NEW_VIEWPORT (1 << 6)
|
|
||||||
#define NV04_NEW_SAMPLER (1 << 7)
|
|
||||||
#define NV04_NEW_FRAMEBUFFER (1 << 8)
|
|
||||||
#define NV04_NEW_VTXARRAYS (1 << 9)
|
|
||||||
|
|
||||||
struct nv04_context {
|
|
||||||
struct pipe_context pipe;
|
|
||||||
|
|
||||||
struct nouveau_winsys *nvws;
|
|
||||||
struct nv04_screen *screen;
|
|
||||||
unsigned pctx_id;
|
|
||||||
|
|
||||||
struct draw_context *draw;
|
|
||||||
|
|
||||||
int chipset;
|
|
||||||
struct nouveau_notifier *sync;
|
|
||||||
|
|
||||||
uint32_t dirty;
|
|
||||||
|
|
||||||
struct nv04_blend_state *blend;
|
|
||||||
struct nv04_sampler_state *sampler[PIPE_MAX_SAMPLERS];
|
|
||||||
struct nv04_fragtex_state fragtex;
|
|
||||||
struct nv04_rasterizer_state *rast;
|
|
||||||
struct nv04_depth_stencil_alpha_state *dsa;
|
|
||||||
|
|
||||||
struct nv04_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
|
|
||||||
unsigned dirty_samplers;
|
|
||||||
unsigned fp_samplers;
|
|
||||||
unsigned vp_samplers;
|
|
||||||
|
|
||||||
uint32_t rt_enable;
|
|
||||||
struct pipe_framebuffer_state *framebuffer;
|
|
||||||
struct pipe_surface *rt;
|
|
||||||
struct pipe_surface *zeta;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
uint32_t format;
|
|
||||||
} tex[16];
|
|
||||||
|
|
||||||
unsigned vb_enable;
|
|
||||||
struct {
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
unsigned delta;
|
|
||||||
} vb[16];
|
|
||||||
|
|
||||||
float *constbuf[PIPE_SHADER_TYPES][32][4];
|
|
||||||
unsigned constbuf_nr[PIPE_SHADER_TYPES];
|
|
||||||
|
|
||||||
struct vertex_info vertex_info;
|
|
||||||
struct {
|
|
||||||
|
|
||||||
struct nouveau_resource *exec_heap;
|
|
||||||
struct nouveau_resource *data_heap;
|
|
||||||
|
|
||||||
struct nv04_vertex_program *active;
|
|
||||||
|
|
||||||
struct nv04_vertex_program *current;
|
|
||||||
struct pipe_buffer *constant_buf;
|
|
||||||
} vertprog;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct nv04_fragment_program *active;
|
|
||||||
|
|
||||||
struct nv04_fragment_program *current;
|
|
||||||
struct pipe_buffer *constant_buf;
|
|
||||||
} fragprog;
|
|
||||||
|
|
||||||
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
|
|
||||||
struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
|
|
||||||
|
|
||||||
struct pipe_viewport_state viewport;
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE struct nv04_context *
|
|
||||||
nv04_context(struct pipe_context *pipe)
|
|
||||||
{
|
|
||||||
return (struct nv04_context *)pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void nv04_init_state_functions(struct nv04_context *nv04);
|
|
||||||
extern void nv04_init_surface_functions(struct nv04_context *nv04);
|
|
||||||
extern void nv04_screen_init_miptree_functions(struct pipe_screen *screen);
|
|
||||||
|
|
||||||
/* nv04_clear.c */
|
|
||||||
extern void nv04_clear(struct pipe_context *pipe, struct pipe_surface *ps,
|
|
||||||
unsigned clearValue);
|
|
||||||
|
|
||||||
/* nv04_draw.c */
|
|
||||||
extern struct draw_stage *nv04_draw_render_stage(struct nv04_context *nv04);
|
|
||||||
|
|
||||||
/* nv04_fragprog.c */
|
|
||||||
extern void nv04_fragprog_bind(struct nv04_context *,
|
|
||||||
struct nv04_fragment_program *);
|
|
||||||
extern void nv04_fragprog_destroy(struct nv04_context *,
|
|
||||||
struct nv04_fragment_program *);
|
|
||||||
|
|
||||||
/* nv04_fragtex.c */
|
|
||||||
extern void nv04_fragtex_bind(struct nv04_context *);
|
|
||||||
|
|
||||||
/* nv04_prim_vbuf.c */
|
|
||||||
struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 );
|
|
||||||
|
|
||||||
/* nv04_state.c and friends */
|
|
||||||
extern void nv04_emit_hw_state(struct nv04_context *nv04);
|
|
||||||
extern void nv04_state_tex_update(struct nv04_context *nv04);
|
|
||||||
|
|
||||||
/* nv04_vbo.c */
|
|
||||||
extern void nv04_draw_arrays(struct pipe_context *, unsigned mode,
|
|
||||||
unsigned start, unsigned count);
|
|
||||||
extern void nv04_draw_elements( struct pipe_context *pipe,
|
|
||||||
struct pipe_buffer *indexBuffer,
|
|
||||||
unsigned indexSize,
|
|
||||||
unsigned prim, unsigned start, unsigned count);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
|
|
||||||
#include "pipe/p_shader_tokens.h"
|
|
||||||
#include "tgsi/tgsi_parse.h"
|
|
||||||
#include "tgsi/tgsi_util.h"
|
|
||||||
|
|
||||||
#include "nv04_context.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_fragprog_bind(struct nv04_context *nv04, struct nv04_fragment_program *fp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_fragprog_destroy(struct nv04_context *nv04,
|
|
||||||
struct nv04_fragment_program *fp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
#include "nv04_context.h"
|
|
||||||
#include "nouveau/nouveau_util.h"
|
|
||||||
|
|
||||||
#define _(m,tf) \
|
|
||||||
{ \
|
|
||||||
PIPE_FORMAT_##m, \
|
|
||||||
NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_##tf, \
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nv04_texture_format {
|
|
||||||
uint pipe;
|
|
||||||
int format;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct nv04_texture_format
|
|
||||||
nv04_texture_formats[] = {
|
|
||||||
_(A8R8G8B8_UNORM, A8R8G8B8),
|
|
||||||
_(X8R8G8B8_UNORM, X8R8G8B8),
|
|
||||||
_(A1R5G5B5_UNORM, A1R5G5B5),
|
|
||||||
_(A4R4G4B4_UNORM, A4R4G4B4),
|
|
||||||
_(L8_UNORM, Y8 ),
|
|
||||||
_(A8_UNORM, Y8 ),
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint32_t
|
|
||||||
nv04_fragtex_format(uint pipe_format)
|
|
||||||
{
|
|
||||||
struct nv04_texture_format *tf = nv04_texture_formats;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i< sizeof(nv04_texture_formats)/sizeof(nv04_texture_formats[0]); i++) {
|
|
||||||
if (tf->pipe == pipe_format)
|
|
||||||
return tf->format;
|
|
||||||
tf++;
|
|
||||||
}
|
|
||||||
|
|
||||||
NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_fragtex_build(struct nv04_context *nv04, int unit)
|
|
||||||
{
|
|
||||||
struct nv04_miptree *nv04mt = nv04->tex_miptree[unit];
|
|
||||||
struct pipe_texture *pt = &nv04mt->base;
|
|
||||||
|
|
||||||
switch (pt->target) {
|
|
||||||
case PIPE_TEXTURE_2D:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("Unknown target %d\n", pt->target);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nv04->fragtex.format = NV04_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CORNER
|
|
||||||
| NV04_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER
|
|
||||||
| nv04_fragtex_format(pt->format)
|
|
||||||
| ( (pt->last_level + 1) << NV04_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT )
|
|
||||||
| ( log2i(pt->width0) << NV04_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT )
|
|
||||||
| ( log2i(pt->height0) << NV04_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT )
|
|
||||||
| NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE
|
|
||||||
| NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_EDGE
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_fragtex_bind(struct nv04_context *nv04)
|
|
||||||
{
|
|
||||||
nv04_fragtex_build(nv04, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
|
|
||||||
#include "nv04_context.h"
|
|
||||||
#include "nv04_screen.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_miptree_layout(struct nv04_miptree *nv04mt)
|
|
||||||
{
|
|
||||||
struct pipe_texture *pt = &nv04mt->base;
|
|
||||||
uint offset = 0;
|
|
||||||
int nr_faces, l;
|
|
||||||
|
|
||||||
nr_faces = 1;
|
|
||||||
|
|
||||||
for (l = 0; l <= pt->last_level; l++) {
|
|
||||||
nv04mt->level[l].pitch = pt->width0;
|
|
||||||
nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (l = 0; l <= pt->last_level; l++) {
|
|
||||||
nv04mt->level[l].image_offset =
|
|
||||||
CALLOC(nr_faces, sizeof(unsigned));
|
|
||||||
/* XXX guess was obviously missing */
|
|
||||||
nv04mt->level[l].image_offset[0] = offset;
|
|
||||||
offset += nv04mt->level[l].pitch * u_minify(pt->height0, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
nv04mt->total_size = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_texture *
|
|
||||||
nv04_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
|
|
||||||
{
|
|
||||||
struct nv04_miptree *mt;
|
|
||||||
|
|
||||||
mt = MALLOC(sizeof(struct nv04_miptree));
|
|
||||||
if (!mt)
|
|
||||||
return NULL;
|
|
||||||
mt->base = *pt;
|
|
||||||
pipe_reference_init(&mt->base.reference, 1);
|
|
||||||
mt->base.screen = pscreen;
|
|
||||||
|
|
||||||
//mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
|
|
||||||
nv04_miptree_layout(mt);
|
|
||||||
|
|
||||||
mt->buffer = pscreen->buffer_create(pscreen, 256, PIPE_BUFFER_USAGE_PIXEL |
|
|
||||||
NOUVEAU_BUFFER_USAGE_TEXTURE,
|
|
||||||
mt->total_size);
|
|
||||||
if (!mt->buffer) {
|
|
||||||
printf("failed %d byte alloc\n",mt->total_size);
|
|
||||||
FREE(mt);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
mt->bo = nouveau_bo(mt->buffer);
|
|
||||||
return &mt->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_texture *
|
|
||||||
nv04_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
|
|
||||||
const unsigned *stride, struct pipe_buffer *pb)
|
|
||||||
{
|
|
||||||
struct nv04_miptree *mt;
|
|
||||||
|
|
||||||
/* Only supports 2D, non-mipmapped textures for the moment */
|
|
||||||
if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
|
|
||||||
pt->depth0 != 1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mt = CALLOC_STRUCT(nv04_miptree);
|
|
||||||
if (!mt)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mt->base = *pt;
|
|
||||||
pipe_reference_init(&mt->base.reference, 1);
|
|
||||||
mt->base.screen = pscreen;
|
|
||||||
mt->level[0].pitch = stride[0];
|
|
||||||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
|
|
||||||
|
|
||||||
pipe_buffer_reference(&mt->buffer, pb);
|
|
||||||
mt->bo = nouveau_bo(mt->buffer);
|
|
||||||
return &mt->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_miptree_destroy(struct pipe_texture *pt)
|
|
||||||
{
|
|
||||||
struct nv04_miptree *mt = (struct nv04_miptree *)pt;
|
|
||||||
int l;
|
|
||||||
|
|
||||||
pipe_buffer_reference(&mt->buffer, NULL);
|
|
||||||
for (l = 0; l <= pt->last_level; l++) {
|
|
||||||
if (mt->level[l].image_offset)
|
|
||||||
FREE(mt->level[l].image_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
FREE(mt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_surface *
|
|
||||||
nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
|
|
||||||
unsigned face, unsigned level, unsigned zslice,
|
|
||||||
unsigned flags)
|
|
||||||
{
|
|
||||||
struct nv04_miptree *nv04mt = (struct nv04_miptree *)pt;
|
|
||||||
struct nv04_surface *ns;
|
|
||||||
|
|
||||||
ns = CALLOC_STRUCT(nv04_surface);
|
|
||||||
if (!ns)
|
|
||||||
return NULL;
|
|
||||||
pipe_texture_reference(&ns->base.texture, pt);
|
|
||||||
ns->base.format = pt->format;
|
|
||||||
ns->base.width = u_minify(pt->width0, level);
|
|
||||||
ns->base.height = u_minify(pt->height0, level);
|
|
||||||
ns->base.usage = flags;
|
|
||||||
pipe_reference_init(&ns->base.reference, 1);
|
|
||||||
ns->base.face = face;
|
|
||||||
ns->base.level = level;
|
|
||||||
ns->base.zslice = zslice;
|
|
||||||
ns->pitch = nv04mt->level[level].pitch;
|
|
||||||
|
|
||||||
ns->base.offset = nv04mt->level[level].image_offset[0];
|
|
||||||
|
|
||||||
return &ns->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_miptree_surface_del(struct pipe_surface *ps)
|
|
||||||
{
|
|
||||||
pipe_texture_reference(&ps->texture, NULL);
|
|
||||||
FREE(ps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_screen_init_miptree_functions(struct pipe_screen *pscreen)
|
|
||||||
{
|
|
||||||
pscreen->texture_create = nv04_miptree_create;
|
|
||||||
pscreen->texture_blanket = nv04_miptree_blanket;
|
|
||||||
pscreen->texture_destroy = nv04_miptree_destroy;
|
|
||||||
pscreen->get_tex_surface = nv04_miptree_surface_new;
|
|
||||||
pscreen->tex_surface_destroy = nv04_miptree_surface_del;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,339 +0,0 @@
|
||||||
|
|
||||||
#include "util/u_debug.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_simple_screen.h"
|
|
||||||
#include "pipe/p_compiler.h"
|
|
||||||
|
|
||||||
#include "draw/draw_vbuf.h"
|
|
||||||
|
|
||||||
#include "nv04_context.h"
|
|
||||||
#include "nv04_state.h"
|
|
||||||
|
|
||||||
#define VERTEX_SIZE 40
|
|
||||||
#define VERTEX_BUFFER_SIZE (4096*VERTEX_SIZE) // 4096 vertices of 40 bytes each
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primitive renderer for nv04.
|
|
||||||
*/
|
|
||||||
struct nv04_vbuf_render {
|
|
||||||
struct vbuf_render base;
|
|
||||||
|
|
||||||
struct nv04_context *nv04;
|
|
||||||
|
|
||||||
/** Vertex buffer */
|
|
||||||
unsigned char* buffer;
|
|
||||||
|
|
||||||
/** Vertex size in bytes */
|
|
||||||
unsigned vertex_size;
|
|
||||||
|
|
||||||
/** Current primitive */
|
|
||||||
unsigned prim;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basically a cast wrapper.
|
|
||||||
*/
|
|
||||||
static INLINE struct nv04_vbuf_render *
|
|
||||||
nv04_vbuf_render( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
assert(render);
|
|
||||||
return (struct nv04_vbuf_render *)render;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const struct vertex_info *
|
|
||||||
nv04_vbuf_render_get_vertex_info( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
|
||||||
struct nv04_context *nv04 = nv04_render->nv04;
|
|
||||||
return &nv04->vertex_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv04_vbuf_render_allocate_vertices( struct vbuf_render *render,
|
|
||||||
ushort vertex_size,
|
|
||||||
ushort nr_vertices )
|
|
||||||
{
|
|
||||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
|
||||||
|
|
||||||
nv04_render->buffer = (unsigned char*) MALLOC(VERTEX_BUFFER_SIZE);
|
|
||||||
assert(!nv04_render->buffer);
|
|
||||||
|
|
||||||
return nv04_render->buffer ? TRUE : FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv04_vbuf_render_map_vertices( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
|
||||||
return nv04_render->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_vbuf_render_unmap_vertices( struct vbuf_render *render,
|
|
||||||
ushort min_index,
|
|
||||||
ushort max_index )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv04_vbuf_render_set_primitive( struct vbuf_render *render,
|
|
||||||
unsigned prim )
|
|
||||||
{
|
|
||||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
|
||||||
|
|
||||||
if (prim <= PIPE_PRIM_LINE_STRIP)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
nv04_render->prim = prim;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void nv04_2triangles(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5)
|
|
||||||
{
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA), 49);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v3,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v4,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v5,8);
|
|
||||||
OUT_RING(chan, 0xFEDCBA);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void nv04_1triangle(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2)
|
|
||||||
{
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD), 25);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8);
|
|
||||||
OUT_RING(chan, 0xFED);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void nv04_1quad(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3)
|
|
||||||
{
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC), 33);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * v3,8);
|
|
||||||
OUT_RING(chan, 0xFECEDC);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv04_vbuf_render_triangles_elts(struct nv04_vbuf_render * render, const ushort * indices, uint nr_indices)
|
|
||||||
{
|
|
||||||
unsigned char* buffer = render->buffer;
|
|
||||||
struct nv04_context* nv04 = render->nv04;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for( i=0; i< nr_indices-5; i+=6)
|
|
||||||
nv04_2triangles(nv04,
|
|
||||||
buffer,
|
|
||||||
indices[i+0],
|
|
||||||
indices[i+1],
|
|
||||||
indices[i+2],
|
|
||||||
indices[i+3],
|
|
||||||
indices[i+4],
|
|
||||||
indices[i+5]
|
|
||||||
);
|
|
||||||
if (i != nr_indices)
|
|
||||||
{
|
|
||||||
nv04_1triangle(nv04,
|
|
||||||
buffer,
|
|
||||||
indices[i+0],
|
|
||||||
indices[i+1],
|
|
||||||
indices[i+2]
|
|
||||||
);
|
|
||||||
i+=3;
|
|
||||||
}
|
|
||||||
if (i != nr_indices)
|
|
||||||
NOUVEAU_ERR("Houston, we have lost some vertices\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv04_vbuf_render_tri_strip_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices)
|
|
||||||
{
|
|
||||||
const uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC};
|
|
||||||
unsigned char* buffer = render->buffer;
|
|
||||||
struct nv04_context *nv04 = render->nv04;
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
int i,j;
|
|
||||||
|
|
||||||
for(i = 0; i<nr_indices; i+=14)
|
|
||||||
{
|
|
||||||
int numvert = MIN2(16, nr_indices - i);
|
|
||||||
int numtri = numvert - 2;
|
|
||||||
if (numvert<3)
|
|
||||||
break;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), numvert*8);
|
|
||||||
for(j = 0; j<numvert; j++)
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * indices [i+j], 8 );
|
|
||||||
|
|
||||||
BEGIN_RING_NI(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), (numtri+1)/2 );
|
|
||||||
for(j = 0; j<numtri/2; j++ )
|
|
||||||
OUT_RING(chan, striptbl[j]);
|
|
||||||
if (numtri%2)
|
|
||||||
OUT_RING(chan, striptbl[numtri/2]&0xFFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv04_vbuf_render_tri_fan_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices)
|
|
||||||
{
|
|
||||||
const uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0};
|
|
||||||
unsigned char* buffer = render->buffer;
|
|
||||||
struct nv04_context *nv04 = render->nv04;
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
int i,j;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), 8);
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * indices[0], 8);
|
|
||||||
|
|
||||||
for(i = 1; i<nr_indices; i+=14)
|
|
||||||
{
|
|
||||||
int numvert=MIN2(15, nr_indices - i);
|
|
||||||
int numtri=numvert-2;
|
|
||||||
if (numvert < 3)
|
|
||||||
break;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1), numvert*8);
|
|
||||||
|
|
||||||
for(j=0;j<numvert;j++)
|
|
||||||
OUT_RINGp(chan, buffer + VERTEX_SIZE * indices[ i+j ], 8 );
|
|
||||||
|
|
||||||
BEGIN_RING_NI(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), (numtri+1)/2);
|
|
||||||
for(j = 0; j<numtri/2; j++)
|
|
||||||
OUT_RING(chan, fantbl[j]);
|
|
||||||
if (numtri%2)
|
|
||||||
OUT_RING(chan, fantbl[numtri/2]&0xFFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv04_vbuf_render_quads_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices)
|
|
||||||
{
|
|
||||||
unsigned char* buffer = render->buffer;
|
|
||||||
struct nv04_context* nv04 = render->nv04;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; i < nr_indices; i += 4)
|
|
||||||
nv04_1quad(nv04,
|
|
||||||
buffer,
|
|
||||||
indices[i+0],
|
|
||||||
indices[i+1],
|
|
||||||
indices[i+2],
|
|
||||||
indices[i+3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_vbuf_render_draw( struct vbuf_render *render,
|
|
||||||
const ushort *indices,
|
|
||||||
uint nr_indices)
|
|
||||||
{
|
|
||||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
|
||||||
|
|
||||||
// emit the indices
|
|
||||||
switch( nv04_render->prim )
|
|
||||||
{
|
|
||||||
case PIPE_PRIM_TRIANGLES:
|
|
||||||
nv04_vbuf_render_triangles_elts(nv04_render, indices, nr_indices);
|
|
||||||
break;
|
|
||||||
case PIPE_PRIM_QUAD_STRIP:
|
|
||||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
|
||||||
nv04_vbuf_render_tri_strip_elts(nv04_render, indices, nr_indices);
|
|
||||||
break;
|
|
||||||
case PIPE_PRIM_TRIANGLE_FAN:
|
|
||||||
case PIPE_PRIM_POLYGON:
|
|
||||||
nv04_vbuf_render_tri_fan_elts(nv04_render, indices, nr_indices);
|
|
||||||
break;
|
|
||||||
case PIPE_PRIM_QUADS:
|
|
||||||
nv04_vbuf_render_quads_elts(nv04_render, indices, nr_indices);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("You have to implement primitive %d, young padawan\n", nv04_render->prim);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_vbuf_render_release_vertices( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
|
||||||
|
|
||||||
free(nv04_render->buffer);
|
|
||||||
nv04_render->buffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_vbuf_render_destroy( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
|
||||||
FREE(nv04_render);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new primitive render.
|
|
||||||
*/
|
|
||||||
static struct vbuf_render *
|
|
||||||
nv04_vbuf_render_create( struct nv04_context *nv04 )
|
|
||||||
{
|
|
||||||
struct nv04_vbuf_render *nv04_render = CALLOC_STRUCT(nv04_vbuf_render);
|
|
||||||
|
|
||||||
nv04_render->nv04 = nv04;
|
|
||||||
|
|
||||||
nv04_render->base.max_vertex_buffer_bytes = VERTEX_BUFFER_SIZE;
|
|
||||||
nv04_render->base.max_indices = 65536;
|
|
||||||
nv04_render->base.get_vertex_info = nv04_vbuf_render_get_vertex_info;
|
|
||||||
nv04_render->base.allocate_vertices = nv04_vbuf_render_allocate_vertices;
|
|
||||||
nv04_render->base.map_vertices = nv04_vbuf_render_map_vertices;
|
|
||||||
nv04_render->base.unmap_vertices = nv04_vbuf_render_unmap_vertices;
|
|
||||||
nv04_render->base.set_primitive = nv04_vbuf_render_set_primitive;
|
|
||||||
nv04_render->base.draw = nv04_vbuf_render_draw;
|
|
||||||
nv04_render->base.release_vertices = nv04_vbuf_render_release_vertices;
|
|
||||||
nv04_render->base.destroy = nv04_vbuf_render_destroy;
|
|
||||||
|
|
||||||
return &nv04_render->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new primitive vbuf/render stage.
|
|
||||||
*/
|
|
||||||
struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 )
|
|
||||||
{
|
|
||||||
struct vbuf_render *render;
|
|
||||||
struct draw_stage *stage;
|
|
||||||
|
|
||||||
render = nv04_vbuf_render_create(nv04);
|
|
||||||
if(!render)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
stage = draw_vbuf_stage( nv04->draw, render );
|
|
||||||
if(!stage) {
|
|
||||||
render->destroy(render);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stage;
|
|
||||||
}
|
|
||||||
|
|
@ -1,222 +0,0 @@
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "nv04_context.h"
|
|
||||||
#include "nv04_screen.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
nv04_screen_get_param(struct pipe_screen *screen, int param)
|
|
||||||
{
|
|
||||||
switch (param) {
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_NPOT_TEXTURES:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TWO_SIDED_STENCIL:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_GLSL:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_POINT_SPRITE:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_OCCLUSION_QUERY:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
|
||||||
return 10;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_TGSI_CONT_SUPPORTED:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
|
||||||
return 0;
|
|
||||||
case NOUVEAU_CAP_HW_VTXBUF:
|
|
||||||
case NOUVEAU_CAP_HW_IDXBUF:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_INDEP_BLEND_FUNC:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static float
|
|
||||||
nv04_screen_get_paramf(struct pipe_screen *screen, int param)
|
|
||||||
{
|
|
||||||
switch (param) {
|
|
||||||
case PIPE_CAP_MAX_LINE_WIDTH:
|
|
||||||
case PIPE_CAP_MAX_LINE_WIDTH_AA:
|
|
||||||
return 0.0;
|
|
||||||
case PIPE_CAP_MAX_POINT_WIDTH:
|
|
||||||
case PIPE_CAP_MAX_POINT_WIDTH_AA:
|
|
||||||
return 0.0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
|
|
||||||
return 0.0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
|
|
||||||
return 0.0;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv04_screen_is_format_supported(struct pipe_screen *screen,
|
|
||||||
enum pipe_format format,
|
|
||||||
enum pipe_texture_target target,
|
|
||||||
unsigned tex_usage, unsigned geom_flags)
|
|
||||||
{
|
|
||||||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_Z16_UNORM:
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case PIPE_FORMAT_X8R8G8B8_UNORM:
|
|
||||||
case PIPE_FORMAT_A1R5G5B5_UNORM:
|
|
||||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
|
||||||
case PIPE_FORMAT_L8_UNORM:
|
|
||||||
case PIPE_FORMAT_A8_UNORM:
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_screen_destroy(struct pipe_screen *pscreen)
|
|
||||||
{
|
|
||||||
struct nv04_screen *screen = nv04_screen(pscreen);
|
|
||||||
|
|
||||||
nouveau_notifier_free(&screen->sync);
|
|
||||||
nouveau_grobj_free(&screen->fahrenheit);
|
|
||||||
nv04_surface_2d_takedown(&screen->eng2d);
|
|
||||||
|
|
||||||
nouveau_screen_fini(&screen->base);
|
|
||||||
|
|
||||||
FREE(pscreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_buffer *
|
|
||||||
nv04_surface_buffer(struct pipe_surface *surf)
|
|
||||||
{
|
|
||||||
struct nv04_miptree *mt = (struct nv04_miptree *)surf->texture;
|
|
||||||
|
|
||||||
return mt->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pipe_screen *
|
|
||||||
nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
|
|
||||||
{
|
|
||||||
struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen);
|
|
||||||
struct nouveau_channel *chan;
|
|
||||||
struct pipe_screen *pscreen;
|
|
||||||
unsigned fahrenheit_class = 0, sub3d_class = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!screen)
|
|
||||||
return NULL;
|
|
||||||
pscreen = &screen->base.base;
|
|
||||||
|
|
||||||
ret = nouveau_screen_init(&screen->base, dev);
|
|
||||||
if (ret) {
|
|
||||||
nv04_screen_destroy(pscreen);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
chan = screen->base.channel;
|
|
||||||
|
|
||||||
pscreen->winsys = ws;
|
|
||||||
pscreen->destroy = nv04_screen_destroy;
|
|
||||||
pscreen->get_param = nv04_screen_get_param;
|
|
||||||
pscreen->get_paramf = nv04_screen_get_paramf;
|
|
||||||
pscreen->is_format_supported = nv04_screen_is_format_supported;
|
|
||||||
|
|
||||||
nv04_screen_init_miptree_functions(pscreen);
|
|
||||||
nv04_screen_init_transfer_functions(pscreen);
|
|
||||||
|
|
||||||
if (dev->chipset >= 0x20) {
|
|
||||||
fahrenheit_class = 0;
|
|
||||||
sub3d_class = 0;
|
|
||||||
} else if (dev->chipset >= 0x10) {
|
|
||||||
fahrenheit_class = NV10_TEXTURED_TRIANGLE;
|
|
||||||
sub3d_class = NV10_CONTEXT_SURFACES_3D;
|
|
||||||
} else {
|
|
||||||
fahrenheit_class=NV04_TEXTURED_TRIANGLE;
|
|
||||||
sub3d_class = NV04_CONTEXT_SURFACES_3D;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fahrenheit_class) {
|
|
||||||
NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", dev->chipset);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 3D object */
|
|
||||||
ret = nouveau_grobj_alloc(chan, 0xbeef0001, fahrenheit_class,
|
|
||||||
&screen->fahrenheit);
|
|
||||||
if (ret) {
|
|
||||||
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
BIND_RING(chan, screen->fahrenheit, 7);
|
|
||||||
|
|
||||||
/* 3D surface object */
|
|
||||||
ret = nouveau_grobj_alloc(chan, 0xbeef0002, sub3d_class,
|
|
||||||
&screen->context_surfaces_3d);
|
|
||||||
if (ret) {
|
|
||||||
NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
BIND_RING(chan, screen->context_surfaces_3d, 6);
|
|
||||||
|
|
||||||
/* 2D engine setup */
|
|
||||||
screen->eng2d = nv04_surface_2d_init(&screen->base);
|
|
||||||
screen->eng2d->buf = nv04_surface_buffer;
|
|
||||||
|
|
||||||
/* Notifier for sync purposes */
|
|
||||||
ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
|
|
||||||
if (ret) {
|
|
||||||
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
|
|
||||||
nv04_screen_destroy(pscreen);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pscreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
#ifndef __NV04_SCREEN_H__
|
|
||||||
#define __NV04_SCREEN_H__
|
|
||||||
|
|
||||||
#include "nouveau/nouveau_screen.h"
|
|
||||||
#include "nv04_surface_2d.h"
|
|
||||||
|
|
||||||
struct nv04_screen {
|
|
||||||
struct nouveau_screen base;
|
|
||||||
|
|
||||||
struct nouveau_winsys *nvws;
|
|
||||||
unsigned chipset;
|
|
||||||
|
|
||||||
/* HW graphics objects */
|
|
||||||
struct nv04_surface_2d *eng2d;
|
|
||||||
struct nouveau_grobj *fahrenheit;
|
|
||||||
struct nouveau_grobj *context_surfaces_3d;
|
|
||||||
struct nouveau_notifier *sync;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE struct nv04_screen *
|
|
||||||
nv04_screen(struct pipe_screen *screen)
|
|
||||||
{
|
|
||||||
return (struct nv04_screen *)screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_screen_init_transfer_functions(struct pipe_screen *pscreen);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,459 +0,0 @@
|
||||||
#include "draw/draw_context.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_shader_tokens.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "tgsi/tgsi_parse.h"
|
|
||||||
|
|
||||||
#include "nv04_context.h"
|
|
||||||
#include "nv04_state.h"
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv04_blend_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_blend_state *cso)
|
|
||||||
{
|
|
||||||
struct nv04_blend_state *cb;
|
|
||||||
|
|
||||||
cb = MALLOC(sizeof(struct nv04_blend_state));
|
|
||||||
|
|
||||||
cb->b_enable = cso->rt[0].blend_enable ? 1 : 0;
|
|
||||||
cb->b_src = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) |
|
|
||||||
(nvgl_blend_func(cso->rt[0].rgb_src_factor)));
|
|
||||||
cb->b_dst = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) |
|
|
||||||
(nvgl_blend_func(cso->rt[0].rgb_dst_factor)));
|
|
||||||
|
|
||||||
|
|
||||||
return (void *)cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_blend_state_bind(struct pipe_context *pipe, void *blend)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
nv04->blend = (struct nv04_blend_state*)blend;
|
|
||||||
|
|
||||||
nv04->dirty |= NV04_NEW_BLEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_blend_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
free(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE unsigned
|
|
||||||
wrap_mode(unsigned wrap) {
|
|
||||||
unsigned ret;
|
|
||||||
|
|
||||||
switch (wrap) {
|
|
||||||
case PIPE_TEX_WRAP_REPEAT:
|
|
||||||
ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_REPEAT:
|
|
||||||
ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
|
|
||||||
ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
|
|
||||||
ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_CLAMP:
|
|
||||||
ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_CLAMP:
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
|
|
||||||
ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP;
|
|
||||||
}
|
|
||||||
return ret >> NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv04_sampler_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_sampler_state *cso)
|
|
||||||
{
|
|
||||||
|
|
||||||
struct nv04_sampler_state *ss;
|
|
||||||
uint32_t filter = 0;
|
|
||||||
|
|
||||||
ss = MALLOC(sizeof(struct nv04_sampler_state));
|
|
||||||
|
|
||||||
ss->format = ((wrap_mode(cso->wrap_s) << NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT) |
|
|
||||||
(wrap_mode(cso->wrap_t) << NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT));
|
|
||||||
|
|
||||||
if (cso->max_anisotropy > 1.0) {
|
|
||||||
filter |= NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE | NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cso->mag_img_filter) {
|
|
||||||
case PIPE_TEX_FILTER_LINEAR:
|
|
||||||
filter |= NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_FILTER_NEAREST:
|
|
||||||
default:
|
|
||||||
filter |= NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cso->min_img_filter) {
|
|
||||||
case PIPE_TEX_FILTER_LINEAR:
|
|
||||||
switch (cso->min_mip_filter) {
|
|
||||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
|
||||||
filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
|
||||||
filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_NONE:
|
|
||||||
default:
|
|
||||||
filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_FILTER_NEAREST:
|
|
||||||
default:
|
|
||||||
switch (cso->min_mip_filter) {
|
|
||||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
|
||||||
filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
|
||||||
filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_NONE:
|
|
||||||
default:
|
|
||||||
filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ss->filter = filter;
|
|
||||||
|
|
||||||
return (void *)ss;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
unsigned unit;
|
|
||||||
|
|
||||||
for (unit = 0; unit < nr; unit++) {
|
|
||||||
nv04->sampler[unit] = sampler[unit];
|
|
||||||
nv04->dirty_samplers |= (1 << unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
free(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
|
|
||||||
struct pipe_texture **miptree)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
unsigned unit;
|
|
||||||
|
|
||||||
for (unit = 0; unit < nr; unit++) {
|
|
||||||
nv04->tex_miptree[unit] = (struct nv04_miptree *)miptree[unit];
|
|
||||||
nv04->dirty_samplers |= (1 << unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv04_rasterizer_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_rasterizer_state *cso)
|
|
||||||
{
|
|
||||||
struct nv04_rasterizer_state *rs;
|
|
||||||
|
|
||||||
/*XXX: ignored:
|
|
||||||
* scissor
|
|
||||||
* points/lines (no hw support, emulated with tris in gallium)
|
|
||||||
*/
|
|
||||||
rs = MALLOC(sizeof(struct nv04_rasterizer_state));
|
|
||||||
|
|
||||||
rs->blend = cso->flatshade ? NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT : NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD;
|
|
||||||
|
|
||||||
return (void *)rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_rasterizer_state_bind(struct pipe_context *pipe, void *rast)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
nv04->rast = (struct nv04_rasterizer_state*)rast;
|
|
||||||
|
|
||||||
draw_set_rasterizer_state(nv04->draw, (nv04->rast ? nv04->rast->templ : NULL));
|
|
||||||
|
|
||||||
nv04->dirty |= NV04_NEW_RAST | NV04_NEW_BLEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
free(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE uint32_t nv04_compare_func(uint32_t f)
|
|
||||||
{
|
|
||||||
switch ( f ) {
|
|
||||||
case PIPE_FUNC_NEVER: return 1;
|
|
||||||
case PIPE_FUNC_LESS: return 2;
|
|
||||||
case PIPE_FUNC_EQUAL: return 3;
|
|
||||||
case PIPE_FUNC_LEQUAL: return 4;
|
|
||||||
case PIPE_FUNC_GREATER: return 5;
|
|
||||||
case PIPE_FUNC_NOTEQUAL: return 6;
|
|
||||||
case PIPE_FUNC_GEQUAL: return 7;
|
|
||||||
case PIPE_FUNC_ALWAYS: return 8;
|
|
||||||
}
|
|
||||||
NOUVEAU_MSG("Unable to find the function\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv04_depth_stencil_alpha_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_depth_stencil_alpha_state *cso)
|
|
||||||
{
|
|
||||||
struct nv04_depth_stencil_alpha_state *hw;
|
|
||||||
|
|
||||||
hw = MALLOC(sizeof(struct nv04_depth_stencil_alpha_state));
|
|
||||||
|
|
||||||
hw->control = float_to_ubyte(cso->alpha.ref_value);
|
|
||||||
hw->control |= ( nv04_compare_func(cso->alpha.func) << NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT );
|
|
||||||
hw->control |= cso->alpha.enabled ? NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE : 0;
|
|
||||||
hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN;
|
|
||||||
hw->control |= cso->depth.enabled ? NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE : 0;
|
|
||||||
hw->control |= ( nv04_compare_func(cso->depth.func)<< NV04_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT );
|
|
||||||
hw->control |= 1 << NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT; // no culling, handled by the draw module
|
|
||||||
hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE;
|
|
||||||
hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE;
|
|
||||||
hw->control |= cso->depth.writemask ? NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE : 0;
|
|
||||||
hw->control |= 1 << NV04_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT; // integer zbuffer format
|
|
||||||
|
|
||||||
return (void *)hw;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
nv04->dsa = hwcso;
|
|
||||||
nv04->dirty |= NV04_NEW_CONTROL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
free(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv04_vp_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_shader_state *templ)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
return draw_create_vertex_shader(nv04->draw, templ);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_vp_state_bind(struct pipe_context *pipe, void *shader)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
draw_bind_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader);
|
|
||||||
|
|
||||||
nv04->dirty |= NV04_NEW_VERTPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_vp_state_delete(struct pipe_context *pipe, void *shader)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
draw_delete_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv04_fp_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_shader_state *cso)
|
|
||||||
{
|
|
||||||
struct nv04_fragment_program *fp;
|
|
||||||
|
|
||||||
fp = CALLOC(1, sizeof(struct nv04_fragment_program));
|
|
||||||
fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
|
|
||||||
|
|
||||||
return (void *)fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_fp_state_bind(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
struct nv04_fragment_program *fp = hwcso;
|
|
||||||
|
|
||||||
nv04->fragprog.current = fp;
|
|
||||||
nv04->dirty |= NV04_NEW_FRAGPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_fp_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
struct nv04_fragment_program *fp = hwcso;
|
|
||||||
|
|
||||||
nv04_fragprog_destroy(nv04, fp);
|
|
||||||
free((void*)fp->pipe.tokens);
|
|
||||||
free(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_set_blend_color(struct pipe_context *pipe,
|
|
||||||
const struct pipe_blend_color *bcol)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_set_clip_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_clip_state *clip)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
|
||||||
struct pipe_buffer *buf )
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
struct pipe_screen *pscreen = pipe->screen;
|
|
||||||
|
|
||||||
assert(shader < PIPE_SHADER_TYPES);
|
|
||||||
assert(index == 0);
|
|
||||||
|
|
||||||
if (buf) {
|
|
||||||
void *mapped;
|
|
||||||
if (buf && buf->size &&
|
|
||||||
(mapped = pipe_buffer_map(pscreen, buf, PIPE_BUFFER_USAGE_CPU_READ)))
|
|
||||||
{
|
|
||||||
memcpy(nv04->constbuf[shader], mapped, buf->size);
|
|
||||||
nv04->constbuf_nr[shader] =
|
|
||||||
buf->size / (4 * sizeof(float));
|
|
||||||
pipe_buffer_unmap(pscreen, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_set_framebuffer_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_framebuffer_state *fb)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
nv04->framebuffer = (struct pipe_framebuffer_state*)fb;
|
|
||||||
|
|
||||||
nv04->dirty |= NV04_NEW_FRAMEBUFFER;
|
|
||||||
}
|
|
||||||
static void
|
|
||||||
nv04_set_polygon_stipple(struct pipe_context *pipe,
|
|
||||||
const struct pipe_poly_stipple *stipple)
|
|
||||||
{
|
|
||||||
NOUVEAU_ERR("line stipple hahaha\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_set_scissor_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_scissor_state *s)
|
|
||||||
{
|
|
||||||
/* struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
// XXX
|
|
||||||
BEGIN_RING(fahrenheit, NV04_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2);
|
|
||||||
OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
|
|
||||||
OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_set_viewport_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_viewport_state *viewport)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
nv04->viewport = *viewport;
|
|
||||||
|
|
||||||
draw_set_viewport_state(nv04->draw, &nv04->viewport);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
|
|
||||||
const struct pipe_vertex_buffer *buffers)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
memcpy(nv04->vtxbuf, buffers, count * sizeof(buffers[0]));
|
|
||||||
nv04->dirty |= NV04_NEW_VTXARRAYS;
|
|
||||||
|
|
||||||
draw_set_vertex_buffers(nv04->draw, count, buffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_set_vertex_elements(struct pipe_context *pipe, unsigned count,
|
|
||||||
const struct pipe_vertex_element *elements)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
|
|
||||||
memcpy(nv04->vtxelt, elements, sizeof(*elements) * count);
|
|
||||||
nv04->dirty |= NV04_NEW_VTXARRAYS;
|
|
||||||
|
|
||||||
draw_set_vertex_elements(nv04->draw, count, elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_init_state_functions(struct nv04_context *nv04)
|
|
||||||
{
|
|
||||||
nv04->pipe.create_blend_state = nv04_blend_state_create;
|
|
||||||
nv04->pipe.bind_blend_state = nv04_blend_state_bind;
|
|
||||||
nv04->pipe.delete_blend_state = nv04_blend_state_delete;
|
|
||||||
|
|
||||||
nv04->pipe.create_sampler_state = nv04_sampler_state_create;
|
|
||||||
nv04->pipe.bind_fragment_sampler_states = nv04_sampler_state_bind;
|
|
||||||
nv04->pipe.delete_sampler_state = nv04_sampler_state_delete;
|
|
||||||
nv04->pipe.set_fragment_sampler_textures = nv04_set_sampler_texture;
|
|
||||||
|
|
||||||
nv04->pipe.create_rasterizer_state = nv04_rasterizer_state_create;
|
|
||||||
nv04->pipe.bind_rasterizer_state = nv04_rasterizer_state_bind;
|
|
||||||
nv04->pipe.delete_rasterizer_state = nv04_rasterizer_state_delete;
|
|
||||||
|
|
||||||
nv04->pipe.create_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_create;
|
|
||||||
nv04->pipe.bind_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_bind;
|
|
||||||
nv04->pipe.delete_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_delete;
|
|
||||||
|
|
||||||
nv04->pipe.create_vs_state = nv04_vp_state_create;
|
|
||||||
nv04->pipe.bind_vs_state = nv04_vp_state_bind;
|
|
||||||
nv04->pipe.delete_vs_state = nv04_vp_state_delete;
|
|
||||||
|
|
||||||
nv04->pipe.create_fs_state = nv04_fp_state_create;
|
|
||||||
nv04->pipe.bind_fs_state = nv04_fp_state_bind;
|
|
||||||
nv04->pipe.delete_fs_state = nv04_fp_state_delete;
|
|
||||||
|
|
||||||
nv04->pipe.set_blend_color = nv04_set_blend_color;
|
|
||||||
nv04->pipe.set_clip_state = nv04_set_clip_state;
|
|
||||||
nv04->pipe.set_constant_buffer = nv04_set_constant_buffer;
|
|
||||||
nv04->pipe.set_framebuffer_state = nv04_set_framebuffer_state;
|
|
||||||
nv04->pipe.set_polygon_stipple = nv04_set_polygon_stipple;
|
|
||||||
nv04->pipe.set_scissor_state = nv04_set_scissor_state;
|
|
||||||
nv04->pipe.set_viewport_state = nv04_set_viewport_state;
|
|
||||||
|
|
||||||
nv04->pipe.set_vertex_buffers = nv04_set_vertex_buffers;
|
|
||||||
nv04->pipe.set_vertex_elements = nv04_set_vertex_elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
#ifndef __NV04_STATE_H__
|
|
||||||
#define __NV04_STATE_H__
|
|
||||||
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "tgsi/tgsi_scan.h"
|
|
||||||
|
|
||||||
struct nv04_blend_state {
|
|
||||||
uint32_t b_enable;
|
|
||||||
uint32_t b_src;
|
|
||||||
uint32_t b_dst;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv04_fragtex_state {
|
|
||||||
uint32_t format;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv04_sampler_state {
|
|
||||||
uint32_t filter;
|
|
||||||
uint32_t format;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv04_depth_stencil_alpha_state {
|
|
||||||
uint32_t control;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv04_rasterizer_state {
|
|
||||||
uint32_t blend;
|
|
||||||
|
|
||||||
const struct pipe_rasterizer_state *templ;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv04_miptree {
|
|
||||||
struct pipe_texture base;
|
|
||||||
struct nouveau_bo *bo;
|
|
||||||
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
uint total_size;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint pitch;
|
|
||||||
uint *image_offset;
|
|
||||||
} level[PIPE_MAX_TEXTURE_LEVELS];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv04_fragment_program_data {
|
|
||||||
unsigned offset;
|
|
||||||
unsigned index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv04_fragment_program {
|
|
||||||
struct pipe_shader_state pipe;
|
|
||||||
struct tgsi_shader_info info;
|
|
||||||
|
|
||||||
boolean translated;
|
|
||||||
boolean on_hw;
|
|
||||||
unsigned samplers;
|
|
||||||
|
|
||||||
uint32_t *insn;
|
|
||||||
int insn_len;
|
|
||||||
|
|
||||||
struct nv04_fragment_program_data *consts;
|
|
||||||
unsigned nr_consts;
|
|
||||||
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
|
|
||||||
uint32_t fp_control;
|
|
||||||
uint32_t fp_reg_control;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
#include "nv04_context.h"
|
|
||||||
#include "nv04_state.h"
|
|
||||||
|
|
||||||
static void nv04_vertex_layout(struct pipe_context* pipe)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
struct nv04_fragment_program *fp = nv04->fragprog.current;
|
|
||||||
uint32_t src = 0;
|
|
||||||
int i;
|
|
||||||
struct vertex_info vinfo;
|
|
||||||
|
|
||||||
memset(&vinfo, 0, sizeof(vinfo));
|
|
||||||
|
|
||||||
for (i = 0; i < fp->info.num_inputs; i++) {
|
|
||||||
int isn = fp->info.input_semantic_name[i];
|
|
||||||
int isi = fp->info.input_semantic_index[i];
|
|
||||||
switch (isn) {
|
|
||||||
case TGSI_SEMANTIC_POSITION:
|
|
||||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_COLOR:
|
|
||||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case TGSI_SEMANTIC_GENERIC:
|
|
||||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_FOG:
|
|
||||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%d vertex input\n",fp->info.num_inputs);
|
|
||||||
draw_compute_vertex_size(&vinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t nv04_blend_func(uint32_t f)
|
|
||||||
{
|
|
||||||
switch ( f ) {
|
|
||||||
case PIPE_BLENDFACTOR_ZERO: return 0x1;
|
|
||||||
case PIPE_BLENDFACTOR_ONE: return 0x2;
|
|
||||||
case PIPE_BLENDFACTOR_SRC_COLOR: return 0x3;
|
|
||||||
case PIPE_BLENDFACTOR_INV_SRC_COLOR: return 0x4;
|
|
||||||
case PIPE_BLENDFACTOR_SRC_ALPHA: return 0x5;
|
|
||||||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return 0x6;
|
|
||||||
case PIPE_BLENDFACTOR_DST_ALPHA: return 0x7;
|
|
||||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA: return 0x8;
|
|
||||||
case PIPE_BLENDFACTOR_DST_COLOR: return 0x9;
|
|
||||||
case PIPE_BLENDFACTOR_INV_DST_COLOR: return 0xA;
|
|
||||||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return 0xB;
|
|
||||||
}
|
|
||||||
NOUVEAU_MSG("Unable to find the blend function 0x%x\n",f);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv04_emit_control(struct nv04_context* nv04)
|
|
||||||
{
|
|
||||||
uint32_t control = nv04->dsa->control;
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1);
|
|
||||||
OUT_RING(chan, control);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv04_emit_blend(struct nv04_context* nv04)
|
|
||||||
{
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
uint32_t blend;
|
|
||||||
|
|
||||||
blend=0x4; // texture MODULATE_ALPHA
|
|
||||||
blend|=0x20; // alpha is MSB
|
|
||||||
blend|=(2<<6); // flat shading
|
|
||||||
blend|=(1<<8); // persp correct
|
|
||||||
blend|=(0<<16); // no fog
|
|
||||||
blend|=(nv04->blend->b_enable<<20);
|
|
||||||
blend|=(nv04_blend_func(nv04->blend->b_src)<<24);
|
|
||||||
blend|=(nv04_blend_func(nv04->blend->b_dst)<<28);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1);
|
|
||||||
OUT_RING(chan, blend);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv04_emit_sampler(struct nv04_context *nv04, int unit)
|
|
||||||
{
|
|
||||||
struct nv04_miptree *nv04mt = nv04->tex_miptree[unit];
|
|
||||||
struct pipe_texture *pt = &nv04mt->base;
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 3);
|
|
||||||
OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
|
||||||
OUT_RELOCd(chan, bo, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
|
|
||||||
OUT_RING(chan, nv04->sampler[unit]->filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv04_state_emit_framebuffer(struct nv04_context* nv04)
|
|
||||||
{
|
|
||||||
struct pipe_framebuffer_state* fb = nv04->framebuffer;
|
|
||||||
struct nv04_surface *rt, *zeta;
|
|
||||||
uint32_t rt_format, w, h;
|
|
||||||
int colour_format = 0, zeta_format = 0;
|
|
||||||
struct nv04_miptree *nv04mt = 0;
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d;
|
|
||||||
struct nouveau_bo *bo;
|
|
||||||
|
|
||||||
w = fb->cbufs[0]->width;
|
|
||||||
h = fb->cbufs[0]->height;
|
|
||||||
colour_format = fb->cbufs[0]->format;
|
|
||||||
rt = (struct nv04_surface *)fb->cbufs[0];
|
|
||||||
|
|
||||||
if (fb->zsbuf) {
|
|
||||||
if (colour_format) {
|
|
||||||
assert(w == fb->zsbuf->width);
|
|
||||||
assert(h == fb->zsbuf->height);
|
|
||||||
} else {
|
|
||||||
w = fb->zsbuf->width;
|
|
||||||
h = fb->zsbuf->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
zeta_format = fb->zsbuf->format;
|
|
||||||
zeta = (struct nv04_surface *)fb->zsbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (colour_format) {
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case 0:
|
|
||||||
rt_format = 0x108;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
|
||||||
rt_format = 0x103;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
|
|
||||||
OUT_RING(chan, rt_format);
|
|
||||||
|
|
||||||
nv04mt = (struct nv04_miptree *)rt->base.texture;
|
|
||||||
bo = nouveau_bo(nv04mt->buffer);
|
|
||||||
/* FIXME pitches have to be aligned ! */
|
|
||||||
BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
|
|
||||||
OUT_RING(chan, rt->pitch|(zeta->pitch<<16));
|
|
||||||
OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
if (fb->zsbuf) {
|
|
||||||
nv04mt = (struct nv04_miptree *)zeta->base.texture;
|
|
||||||
BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
|
|
||||||
OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_emit_hw_state(struct nv04_context *nv04)
|
|
||||||
{
|
|
||||||
struct nv04_screen *screen = nv04->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *fahrenheit = screen->fahrenheit;
|
|
||||||
struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (nv04->dirty & NV04_NEW_VERTPROG) {
|
|
||||||
//nv04_vertprog_bind(nv04, nv04->vertprog.current);
|
|
||||||
nv04->dirty &= ~NV04_NEW_VERTPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv04->dirty & NV04_NEW_FRAGPROG) {
|
|
||||||
nv04_fragprog_bind(nv04, nv04->fragprog.current);
|
|
||||||
nv04->dirty &= ~NV04_NEW_FRAGPROG;
|
|
||||||
nv04->dirty_samplers |= (1<<10);
|
|
||||||
nv04->dirty_samplers = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv04->dirty & NV04_NEW_CONTROL) {
|
|
||||||
nv04->dirty &= ~NV04_NEW_CONTROL;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1);
|
|
||||||
OUT_RING(chan, nv04->dsa->control);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv04->dirty & NV04_NEW_BLEND) {
|
|
||||||
nv04->dirty &= ~NV04_NEW_BLEND;
|
|
||||||
|
|
||||||
nv04_emit_blend(nv04);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv04->dirty & NV04_NEW_VTXARRAYS) {
|
|
||||||
nv04->dirty &= ~NV04_NEW_VTXARRAYS;
|
|
||||||
nv04_vertex_layout(nv04);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv04->dirty & NV04_NEW_SAMPLER) {
|
|
||||||
nv04->dirty &= ~NV04_NEW_SAMPLER;
|
|
||||||
|
|
||||||
nv04_emit_sampler(nv04, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv04->dirty & NV04_NEW_VIEWPORT) {
|
|
||||||
nv04->dirty &= ~NV04_NEW_VIEWPORT;
|
|
||||||
// nv04_state_emit_viewport(nv04);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv04->dirty & NV04_NEW_FRAMEBUFFER) {
|
|
||||||
nv04->dirty &= ~NV04_NEW_FRAMEBUFFER;
|
|
||||||
nv04_state_emit_framebuffer(nv04);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emit relocs for every referenced buffer.
|
|
||||||
* This is to ensure the bufmgr has an accurate idea of how
|
|
||||||
* the buffer is used. This isn't very efficient, but we don't
|
|
||||||
* seem to take a significant performance hit. Will be improved
|
|
||||||
* at some point. Vertex arrays are emitted by nv04_vbo.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Render target */
|
|
||||||
unsigned rt_pitch = ((struct nv04_surface *)nv04->rt)->pitch;
|
|
||||||
unsigned zeta_pitch = ((struct nv04_surface *)nv04->zeta)->pitch;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
|
|
||||||
OUT_RING(chan, rt_pitch|(zeta_pitch<<16));
|
|
||||||
OUT_RELOCl(chan, nouveau_bo(nv04->rt), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
if (nv04->zeta) {
|
|
||||||
BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
|
|
||||||
OUT_RELOCl(chan, nouveau_bo(nv04->zeta), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Texture images */
|
|
||||||
for (i = 0; i < 1; i++) {
|
|
||||||
if (!(nv04->fp_samplers & (1 << i)))
|
|
||||||
continue;
|
|
||||||
struct nv04_miptree *nv04mt = nv04->tex_miptree[i];
|
|
||||||
struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer);
|
|
||||||
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 2);
|
|
||||||
OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
|
||||||
OUT_RELOCd(chan, bo, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
||||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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 "nv04_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "util/u_simple_screen.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_tile.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_surface_copy(struct pipe_context *pipe,
|
|
||||||
struct pipe_surface *dest, unsigned destx, unsigned desty,
|
|
||||||
struct pipe_surface *src, unsigned srcx, unsigned srcy,
|
|
||||||
unsigned width, unsigned height)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
struct nv04_surface_2d *eng2d = nv04->screen->eng2d;
|
|
||||||
|
|
||||||
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
|
|
||||||
unsigned destx, unsigned desty, unsigned width,
|
|
||||||
unsigned height, unsigned value)
|
|
||||||
{
|
|
||||||
struct nv04_context *nv04 = nv04_context(pipe);
|
|
||||||
struct nv04_surface_2d *eng2d = nv04->screen->eng2d;
|
|
||||||
|
|
||||||
eng2d->fill(eng2d, dest, destx, desty, width, height, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_init_surface_functions(struct nv04_context *nv04)
|
|
||||||
{
|
|
||||||
nv04->pipe.surface_copy = nv04_surface_copy;
|
|
||||||
nv04->pipe.surface_fill = nv04_surface_fill;
|
|
||||||
}
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
||||||
#include <pipe/p_state.h>
|
|
||||||
#include <pipe/p_defines.h>
|
|
||||||
#include <util/u_inlines.h>
|
|
||||||
#include <util/u_format.h>
|
|
||||||
#include <util/u_memory.h>
|
|
||||||
#include <util/u_math.h>
|
|
||||||
#include <nouveau/nouveau_winsys.h>
|
|
||||||
#include "nv04_context.h"
|
|
||||||
#include "nv04_screen.h"
|
|
||||||
#include "nv04_state.h"
|
|
||||||
|
|
||||||
struct nv04_transfer {
|
|
||||||
struct pipe_transfer base;
|
|
||||||
struct pipe_surface *surface;
|
|
||||||
boolean direct;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
|
|
||||||
struct pipe_texture *template)
|
|
||||||
{
|
|
||||||
memset(template, 0, sizeof(struct pipe_texture));
|
|
||||||
template->target = pt->target;
|
|
||||||
template->format = pt->format;
|
|
||||||
template->width0 = width;
|
|
||||||
template->height0 = height;
|
|
||||||
template->depth0 = 1;
|
|
||||||
template->last_level = 0;
|
|
||||||
template->nr_samples = pt->nr_samples;
|
|
||||||
|
|
||||||
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
|
|
||||||
NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_transfer *
|
|
||||||
nv04_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
|
|
||||||
unsigned face, unsigned level, unsigned zslice,
|
|
||||||
enum pipe_transfer_usage usage,
|
|
||||||
unsigned x, unsigned y, unsigned w, unsigned h)
|
|
||||||
{
|
|
||||||
struct nv04_miptree *mt = (struct nv04_miptree *)pt;
|
|
||||||
struct nv04_transfer *tx;
|
|
||||||
struct pipe_texture tx_tex_template, *tx_tex;
|
|
||||||
|
|
||||||
tx = CALLOC_STRUCT(nv04_transfer);
|
|
||||||
if (!tx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
pipe_texture_reference(&tx->base.texture, pt);
|
|
||||||
tx->base.x = x;
|
|
||||||
tx->base.y = y;
|
|
||||||
tx->base.width = w;
|
|
||||||
tx->base.height = h;
|
|
||||||
tx->base.stride = mt->level[level].pitch;
|
|
||||||
tx->base.usage = usage;
|
|
||||||
tx->base.face = face;
|
|
||||||
tx->base.level = level;
|
|
||||||
tx->base.zslice = zslice;
|
|
||||||
|
|
||||||
/* Direct access to texture */
|
|
||||||
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
|
|
||||||
debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
|
|
||||||
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
|
|
||||||
{
|
|
||||||
tx->direct = true;
|
|
||||||
tx->surface = pscreen->get_tex_surface(pscreen, pt,
|
|
||||||
0, 0, 0,
|
|
||||||
pipe_transfer_buffer_flags(&tx->base));
|
|
||||||
return &tx->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx->direct = false;
|
|
||||||
|
|
||||||
nv04_compatible_transfer_tex(pt, w, h, &tx_tex_template);
|
|
||||||
|
|
||||||
tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
|
|
||||||
if (!tx_tex)
|
|
||||||
{
|
|
||||||
FREE(tx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx->base.stride = ((struct nv04_miptree*)tx_tex)->level[0].pitch;
|
|
||||||
|
|
||||||
tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
|
|
||||||
face, level, zslice,
|
|
||||||
pipe_transfer_buffer_flags(&tx->base));
|
|
||||||
|
|
||||||
pipe_texture_reference(&tx_tex, NULL);
|
|
||||||
|
|
||||||
if (!tx->surface)
|
|
||||||
{
|
|
||||||
pipe_surface_reference(&tx->surface, NULL);
|
|
||||||
FREE(tx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usage & PIPE_TRANSFER_READ) {
|
|
||||||
struct nv04_screen *nvscreen = nv04_screen(pscreen);
|
|
||||||
struct pipe_surface *src;
|
|
||||||
|
|
||||||
src = pscreen->get_tex_surface(pscreen, pt,
|
|
||||||
face, level, zslice,
|
|
||||||
PIPE_BUFFER_USAGE_GPU_READ);
|
|
||||||
|
|
||||||
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
|
|
||||||
/* TODO: Check if SIFM can un-swizzle */
|
|
||||||
nvscreen->eng2d->copy(nvscreen->eng2d,
|
|
||||||
tx->surface, 0, 0,
|
|
||||||
src, x, y,
|
|
||||||
w, h);
|
|
||||||
|
|
||||||
pipe_surface_reference(&src, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return &tx->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_transfer_del(struct pipe_transfer *ptx)
|
|
||||||
{
|
|
||||||
struct nv04_transfer *tx = (struct nv04_transfer *)ptx;
|
|
||||||
|
|
||||||
if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
|
|
||||||
struct pipe_screen *pscreen = ptx->texture->screen;
|
|
||||||
struct nv04_screen *nvscreen = nv04_screen(pscreen);
|
|
||||||
struct pipe_surface *dst;
|
|
||||||
|
|
||||||
dst = pscreen->get_tex_surface(pscreen, ptx->texture,
|
|
||||||
ptx->face, ptx->level, ptx->zslice,
|
|
||||||
PIPE_BUFFER_USAGE_GPU_WRITE);
|
|
||||||
|
|
||||||
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
|
|
||||||
nvscreen->eng2d->copy(nvscreen->eng2d,
|
|
||||||
dst, tx->base.x, tx->base.y,
|
|
||||||
tx->surface, 0, 0,
|
|
||||||
tx->base.width, tx->base.height);
|
|
||||||
|
|
||||||
pipe_surface_reference(&dst, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_surface_reference(&tx->surface, NULL);
|
|
||||||
pipe_texture_reference(&ptx->texture, NULL);
|
|
||||||
FREE(ptx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv04_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
|
|
||||||
{
|
|
||||||
struct nv04_transfer *tx = (struct nv04_transfer *)ptx;
|
|
||||||
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
|
|
||||||
struct nv04_miptree *mt = (struct nv04_miptree *)tx->surface->texture;
|
|
||||||
void *map = pipe_buffer_map(pscreen, mt->buffer,
|
|
||||||
pipe_transfer_buffer_flags(ptx));
|
|
||||||
|
|
||||||
if(!tx->direct)
|
|
||||||
return map + ns->base.offset;
|
|
||||||
else
|
|
||||||
return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv04_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
|
|
||||||
{
|
|
||||||
struct nv04_transfer *tx = (struct nv04_transfer *)ptx;
|
|
||||||
struct nv04_miptree *mt = (struct nv04_miptree *)tx->surface->texture;
|
|
||||||
|
|
||||||
pipe_buffer_unmap(pscreen, mt->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv04_screen_init_transfer_functions(struct pipe_screen *pscreen)
|
|
||||||
{
|
|
||||||
pscreen->get_tex_transfer = nv04_transfer_new;
|
|
||||||
pscreen->tex_transfer_destroy = nv04_transfer_del;
|
|
||||||
pscreen->transfer_map = nv04_transfer_map;
|
|
||||||
pscreen->transfer_unmap = nv04_transfer_unmap;
|
|
||||||
}
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
#include "draw/draw_context.h"
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "nv04_context.h"
|
|
||||||
#include "nv04_state.h"
|
|
||||||
|
|
||||||
#include "nouveau/nouveau_channel.h"
|
|
||||||
#include "nouveau/nouveau_pushbuf.h"
|
|
||||||
|
|
||||||
void nv04_draw_elements( struct pipe_context *pipe,
|
|
||||||
struct pipe_buffer *indexBuffer,
|
|
||||||
unsigned indexSize,
|
|
||||||
unsigned prim, unsigned start, unsigned count)
|
|
||||||
{
|
|
||||||
struct pipe_screen *pscreen = pipe->screen;
|
|
||||||
struct nv04_context *nv04 = nv04_context( pipe );
|
|
||||||
struct draw_context *draw = nv04->draw;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
nv04_emit_hw_state(nv04);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map vertex buffers
|
|
||||||
*/
|
|
||||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
|
|
||||||
if (nv04->vtxbuf[i].buffer) {
|
|
||||||
void *buf
|
|
||||||
= pipe_buffer_map(pscreen,
|
|
||||||
nv04->vtxbuf[i].buffer,
|
|
||||||
PIPE_BUFFER_USAGE_CPU_READ);
|
|
||||||
draw_set_mapped_vertex_buffer(draw, i, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Map index buffer, if present */
|
|
||||||
if (indexBuffer) {
|
|
||||||
void *mapped_indexes
|
|
||||||
= pipe_buffer_map(pscreen, indexBuffer,
|
|
||||||
PIPE_BUFFER_USAGE_CPU_READ);
|
|
||||||
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* no index/element buffer */
|
|
||||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
|
|
||||||
nv04->constbuf[PIPE_SHADER_VERTEX],
|
|
||||||
nv04->constbuf_nr[PIPE_SHADER_VERTEX]);
|
|
||||||
|
|
||||||
/* draw! */
|
|
||||||
draw_arrays(nv04->draw, prim, start, count);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* unmap vertex/index buffers
|
|
||||||
*/
|
|
||||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
|
|
||||||
if (nv04->vtxbuf[i].buffer) {
|
|
||||||
pipe_buffer_unmap(pscreen, nv04->vtxbuf[i].buffer);
|
|
||||||
draw_set_mapped_vertex_buffer(draw, i, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (indexBuffer) {
|
|
||||||
pipe_buffer_unmap(pscreen, indexBuffer);
|
|
||||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nv04_draw_arrays( struct pipe_context *pipe,
|
|
||||||
unsigned prim, unsigned start, unsigned count)
|
|
||||||
{
|
|
||||||
printf("coucou in draw arrays\n");
|
|
||||||
nv04_draw_elements(pipe, NULL, 0, prim, start, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
TOP = ../../../..
|
|
||||||
include $(TOP)/configs/current
|
|
||||||
|
|
||||||
LIBNAME = nv10
|
|
||||||
|
|
||||||
C_SOURCES = \
|
|
||||||
nv10_clear.c \
|
|
||||||
nv10_context.c \
|
|
||||||
nv10_fragprog.c \
|
|
||||||
nv10_fragtex.c \
|
|
||||||
nv10_miptree.c \
|
|
||||||
nv10_prim_vbuf.c \
|
|
||||||
nv10_screen.c \
|
|
||||||
nv10_state.c \
|
|
||||||
nv10_state_emit.c \
|
|
||||||
nv10_surface.c \
|
|
||||||
nv10_transfer.c \
|
|
||||||
nv10_vbo.c
|
|
||||||
|
|
||||||
include ../../Makefile.template
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_clear.h"
|
|
||||||
|
|
||||||
#include "nv10_context.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
nv10_clear(struct pipe_context *pipe, unsigned buffers,
|
|
||||||
const float *rgba, double depth, unsigned stencil)
|
|
||||||
{
|
|
||||||
util_clear(pipe, nv10_context(pipe)->framebuffer, buffers, rgba, depth,
|
|
||||||
stencil);
|
|
||||||
}
|
|
||||||
|
|
@ -1,298 +0,0 @@
|
||||||
#include "draw/draw_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "util/u_simple_screen.h"
|
|
||||||
|
|
||||||
#include "nv10_context.h"
|
|
||||||
#include "nv10_screen.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_flush(struct pipe_context *pipe, unsigned flags,
|
|
||||||
struct pipe_fence_handle **fence)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
|
|
||||||
draw_flush(nv10->draw);
|
|
||||||
|
|
||||||
FIRE_RING(chan);
|
|
||||||
if (fence)
|
|
||||||
*fence = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_destroy(struct pipe_context *pipe)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
if (nv10->draw)
|
|
||||||
draw_destroy(nv10->draw);
|
|
||||||
|
|
||||||
FREE(nv10);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv10_init_hwctx(struct nv10_context *nv10)
|
|
||||||
{
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
int i;
|
|
||||||
float projectionmatrix[16];
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DMA_NOTIFY, 1);
|
|
||||||
OUT_RING (chan, screen->sync->handle);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY0, 2);
|
|
||||||
OUT_RING (chan, chan->vram->handle);
|
|
||||||
OUT_RING (chan, chan->gart->handle);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY2, 2);
|
|
||||||
OUT_RING (chan, chan->vram->handle);
|
|
||||||
OUT_RING (chan, chan->vram->handle);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1);
|
|
||||||
OUT_RING (chan, (0x7ff<<16)|0x800);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1);
|
|
||||||
OUT_RING (chan, (0x7ff<<16)|0x800);
|
|
||||||
|
|
||||||
for (i=1;i<8;i++) {
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, 0x290, 1);
|
|
||||||
OUT_RING (chan, (0x10<<16)|1);
|
|
||||||
BEGIN_RING(chan, celsius, 0x3f4, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
|
|
||||||
if (nv10->screen->celsius->grclass != NV10TCL) {
|
|
||||||
/* For nv11, nv17 */
|
|
||||||
BEGIN_RING(chan, celsius, 0x120, 3);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 1);
|
|
||||||
OUT_RING (chan, 2);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
|
|
||||||
/* Set state */
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2);
|
|
||||||
OUT_RING (chan, 0x207);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(0), 2);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_RC_IN_ALPHA(0), 12);
|
|
||||||
OUT_RING (chan, 0x30141010);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0x20040000);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0x00000c00);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0x00000c00);
|
|
||||||
OUT_RING (chan, 0x18000000);
|
|
||||||
OUT_RING (chan, 0x300e0300);
|
|
||||||
OUT_RING (chan, 0x0c091c80);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 2);
|
|
||||||
OUT_RING (chan, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 4);
|
|
||||||
OUT_RING (chan, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0x8006);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 8);
|
|
||||||
OUT_RING (chan, 0xff);
|
|
||||||
OUT_RING (chan, 0x207);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0xff);
|
|
||||||
OUT_RING (chan, 0x1e00);
|
|
||||||
OUT_RING (chan, 0x1e00);
|
|
||||||
OUT_RING (chan, 0x1e00);
|
|
||||||
OUT_RING (chan, 0x1d01);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 2);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_SEPARATE_SPECULAR_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1);
|
|
||||||
OUT_RING (chan, 0x201);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1);
|
|
||||||
OUT_RING (chan, 8);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1);
|
|
||||||
OUT_RING (chan, 8);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
|
|
||||||
OUT_RING (chan, 0x1b02);
|
|
||||||
OUT_RING (chan, 0x1b02);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2);
|
|
||||||
OUT_RING (chan, 0x405);
|
|
||||||
OUT_RING (chan, 0x901);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_TX_GEN_S(0), 8);
|
|
||||||
for (i=0;i<8;i++) {
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
}
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3);
|
|
||||||
OUT_RING (chan, 0x3fc00000); /* -1.50 */
|
|
||||||
OUT_RING (chan, 0xbdb8aa0a); /* -0.09 */
|
|
||||||
OUT_RING (chan, 0); /* 0.00 */
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_NOP, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 2);
|
|
||||||
OUT_RING (chan, 0x802);
|
|
||||||
OUT_RING (chan, 2);
|
|
||||||
/* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
|
|
||||||
* using texturing, except when using the texture matrix
|
|
||||||
*/
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 6);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1);
|
|
||||||
OUT_RING (chan, 0x01010101);
|
|
||||||
|
|
||||||
/* Set vertex component */
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL_4F_R, 4);
|
|
||||||
OUT_RINGf (chan, 1.0);
|
|
||||||
OUT_RINGf (chan, 1.0);
|
|
||||||
OUT_RINGf (chan, 1.0);
|
|
||||||
OUT_RINGf (chan, 1.0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL2_3F_R, 3);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_NOR_3F_X, 3);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
OUT_RINGf (chan, 1.0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX0_4F_S, 4);
|
|
||||||
OUT_RINGf (chan, 0.0);
|
|
||||||
OUT_RINGf (chan, 0.0);
|
|
||||||
OUT_RINGf (chan, 0.0);
|
|
||||||
OUT_RINGf (chan, 1.0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX1_4F_S, 4);
|
|
||||||
OUT_RINGf (chan, 0.0);
|
|
||||||
OUT_RINGf (chan, 0.0);
|
|
||||||
OUT_RINGf (chan, 0.0);
|
|
||||||
OUT_RINGf (chan, 1.0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_FOG_1F, 1);
|
|
||||||
OUT_RINGf (chan, 0.0);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_EDGEFLAG_ENABLE, 1);
|
|
||||||
OUT_RING (chan, 1);
|
|
||||||
|
|
||||||
memset(projectionmatrix, 0, sizeof(projectionmatrix));
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_PROJECTION_MATRIX(0), 16);
|
|
||||||
projectionmatrix[0*4+0] = 1.0;
|
|
||||||
projectionmatrix[1*4+1] = 1.0;
|
|
||||||
projectionmatrix[2*4+2] = 1.0;
|
|
||||||
projectionmatrix[3*4+3] = 1.0;
|
|
||||||
for (i=0;i<16;i++) {
|
|
||||||
OUT_RINGf (chan, projectionmatrix[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DEPTH_RANGE_NEAR, 2);
|
|
||||||
OUT_RING (chan, 0.0);
|
|
||||||
OUT_RINGf (chan, 16777216.0);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_TRANSLATE_X, 4);
|
|
||||||
OUT_RINGf (chan, -2048.0);
|
|
||||||
OUT_RINGf (chan, -2048.0);
|
|
||||||
OUT_RINGf (chan, 16777215.0 * 0.5);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
|
|
||||||
FIRE_RING (chan);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pipe_context *
|
|
||||||
nv10_create(struct pipe_screen *pscreen, unsigned pctx_id)
|
|
||||||
{
|
|
||||||
struct nv10_screen *screen = nv10_screen(pscreen);
|
|
||||||
struct pipe_winsys *ws = pscreen->winsys;
|
|
||||||
struct nv10_context *nv10;
|
|
||||||
struct nouveau_winsys *nvws = screen->nvws;
|
|
||||||
|
|
||||||
nv10 = CALLOC(1, sizeof(struct nv10_context));
|
|
||||||
if (!nv10)
|
|
||||||
return NULL;
|
|
||||||
nv10->screen = screen;
|
|
||||||
nv10->pctx_id = pctx_id;
|
|
||||||
|
|
||||||
nv10->nvws = nvws;
|
|
||||||
|
|
||||||
nv10->pipe.winsys = ws;
|
|
||||||
nv10->pipe.screen = pscreen;
|
|
||||||
nv10->pipe.destroy = nv10_destroy;
|
|
||||||
nv10->pipe.draw_arrays = nv10_draw_arrays;
|
|
||||||
nv10->pipe.draw_elements = nv10_draw_elements;
|
|
||||||
nv10->pipe.clear = nv10_clear;
|
|
||||||
nv10->pipe.flush = nv10_flush;
|
|
||||||
|
|
||||||
nv10->pipe.is_texture_referenced = nouveau_is_texture_referenced;
|
|
||||||
nv10->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
|
|
||||||
|
|
||||||
nv10_init_surface_functions(nv10);
|
|
||||||
nv10_init_state_functions(nv10);
|
|
||||||
|
|
||||||
nv10->draw = draw_create();
|
|
||||||
assert(nv10->draw);
|
|
||||||
draw_set_rasterize_stage(nv10->draw, nv10_draw_vbuf_stage(nv10));
|
|
||||||
|
|
||||||
nv10_init_hwctx(nv10);
|
|
||||||
|
|
||||||
return &nv10->pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
#ifndef __NV10_CONTEXT_H__
|
|
||||||
#define __NV10_CONTEXT_H__
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "pipe/p_compiler.h"
|
|
||||||
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
|
|
||||||
#include "draw/draw_vertex.h"
|
|
||||||
|
|
||||||
#include "nouveau/nouveau_winsys.h"
|
|
||||||
#include "nouveau/nouveau_gldefs.h"
|
|
||||||
#include "nouveau/nouveau_context.h"
|
|
||||||
|
|
||||||
#include "nv10_state.h"
|
|
||||||
|
|
||||||
#define NOUVEAU_ERR(fmt, args...) \
|
|
||||||
fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args);
|
|
||||||
#define NOUVEAU_MSG(fmt, args...) \
|
|
||||||
fprintf(stderr, "nouveau: "fmt, ##args);
|
|
||||||
|
|
||||||
#define NV10_NEW_VERTPROG (1 << 0)
|
|
||||||
#define NV10_NEW_FRAGPROG (1 << 1)
|
|
||||||
#define NV10_NEW_VTXARRAYS (1 << 2)
|
|
||||||
#define NV10_NEW_BLEND (1 << 3)
|
|
||||||
#define NV10_NEW_BLENDCOL (1 << 4)
|
|
||||||
#define NV10_NEW_RAST (1 << 5)
|
|
||||||
#define NV10_NEW_DSA (1 << 6)
|
|
||||||
#define NV10_NEW_VIEWPORT (1 << 7)
|
|
||||||
#define NV10_NEW_SCISSOR (1 << 8)
|
|
||||||
#define NV10_NEW_FRAMEBUFFER (1 << 9)
|
|
||||||
|
|
||||||
#include "nv10_screen.h"
|
|
||||||
|
|
||||||
struct nv10_context {
|
|
||||||
struct pipe_context pipe;
|
|
||||||
|
|
||||||
struct nouveau_winsys *nvws;
|
|
||||||
struct nv10_screen *screen;
|
|
||||||
unsigned pctx_id;
|
|
||||||
|
|
||||||
struct draw_context *draw;
|
|
||||||
|
|
||||||
uint32_t dirty;
|
|
||||||
|
|
||||||
struct nv10_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
|
|
||||||
struct nv10_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
|
|
||||||
unsigned dirty_samplers;
|
|
||||||
unsigned fp_samplers;
|
|
||||||
unsigned vp_samplers;
|
|
||||||
|
|
||||||
uint32_t rt_enable;
|
|
||||||
struct pipe_buffer *rt[4];
|
|
||||||
struct pipe_buffer *zeta;
|
|
||||||
uint32_t lma_offset;
|
|
||||||
|
|
||||||
struct nv10_blend_state *blend;
|
|
||||||
struct pipe_blend_color *blend_color;
|
|
||||||
struct nv10_rasterizer_state *rast;
|
|
||||||
struct nv10_depth_stencil_alpha_state *dsa;
|
|
||||||
struct pipe_viewport_state *viewport;
|
|
||||||
struct pipe_scissor_state *scissor;
|
|
||||||
struct pipe_framebuffer_state *framebuffer;
|
|
||||||
|
|
||||||
//struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
|
|
||||||
float *constbuf[PIPE_SHADER_TYPES][32][4];
|
|
||||||
unsigned constbuf_nr[PIPE_SHADER_TYPES];
|
|
||||||
|
|
||||||
struct vertex_info vertex_info;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
uint32_t format;
|
|
||||||
} tex[2];
|
|
||||||
|
|
||||||
unsigned vb_enable;
|
|
||||||
struct {
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
unsigned delta;
|
|
||||||
} vb[16];
|
|
||||||
|
|
||||||
/* struct {
|
|
||||||
|
|
||||||
struct nouveau_resource *exec_heap;
|
|
||||||
struct nouveau_resource *data_heap;
|
|
||||||
|
|
||||||
struct nv10_vertex_program *active;
|
|
||||||
|
|
||||||
struct nv10_vertex_program *current;
|
|
||||||
} vertprog;
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
struct nv10_fragment_program *active;
|
|
||||||
|
|
||||||
struct nv10_fragment_program *current;
|
|
||||||
struct pipe_buffer *constant_buf;
|
|
||||||
} fragprog;
|
|
||||||
|
|
||||||
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
|
|
||||||
struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE struct nv10_context *
|
|
||||||
nv10_context(struct pipe_context *pipe)
|
|
||||||
{
|
|
||||||
return (struct nv10_context *)pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void nv10_init_state_functions(struct nv10_context *nv10);
|
|
||||||
extern void nv10_init_surface_functions(struct nv10_context *nv10);
|
|
||||||
|
|
||||||
extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen);
|
|
||||||
|
|
||||||
/* nv10_clear.c */
|
|
||||||
extern void nv10_clear(struct pipe_context *pipe, unsigned buffers,
|
|
||||||
const float *rgba, double depth, unsigned stencil);
|
|
||||||
|
|
||||||
|
|
||||||
/* nv10_draw.c */
|
|
||||||
extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10);
|
|
||||||
|
|
||||||
/* nv10_fragprog.c */
|
|
||||||
extern void nv10_fragprog_bind(struct nv10_context *,
|
|
||||||
struct nv10_fragment_program *);
|
|
||||||
extern void nv10_fragprog_destroy(struct nv10_context *,
|
|
||||||
struct nv10_fragment_program *);
|
|
||||||
|
|
||||||
/* nv10_fragtex.c */
|
|
||||||
extern void nv10_fragtex_bind(struct nv10_context *);
|
|
||||||
|
|
||||||
/* nv10_prim_vbuf.c */
|
|
||||||
struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 );
|
|
||||||
extern void nv10_vtxbuf_bind(struct nv10_context* nv10);
|
|
||||||
|
|
||||||
/* nv10_state.c and friends */
|
|
||||||
extern void nv10_emit_hw_state(struct nv10_context *nv10);
|
|
||||||
extern void nv10_state_tex_update(struct nv10_context *nv10);
|
|
||||||
|
|
||||||
/* nv10_vbo.c */
|
|
||||||
extern void nv10_draw_arrays(struct pipe_context *, unsigned mode,
|
|
||||||
unsigned start, unsigned count);
|
|
||||||
extern void nv10_draw_elements( struct pipe_context *pipe,
|
|
||||||
struct pipe_buffer *indexBuffer,
|
|
||||||
unsigned indexSize,
|
|
||||||
unsigned prim, unsigned start, unsigned count);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
|
|
||||||
#include "pipe/p_shader_tokens.h"
|
|
||||||
#include "tgsi/tgsi_parse.h"
|
|
||||||
#include "tgsi/tgsi_util.h"
|
|
||||||
|
|
||||||
#include "nv10_context.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
nv10_fragprog_bind(struct nv10_context *nv10, struct nv10_fragment_program *fp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv10_fragprog_destroy(struct nv10_context *nv10,
|
|
||||||
struct nv10_fragment_program *fp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,130 +0,0 @@
|
||||||
#include "nv10_context.h"
|
|
||||||
#include "nouveau/nouveau_util.h"
|
|
||||||
|
|
||||||
#define _(m,tf) \
|
|
||||||
{ \
|
|
||||||
TRUE, \
|
|
||||||
PIPE_FORMAT_##m, \
|
|
||||||
NV10TCL_TX_FORMAT_FORMAT_##tf, \
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nv10_texture_format {
|
|
||||||
boolean defined;
|
|
||||||
uint pipe;
|
|
||||||
int format;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct nv10_texture_format
|
|
||||||
nv10_texture_formats[] = {
|
|
||||||
_(A8R8G8B8_UNORM, A8R8G8B8),
|
|
||||||
_(A1R5G5B5_UNORM, A1R5G5B5),
|
|
||||||
_(A4R4G4B4_UNORM, A4R4G4B4),
|
|
||||||
_(L8_UNORM , L8 ),
|
|
||||||
_(A8_UNORM , A8 ),
|
|
||||||
_(A8L8_UNORM , A8L8 ),
|
|
||||||
// _(RGB_DXT1 , DXT1, ),
|
|
||||||
// _(RGBA_DXT1 , DXT1, ),
|
|
||||||
// _(RGBA_DXT3 , DXT3, ),
|
|
||||||
// _(RGBA_DXT5 , DXT5, ),
|
|
||||||
{},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct nv10_texture_format *
|
|
||||||
nv10_fragtex_format(uint pipe_format)
|
|
||||||
{
|
|
||||||
struct nv10_texture_format *tf = nv10_texture_formats;
|
|
||||||
|
|
||||||
while (tf->defined) {
|
|
||||||
if (tf->pipe == pipe_format)
|
|
||||||
return tf;
|
|
||||||
tf++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_fragtex_build(struct nv10_context *nv10, int unit)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
struct nv10_sampler_state *ps = nv10->tex_sampler[unit];
|
|
||||||
struct nv10_miptree *nv10mt = nv10->tex_miptree[unit];
|
|
||||||
struct pipe_texture *pt = &nv10mt->base;
|
|
||||||
struct nv10_texture_format *tf;
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
uint32_t txf, txs, txp;
|
|
||||||
|
|
||||||
tf = nv10_fragtex_format(pt->format);
|
|
||||||
if (!tf || !tf->defined) {
|
|
||||||
NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
txf = tf->format << 8;
|
|
||||||
txf |= (pt->last_level + 1) << 16;
|
|
||||||
txf |= log2i(pt->width0) << 20;
|
|
||||||
txf |= log2i(pt->height0) << 24;
|
|
||||||
txf |= log2i(pt->depth0) << 28;
|
|
||||||
txf |= 8;
|
|
||||||
|
|
||||||
switch (pt->target) {
|
|
||||||
case PIPE_TEXTURE_CUBE:
|
|
||||||
txf |= NV10TCL_TX_FORMAT_CUBE_MAP;
|
|
||||||
/* fall-through */
|
|
||||||
case PIPE_TEXTURE_2D:
|
|
||||||
txf |= (2<<4);
|
|
||||||
break;
|
|
||||||
case PIPE_TEXTURE_1D:
|
|
||||||
txf |= (1<<4);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("Unknown target %d\n", pt->target);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_TX_OFFSET(unit), 8);
|
|
||||||
OUT_RELOCl(chan, nouveau_bo(nv10mt->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
|
||||||
OUT_RELOCd(chan, nouveau_bo(nv10mt->buffer),txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
|
|
||||||
OUT_RING (chan, ps->wrap);
|
|
||||||
OUT_RING (chan, 0x40000000); /* enable */
|
|
||||||
OUT_RING (chan, txs);
|
|
||||||
OUT_RING (chan, ps->filt | 0x2000 /* magic */);
|
|
||||||
OUT_RING (chan, (pt->width0 << 16) | pt->height0);
|
|
||||||
OUT_RING (chan, ps->bcol);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv10_fragtex_bind(struct nv10_context *nv10)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
struct nv10_fragment_program *fp = nv10->fragprog.active;
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
unsigned samplers, unit;
|
|
||||||
|
|
||||||
samplers = nv10->fp_samplers & ~fp->samplers;
|
|
||||||
while (samplers) {
|
|
||||||
unit = ffs(samplers) - 1;
|
|
||||||
samplers &= ~(1 << unit);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(unit), 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
samplers = nv10->dirty_samplers & fp->samplers;
|
|
||||||
while (samplers) {
|
|
||||||
unit = ffs(samplers) - 1;
|
|
||||||
samplers &= ~(1 << unit);
|
|
||||||
|
|
||||||
nv10_fragtex_build(nv10, unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
nv10->fp_samplers = fp->samplers;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,165 +0,0 @@
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_format.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
|
|
||||||
#include "nv10_context.h"
|
|
||||||
#include "nv10_screen.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_miptree_layout(struct nv10_miptree *nv10mt)
|
|
||||||
{
|
|
||||||
struct pipe_texture *pt = &nv10mt->base;
|
|
||||||
boolean swizzled = FALSE;
|
|
||||||
uint width = pt->width0;
|
|
||||||
uint offset = 0;
|
|
||||||
int nr_faces, l, f;
|
|
||||||
|
|
||||||
if (pt->target == PIPE_TEXTURE_CUBE) {
|
|
||||||
nr_faces = 6;
|
|
||||||
} else {
|
|
||||||
nr_faces = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (l = 0; l <= pt->last_level; l++) {
|
|
||||||
if (swizzled)
|
|
||||||
nv10mt->level[l].pitch = util_format_get_stride(pt->format, width);
|
|
||||||
else
|
|
||||||
nv10mt->level[l].pitch = util_format_get_stride(pt->format, pt->width0);
|
|
||||||
nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63;
|
|
||||||
|
|
||||||
nv10mt->level[l].image_offset =
|
|
||||||
CALLOC(nr_faces, sizeof(unsigned));
|
|
||||||
|
|
||||||
width = u_minify(width, 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
for (f = 0; f < nr_faces; f++) {
|
|
||||||
for (l = 0; l <= pt->last_level; l++) {
|
|
||||||
nv10mt->level[l].image_offset[f] = offset;
|
|
||||||
offset += nv10mt->level[l].pitch * u_minify(pt->height0, l);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nv10mt->total_size = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_texture *
|
|
||||||
nv10_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
|
|
||||||
const unsigned *stride, struct pipe_buffer *pb)
|
|
||||||
{
|
|
||||||
struct nv10_miptree *mt;
|
|
||||||
|
|
||||||
/* Only supports 2D, non-mipmapped textures for the moment */
|
|
||||||
if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
|
|
||||||
pt->depth0 != 1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mt = CALLOC_STRUCT(nv10_miptree);
|
|
||||||
if (!mt)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mt->base = *pt;
|
|
||||||
pipe_reference_init(&mt->base.reference, 1);
|
|
||||||
mt->base.screen = pscreen;
|
|
||||||
mt->level[0].pitch = stride[0];
|
|
||||||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
|
|
||||||
|
|
||||||
pipe_buffer_reference(&mt->buffer, pb);
|
|
||||||
mt->bo = nouveau_bo(mt->buffer);
|
|
||||||
return &mt->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_texture *
|
|
||||||
nv10_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt)
|
|
||||||
{
|
|
||||||
struct nv10_miptree *mt;
|
|
||||||
|
|
||||||
mt = MALLOC(sizeof(struct nv10_miptree));
|
|
||||||
if (!mt)
|
|
||||||
return NULL;
|
|
||||||
mt->base = *pt;
|
|
||||||
pipe_reference_init(&mt->base.reference, 1);
|
|
||||||
mt->base.screen = screen;
|
|
||||||
|
|
||||||
nv10_miptree_layout(mt);
|
|
||||||
|
|
||||||
mt->buffer = screen->buffer_create(screen, 256, PIPE_BUFFER_USAGE_PIXEL,
|
|
||||||
mt->total_size);
|
|
||||||
if (!mt->buffer) {
|
|
||||||
FREE(mt);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
mt->bo = nouveau_bo(mt->buffer);
|
|
||||||
|
|
||||||
return &mt->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_miptree_destroy(struct pipe_texture *pt)
|
|
||||||
{
|
|
||||||
struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt;
|
|
||||||
int l;
|
|
||||||
|
|
||||||
pipe_buffer_reference(&nv10mt->buffer, NULL);
|
|
||||||
for (l = 0; l <= pt->last_level; l++) {
|
|
||||||
if (nv10mt->level[l].image_offset)
|
|
||||||
FREE(nv10mt->level[l].image_offset);
|
|
||||||
}
|
|
||||||
FREE(nv10mt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt,
|
|
||||||
uint face, uint levels)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct pipe_surface *
|
|
||||||
nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt,
|
|
||||||
unsigned face, unsigned level, unsigned zslice,
|
|
||||||
unsigned flags)
|
|
||||||
{
|
|
||||||
struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt;
|
|
||||||
struct nv04_surface *ns;
|
|
||||||
|
|
||||||
ns = CALLOC_STRUCT(nv04_surface);
|
|
||||||
if (!ns)
|
|
||||||
return NULL;
|
|
||||||
pipe_texture_reference(&ns->base.texture, pt);
|
|
||||||
ns->base.format = pt->format;
|
|
||||||
ns->base.width = u_minify(pt->width0, level);
|
|
||||||
ns->base.height = u_minify(pt->height0, level);
|
|
||||||
ns->base.usage = flags;
|
|
||||||
pipe_reference_init(&ns->base.reference, 1);
|
|
||||||
ns->base.face = face;
|
|
||||||
ns->base.level = level;
|
|
||||||
ns->base.zslice = zslice;
|
|
||||||
ns->pitch = nv10mt->level[level].pitch;
|
|
||||||
|
|
||||||
if (pt->target == PIPE_TEXTURE_CUBE) {
|
|
||||||
ns->base.offset = nv10mt->level[level].image_offset[face];
|
|
||||||
} else {
|
|
||||||
ns->base.offset = nv10mt->level[level].image_offset[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ns->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_miptree_surface_destroy(struct pipe_surface *surface)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen)
|
|
||||||
{
|
|
||||||
pscreen->texture_create = nv10_miptree_create;
|
|
||||||
pscreen->texture_blanket = nv10_miptree_blanket;
|
|
||||||
pscreen->texture_destroy = nv10_miptree_destroy;
|
|
||||||
pscreen->get_tex_surface = nv10_miptree_surface_get;
|
|
||||||
pscreen->tex_surface_destroy = nv10_miptree_surface_destroy;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,267 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
||||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Build post-transformation, post-clipping vertex buffers and element
|
|
||||||
* lists by hooking into the end of the primitive pipeline and
|
|
||||||
* manipulating the vertex_id field in the vertex headers.
|
|
||||||
*
|
|
||||||
* XXX: work in progress
|
|
||||||
*
|
|
||||||
* \author José Fonseca <jrfonseca@tungstengraphics.com>
|
|
||||||
* \author Keith Whitwell <keith@tungstengraphics.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "util/u_debug.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "nv10_context.h"
|
|
||||||
#include "nv10_state.h"
|
|
||||||
|
|
||||||
#include "draw/draw_vbuf.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primitive renderer for nv10.
|
|
||||||
*/
|
|
||||||
struct nv10_vbuf_render {
|
|
||||||
struct vbuf_render base;
|
|
||||||
|
|
||||||
struct nv10_context *nv10;
|
|
||||||
|
|
||||||
/** Vertex buffer */
|
|
||||||
struct pipe_buffer* buffer;
|
|
||||||
|
|
||||||
/** Vertex size in bytes */
|
|
||||||
unsigned vertex_size;
|
|
||||||
|
|
||||||
/** Hardware primitive */
|
|
||||||
unsigned hwprim;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void nv10_vtxbuf_bind( struct nv10_context* nv10 )
|
|
||||||
{
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 8; i++) {
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VTXBUF_ADDRESS(i), 1);
|
|
||||||
OUT_RING(chan, 0/*nv10->vtxbuf*/);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VTXFMT(i), 1);
|
|
||||||
OUT_RING(chan, 0/*XXX*/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basically a cast wrapper.
|
|
||||||
*/
|
|
||||||
static INLINE struct nv10_vbuf_render *
|
|
||||||
nv10_vbuf_render( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
assert(render);
|
|
||||||
return (struct nv10_vbuf_render *)render;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const struct vertex_info *
|
|
||||||
nv10_vbuf_render_get_vertex_info( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
|
|
||||||
struct nv10_context *nv10 = nv10_render->nv10;
|
|
||||||
|
|
||||||
nv10_emit_hw_state(nv10);
|
|
||||||
|
|
||||||
return &nv10->vertex_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv10_vbuf_render_allocate_vertices( struct vbuf_render *render,
|
|
||||||
ushort vertex_size,
|
|
||||||
ushort nr_vertices )
|
|
||||||
{
|
|
||||||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
|
|
||||||
struct nv10_context *nv10 = nv10_render->nv10;
|
|
||||||
struct pipe_screen *screen = nv10->pipe.screen;
|
|
||||||
size_t size = (size_t)vertex_size * (size_t)nr_vertices;
|
|
||||||
|
|
||||||
assert(!nv10_render->buffer);
|
|
||||||
nv10_render->buffer = screen->buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX, size);
|
|
||||||
|
|
||||||
nv10->dirty |= NV10_NEW_VTXARRAYS;
|
|
||||||
|
|
||||||
if (nv10_render->buffer)
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv10_vbuf_render_map_vertices( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
|
|
||||||
struct nv10_context *nv10 = nv10_render->nv10;
|
|
||||||
struct pipe_screen *pscreen = nv10->pipe.screen;
|
|
||||||
|
|
||||||
return pipe_buffer_map(pscreen, nv10_render->buffer,
|
|
||||||
PIPE_BUFFER_USAGE_CPU_WRITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_vbuf_render_unmap_vertices( struct vbuf_render *render,
|
|
||||||
ushort min_index,
|
|
||||||
ushort max_index )
|
|
||||||
{
|
|
||||||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
|
|
||||||
struct nv10_context *nv10 = nv10_render->nv10;
|
|
||||||
struct pipe_screen *pscreen = nv10->pipe.screen;
|
|
||||||
|
|
||||||
assert(!nv10_render->buffer);
|
|
||||||
pipe_buffer_unmap(pscreen, nv10_render->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv10_vbuf_render_set_primitive( struct vbuf_render *render,
|
|
||||||
unsigned prim )
|
|
||||||
{
|
|
||||||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
|
|
||||||
unsigned hwp = nvgl_primitive(prim);
|
|
||||||
if (hwp == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
nv10_render->hwprim = hwp;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_vbuf_render_draw( struct vbuf_render *render,
|
|
||||||
const ushort *indices,
|
|
||||||
uint nr_indices)
|
|
||||||
{
|
|
||||||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
|
|
||||||
struct nv10_context *nv10 = nv10_render->nv10;
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
int push, i;
|
|
||||||
|
|
||||||
nv10_emit_hw_state(nv10);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1);
|
|
||||||
OUT_RELOCl(chan, nouveau_bo(nv10_render->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
|
|
||||||
OUT_RING(chan, nv10_render->hwprim);
|
|
||||||
|
|
||||||
if (nr_indices & 1) {
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VB_ELEMENT_U32, 1);
|
|
||||||
OUT_RING (chan, indices[0]);
|
|
||||||
indices++; nr_indices--;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (nr_indices) {
|
|
||||||
// XXX too big/small ? check the size
|
|
||||||
push = MIN2(nr_indices, 1200 * 2);
|
|
||||||
|
|
||||||
BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U16, push >> 1);
|
|
||||||
for (i = 0; i < push; i+=2)
|
|
||||||
OUT_RING(chan, (indices[i+1] << 16) | indices[i]);
|
|
||||||
|
|
||||||
nr_indices -= push;
|
|
||||||
indices += push;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_vbuf_render_release_vertices( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
|
|
||||||
|
|
||||||
assert(nv10_render->buffer);
|
|
||||||
pipe_buffer_reference(&nv10_render->buffer, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_vbuf_render_destroy( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
|
|
||||||
FREE(nv10_render);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new primitive render.
|
|
||||||
*/
|
|
||||||
static struct vbuf_render *
|
|
||||||
nv10_vbuf_render_create( struct nv10_context *nv10 )
|
|
||||||
{
|
|
||||||
struct nv10_vbuf_render *nv10_render = CALLOC_STRUCT(nv10_vbuf_render);
|
|
||||||
|
|
||||||
nv10_render->nv10 = nv10;
|
|
||||||
|
|
||||||
nv10_render->base.max_vertex_buffer_bytes = 16*1024;
|
|
||||||
nv10_render->base.max_indices = 1024;
|
|
||||||
nv10_render->base.get_vertex_info = nv10_vbuf_render_get_vertex_info;
|
|
||||||
nv10_render->base.allocate_vertices = nv10_vbuf_render_allocate_vertices;
|
|
||||||
nv10_render->base.map_vertices = nv10_vbuf_render_map_vertices;
|
|
||||||
nv10_render->base.unmap_vertices = nv10_vbuf_render_unmap_vertices;
|
|
||||||
nv10_render->base.set_primitive = nv10_vbuf_render_set_primitive;
|
|
||||||
nv10_render->base.draw = nv10_vbuf_render_draw;
|
|
||||||
nv10_render->base.release_vertices = nv10_vbuf_render_release_vertices;
|
|
||||||
nv10_render->base.destroy = nv10_vbuf_render_destroy;
|
|
||||||
|
|
||||||
return &nv10_render->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new primitive vbuf/render stage.
|
|
||||||
*/
|
|
||||||
struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 )
|
|
||||||
{
|
|
||||||
struct vbuf_render *render;
|
|
||||||
struct draw_stage *stage;
|
|
||||||
|
|
||||||
render = nv10_vbuf_render_create(nv10);
|
|
||||||
if(!render)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
stage = draw_vbuf_stage( nv10->draw, render );
|
|
||||||
if(!stage) {
|
|
||||||
render->destroy(render);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stage;
|
|
||||||
}
|
|
||||||
|
|
@ -1,208 +0,0 @@
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
|
|
||||||
#include "nv10_context.h"
|
|
||||||
#include "nv10_screen.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
nv10_screen_get_param(struct pipe_screen *screen, int param)
|
|
||||||
{
|
|
||||||
switch (param) {
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
|
|
||||||
return 2;
|
|
||||||
case PIPE_CAP_NPOT_TEXTURES:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TWO_SIDED_STENCIL:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_GLSL:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_POINT_SPRITE:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_OCCLUSION_QUERY:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
|
||||||
return 12;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
|
||||||
return 12;
|
|
||||||
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TGSI_CONT_SUPPORTED:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
|
||||||
return 0;
|
|
||||||
case NOUVEAU_CAP_HW_VTXBUF:
|
|
||||||
case NOUVEAU_CAP_HW_IDXBUF:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_INDEP_BLEND_FUNC:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static float
|
|
||||||
nv10_screen_get_paramf(struct pipe_screen *screen, int param)
|
|
||||||
{
|
|
||||||
switch (param) {
|
|
||||||
case PIPE_CAP_MAX_LINE_WIDTH:
|
|
||||||
case PIPE_CAP_MAX_LINE_WIDTH_AA:
|
|
||||||
return 10.0;
|
|
||||||
case PIPE_CAP_MAX_POINT_WIDTH:
|
|
||||||
case PIPE_CAP_MAX_POINT_WIDTH_AA:
|
|
||||||
return 64.0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
|
|
||||||
return 2.0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
|
|
||||||
return 4.0;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv10_screen_is_format_supported(struct pipe_screen *screen,
|
|
||||||
enum pipe_format format,
|
|
||||||
enum pipe_texture_target target,
|
|
||||||
unsigned tex_usage, unsigned geom_flags)
|
|
||||||
{
|
|
||||||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_Z24S8_UNORM:
|
|
||||||
case PIPE_FORMAT_Z24X8_UNORM:
|
|
||||||
case PIPE_FORMAT_Z16_UNORM:
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case PIPE_FORMAT_A1R5G5B5_UNORM:
|
|
||||||
case PIPE_FORMAT_A4R4G4B4_UNORM:
|
|
||||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
|
||||||
case PIPE_FORMAT_L8_UNORM:
|
|
||||||
case PIPE_FORMAT_A8_UNORM:
|
|
||||||
case PIPE_FORMAT_I8_UNORM:
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_screen_destroy(struct pipe_screen *pscreen)
|
|
||||||
{
|
|
||||||
struct nv10_screen *screen = nv10_screen(pscreen);
|
|
||||||
|
|
||||||
nouveau_notifier_free(&screen->sync);
|
|
||||||
nouveau_grobj_free(&screen->celsius);
|
|
||||||
nv04_surface_2d_takedown(&screen->eng2d);
|
|
||||||
|
|
||||||
nouveau_screen_fini(&screen->base);
|
|
||||||
|
|
||||||
FREE(pscreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_buffer *
|
|
||||||
nv10_surface_buffer(struct pipe_surface *surf)
|
|
||||||
{
|
|
||||||
struct nv10_miptree *mt = (struct nv10_miptree *)surf->texture;
|
|
||||||
|
|
||||||
return mt->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pipe_screen *
|
|
||||||
nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
|
|
||||||
{
|
|
||||||
struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen);
|
|
||||||
struct nouveau_channel *chan;
|
|
||||||
struct pipe_screen *pscreen;
|
|
||||||
unsigned celsius_class;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!screen)
|
|
||||||
return NULL;
|
|
||||||
pscreen = &screen->base.base;
|
|
||||||
|
|
||||||
ret = nouveau_screen_init(&screen->base, dev);
|
|
||||||
if (ret) {
|
|
||||||
nv10_screen_destroy(pscreen);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
chan = screen->base.channel;
|
|
||||||
|
|
||||||
pscreen->winsys = ws;
|
|
||||||
pscreen->destroy = nv10_screen_destroy;
|
|
||||||
pscreen->get_param = nv10_screen_get_param;
|
|
||||||
pscreen->get_paramf = nv10_screen_get_paramf;
|
|
||||||
pscreen->is_format_supported = nv10_screen_is_format_supported;
|
|
||||||
|
|
||||||
nv10_screen_init_miptree_functions(pscreen);
|
|
||||||
nv10_screen_init_transfer_functions(pscreen);
|
|
||||||
|
|
||||||
/* 3D object */
|
|
||||||
if (dev->chipset >= 0x20)
|
|
||||||
celsius_class = NV11TCL;
|
|
||||||
else if (dev->chipset >= 0x17)
|
|
||||||
celsius_class = NV17TCL;
|
|
||||||
else if (dev->chipset >= 0x11)
|
|
||||||
celsius_class = NV11TCL;
|
|
||||||
else
|
|
||||||
celsius_class = NV10TCL;
|
|
||||||
|
|
||||||
if (!celsius_class) {
|
|
||||||
NOUVEAU_ERR("Unknown nv1x chipset: nv%02x\n", dev->chipset);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nouveau_grobj_alloc(chan, 0xbeef0001, celsius_class,
|
|
||||||
&screen->celsius);
|
|
||||||
if (ret) {
|
|
||||||
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 2D engine setup */
|
|
||||||
screen->eng2d = nv04_surface_2d_init(&screen->base);
|
|
||||||
screen->eng2d->buf = nv10_surface_buffer;
|
|
||||||
|
|
||||||
/* Notifier for sync purposes */
|
|
||||||
ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
|
|
||||||
if (ret) {
|
|
||||||
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
|
|
||||||
nv10_screen_destroy(pscreen);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pscreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef __NV10_SCREEN_H__
|
|
||||||
#define __NV10_SCREEN_H__
|
|
||||||
|
|
||||||
#include "nouveau/nouveau_screen.h"
|
|
||||||
#include "nv04/nv04_surface_2d.h"
|
|
||||||
|
|
||||||
struct nv10_screen {
|
|
||||||
struct nouveau_screen base;
|
|
||||||
|
|
||||||
struct nouveau_winsys *nvws;
|
|
||||||
|
|
||||||
/* HW graphics objects */
|
|
||||||
struct nv04_surface_2d *eng2d;
|
|
||||||
struct nouveau_grobj *celsius;
|
|
||||||
struct nouveau_notifier *sync;
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE struct nv10_screen *
|
|
||||||
nv10_screen(struct pipe_screen *screen)
|
|
||||||
{
|
|
||||||
return (struct nv10_screen *)screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
nv10_screen_init_transfer_functions(struct pipe_screen *pscreen);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,590 +0,0 @@
|
||||||
#include "draw/draw_context.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_shader_tokens.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "tgsi/tgsi_parse.h"
|
|
||||||
|
|
||||||
#include "nv10_context.h"
|
|
||||||
#include "nv10_state.h"
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv10_blend_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_blend_state *cso)
|
|
||||||
{
|
|
||||||
struct nv10_blend_state *cb;
|
|
||||||
|
|
||||||
cb = MALLOC(sizeof(struct nv10_blend_state));
|
|
||||||
|
|
||||||
cb->b_enable = cso->rt[0].blend_enable ? 1 : 0;
|
|
||||||
cb->b_srcfunc = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) |
|
|
||||||
(nvgl_blend_func(cso->rt[0].rgb_src_factor)));
|
|
||||||
cb->b_dstfunc = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) |
|
|
||||||
(nvgl_blend_func(cso->rt[0].rgb_dst_factor)));
|
|
||||||
|
|
||||||
cb->c_mask = (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01<<24) : 0) |
|
|
||||||
((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01<<16) : 0) |
|
|
||||||
((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) |
|
|
||||||
((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01<< 0) : 0));
|
|
||||||
|
|
||||||
cb->d_enable = cso->dither ? 1 : 0;
|
|
||||||
|
|
||||||
return (void *)cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_blend_state_bind(struct pipe_context *pipe, void *blend)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
nv10->blend = (struct nv10_blend_state*)blend;
|
|
||||||
|
|
||||||
nv10->dirty |= NV10_NEW_BLEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
FREE(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE unsigned
|
|
||||||
wrap_mode(unsigned wrap) {
|
|
||||||
unsigned ret;
|
|
||||||
|
|
||||||
switch (wrap) {
|
|
||||||
case PIPE_TEX_WRAP_REPEAT:
|
|
||||||
ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_REPEAT:
|
|
||||||
ret = NV10TCL_TX_FORMAT_WRAP_S_MIRRORED_REPEAT;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
|
|
||||||
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
|
|
||||||
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_BORDER;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_CLAMP:
|
|
||||||
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_CLAMP:
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
|
|
||||||
ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret >> NV10TCL_TX_FORMAT_WRAP_S_SHIFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv10_sampler_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_sampler_state *cso)
|
|
||||||
{
|
|
||||||
struct nv10_sampler_state *ps;
|
|
||||||
uint32_t filter = 0;
|
|
||||||
|
|
||||||
ps = MALLOC(sizeof(struct nv10_sampler_state));
|
|
||||||
|
|
||||||
ps->wrap = ((wrap_mode(cso->wrap_s) << NV10TCL_TX_FORMAT_WRAP_S_SHIFT) |
|
|
||||||
(wrap_mode(cso->wrap_t) << NV10TCL_TX_FORMAT_WRAP_T_SHIFT));
|
|
||||||
|
|
||||||
ps->en = 0;
|
|
||||||
if (cso->max_anisotropy > 1.0) {
|
|
||||||
/* no idea, binary driver sets it, works without it.. meh.. */
|
|
||||||
ps->wrap |= (1 << 5);
|
|
||||||
|
|
||||||
/* if (cso->max_anisotropy >= 16.0) {
|
|
||||||
ps->en |= NV10TCL_TX_ENABLE_ANISO_16X;
|
|
||||||
} else
|
|
||||||
if (cso->max_anisotropy >= 12.0) {
|
|
||||||
ps->en |= NV10TCL_TX_ENABLE_ANISO_12X;
|
|
||||||
} else
|
|
||||||
if (cso->max_anisotropy >= 10.0) {
|
|
||||||
ps->en |= NV10TCL_TX_ENABLE_ANISO_10X;
|
|
||||||
} else
|
|
||||||
if (cso->max_anisotropy >= 8.0) {
|
|
||||||
ps->en |= NV10TCL_TX_ENABLE_ANISO_8X;
|
|
||||||
} else
|
|
||||||
if (cso->max_anisotropy >= 6.0) {
|
|
||||||
ps->en |= NV10TCL_TX_ENABLE_ANISO_6X;
|
|
||||||
} else
|
|
||||||
if (cso->max_anisotropy >= 4.0) {
|
|
||||||
ps->en |= NV10TCL_TX_ENABLE_ANISO_4X;
|
|
||||||
} else {
|
|
||||||
ps->en |= NV10TCL_TX_ENABLE_ANISO_2X;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cso->mag_img_filter) {
|
|
||||||
case PIPE_TEX_FILTER_LINEAR:
|
|
||||||
filter |= NV10TCL_TX_FILTER_MAGNIFY_LINEAR;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_FILTER_NEAREST:
|
|
||||||
default:
|
|
||||||
filter |= NV10TCL_TX_FILTER_MAGNIFY_NEAREST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cso->min_img_filter) {
|
|
||||||
case PIPE_TEX_FILTER_LINEAR:
|
|
||||||
switch (cso->min_mip_filter) {
|
|
||||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
|
||||||
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
|
||||||
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_NONE:
|
|
||||||
default:
|
|
||||||
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_FILTER_NEAREST:
|
|
||||||
default:
|
|
||||||
switch (cso->min_mip_filter) {
|
|
||||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
|
||||||
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
|
||||||
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_NONE:
|
|
||||||
default:
|
|
||||||
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ps->filt = filter;
|
|
||||||
|
|
||||||
/* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
|
|
||||||
switch (cso->compare_func) {
|
|
||||||
case PIPE_FUNC_NEVER:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_GREATER:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_EQUAL:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_GEQUAL:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_LESS:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_NOTEQUAL:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_LEQUAL:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_ALWAYS:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
|
|
||||||
(float_to_ubyte(cso->border_color[0]) << 16) |
|
|
||||||
(float_to_ubyte(cso->border_color[1]) << 8) |
|
|
||||||
(float_to_ubyte(cso->border_color[2]) << 0));
|
|
||||||
|
|
||||||
return (void *)ps;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
unsigned unit;
|
|
||||||
|
|
||||||
for (unit = 0; unit < nr; unit++) {
|
|
||||||
nv10->tex_sampler[unit] = sampler[unit];
|
|
||||||
nv10->dirty_samplers |= (1 << unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
FREE(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
|
|
||||||
struct pipe_texture **miptree)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
unsigned unit;
|
|
||||||
|
|
||||||
for (unit = 0; unit < nr; unit++) {
|
|
||||||
nv10->tex_miptree[unit] = (struct nv10_miptree *)miptree[unit];
|
|
||||||
nv10->dirty_samplers |= (1 << unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv10_rasterizer_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_rasterizer_state *cso)
|
|
||||||
{
|
|
||||||
struct nv10_rasterizer_state *rs;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/*XXX: ignored:
|
|
||||||
* light_twoside
|
|
||||||
* offset_cw/ccw -nohw
|
|
||||||
* scissor
|
|
||||||
* point_smooth -nohw
|
|
||||||
* multisample
|
|
||||||
* offset_units / offset_scale
|
|
||||||
*/
|
|
||||||
rs = MALLOC(sizeof(struct nv10_rasterizer_state));
|
|
||||||
|
|
||||||
rs->templ = cso;
|
|
||||||
|
|
||||||
rs->shade_model = cso->flatshade ? 0x1d00 : 0x1d01;
|
|
||||||
|
|
||||||
rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff;
|
|
||||||
rs->line_smooth_en = cso->line_smooth ? 1 : 0;
|
|
||||||
|
|
||||||
rs->point_size = *(uint32_t*)&cso->point_size;
|
|
||||||
|
|
||||||
rs->poly_smooth_en = cso->poly_smooth ? 1 : 0;
|
|
||||||
|
|
||||||
if (cso->front_winding == PIPE_WINDING_CCW) {
|
|
||||||
rs->front_face = NV10TCL_FRONT_FACE_CCW;
|
|
||||||
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw);
|
|
||||||
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw);
|
|
||||||
} else {
|
|
||||||
rs->front_face = NV10TCL_FRONT_FACE_CW;
|
|
||||||
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw);
|
|
||||||
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cso->cull_mode) {
|
|
||||||
case PIPE_WINDING_CCW:
|
|
||||||
rs->cull_face_en = 1;
|
|
||||||
if (cso->front_winding == PIPE_WINDING_CCW)
|
|
||||||
rs->cull_face = NV10TCL_CULL_FACE_FRONT;
|
|
||||||
else
|
|
||||||
rs->cull_face = NV10TCL_CULL_FACE_BACK;
|
|
||||||
break;
|
|
||||||
case PIPE_WINDING_CW:
|
|
||||||
rs->cull_face_en = 1;
|
|
||||||
if (cso->front_winding == PIPE_WINDING_CW)
|
|
||||||
rs->cull_face = NV10TCL_CULL_FACE_FRONT;
|
|
||||||
else
|
|
||||||
rs->cull_face = NV10TCL_CULL_FACE_BACK;
|
|
||||||
break;
|
|
||||||
case PIPE_WINDING_BOTH:
|
|
||||||
rs->cull_face_en = 1;
|
|
||||||
rs->cull_face = NV10TCL_CULL_FACE_FRONT_AND_BACK;
|
|
||||||
break;
|
|
||||||
case PIPE_WINDING_NONE:
|
|
||||||
default:
|
|
||||||
rs->cull_face_en = 0;
|
|
||||||
rs->cull_face = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cso->point_sprite) {
|
|
||||||
rs->point_sprite = (1 << 0);
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE)
|
|
||||||
rs->point_sprite |= (1 << (8 + i));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rs->point_sprite = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (void *)rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_rasterizer_state_bind(struct pipe_context *pipe, void *rast)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
nv10->rast = (struct nv10_rasterizer_state*)rast;
|
|
||||||
|
|
||||||
draw_set_rasterizer_state(nv10->draw, (nv10->rast ? nv10->rast->templ : NULL));
|
|
||||||
|
|
||||||
nv10->dirty |= NV10_NEW_RAST;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
FREE(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_depth_stencil_alpha_state *cso)
|
|
||||||
{
|
|
||||||
struct nv10_depth_stencil_alpha_state *hw;
|
|
||||||
|
|
||||||
hw = MALLOC(sizeof(struct nv10_depth_stencil_alpha_state));
|
|
||||||
|
|
||||||
hw->depth.func = nvgl_comparison_op(cso->depth.func);
|
|
||||||
hw->depth.write_enable = cso->depth.writemask ? 1 : 0;
|
|
||||||
hw->depth.test_enable = cso->depth.enabled ? 1 : 0;
|
|
||||||
|
|
||||||
hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0;
|
|
||||||
hw->stencil.wmask = cso->stencil[0].writemask;
|
|
||||||
hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func);
|
|
||||||
hw->stencil.ref = cso->stencil[0].ref_value;
|
|
||||||
hw->stencil.vmask = cso->stencil[0].valuemask;
|
|
||||||
hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op);
|
|
||||||
hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op);
|
|
||||||
hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op);
|
|
||||||
|
|
||||||
hw->alpha.enabled = cso->alpha.enabled ? 1 : 0;
|
|
||||||
hw->alpha.func = nvgl_comparison_op(cso->alpha.func);
|
|
||||||
hw->alpha.ref = float_to_ubyte(cso->alpha.ref_value);
|
|
||||||
|
|
||||||
return (void *)hw;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
nv10->dsa = (struct nv10_depth_stencil_alpha_state*)dsa;
|
|
||||||
|
|
||||||
nv10->dirty |= NV10_NEW_DSA;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
FREE(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv10_vp_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_shader_state *templ)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
return draw_create_vertex_shader(nv10->draw, templ);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_vp_state_bind(struct pipe_context *pipe, void *shader)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
draw_bind_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader);
|
|
||||||
|
|
||||||
nv10->dirty |= NV10_NEW_VERTPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_vp_state_delete(struct pipe_context *pipe, void *shader)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
draw_delete_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv10_fp_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_shader_state *cso)
|
|
||||||
{
|
|
||||||
struct nv10_fragment_program *fp;
|
|
||||||
|
|
||||||
fp = CALLOC(1, sizeof(struct nv10_fragment_program));
|
|
||||||
fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
|
|
||||||
|
|
||||||
tgsi_scan_shader(cso->tokens, &fp->info);
|
|
||||||
|
|
||||||
return (void *)fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_fp_state_bind(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
struct nv10_fragment_program *fp = hwcso;
|
|
||||||
|
|
||||||
nv10->fragprog.current = fp;
|
|
||||||
nv10->dirty |= NV10_NEW_FRAGPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
struct nv10_fragment_program *fp = hwcso;
|
|
||||||
|
|
||||||
nv10_fragprog_destroy(nv10, fp);
|
|
||||||
FREE((void*)fp->pipe.tokens);
|
|
||||||
FREE(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_blend_color(struct pipe_context *pipe,
|
|
||||||
const struct pipe_blend_color *bcol)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
nv10->blend_color = (struct pipe_blend_color*)bcol;
|
|
||||||
|
|
||||||
nv10->dirty |= NV10_NEW_BLENDCOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_clip_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_clip_state *clip)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
draw_set_clip_state(nv10->draw, clip);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
|
||||||
struct pipe_buffer *buf )
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
struct pipe_screen *pscreen = pipe->screen;
|
|
||||||
|
|
||||||
assert(shader < PIPE_SHADER_TYPES);
|
|
||||||
assert(index == 0);
|
|
||||||
|
|
||||||
if (buf) {
|
|
||||||
void *mapped;
|
|
||||||
if (buf->size &&
|
|
||||||
(mapped = pipe_buffer_map(pscreen, buf, PIPE_BUFFER_USAGE_CPU_READ)))
|
|
||||||
{
|
|
||||||
memcpy(nv10->constbuf[shader], mapped, buf->size);
|
|
||||||
nv10->constbuf_nr[shader] =
|
|
||||||
buf->size / (4 * sizeof(float));
|
|
||||||
pipe_buffer_unmap(pscreen, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_framebuffer_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_framebuffer_state *fb)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
nv10->framebuffer = (struct pipe_framebuffer_state*)fb;
|
|
||||||
|
|
||||||
nv10->dirty |= NV10_NEW_FRAMEBUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_polygon_stipple(struct pipe_context *pipe,
|
|
||||||
const struct pipe_poly_stipple *stipple)
|
|
||||||
{
|
|
||||||
NOUVEAU_ERR("line stipple hahaha\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_scissor_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_scissor_state *s)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
nv10->scissor = (struct pipe_scissor_state*)s;
|
|
||||||
|
|
||||||
nv10->dirty |= NV10_NEW_SCISSOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_viewport_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_viewport_state *vpt)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
nv10->viewport = (struct pipe_viewport_state*)vpt;
|
|
||||||
|
|
||||||
draw_set_viewport_state(nv10->draw, nv10->viewport);
|
|
||||||
|
|
||||||
nv10->dirty |= NV10_NEW_VIEWPORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
|
|
||||||
const struct pipe_vertex_buffer *vb)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count);
|
|
||||||
nv10->dirty |= NV10_NEW_VTXARRAYS;
|
|
||||||
|
|
||||||
draw_set_vertex_buffers(nv10->draw, count, vb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count,
|
|
||||||
const struct pipe_vertex_element *ve)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
|
|
||||||
memcpy(nv10->vtxelt, ve, sizeof(*ve) * count);
|
|
||||||
nv10->dirty |= NV10_NEW_VTXARRAYS;
|
|
||||||
|
|
||||||
draw_set_vertex_elements(nv10->draw, count, ve);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv10_init_state_functions(struct nv10_context *nv10)
|
|
||||||
{
|
|
||||||
nv10->pipe.create_blend_state = nv10_blend_state_create;
|
|
||||||
nv10->pipe.bind_blend_state = nv10_blend_state_bind;
|
|
||||||
nv10->pipe.delete_blend_state = nv10_blend_state_delete;
|
|
||||||
|
|
||||||
nv10->pipe.create_sampler_state = nv10_sampler_state_create;
|
|
||||||
nv10->pipe.bind_fragment_sampler_states = nv10_sampler_state_bind;
|
|
||||||
nv10->pipe.delete_sampler_state = nv10_sampler_state_delete;
|
|
||||||
nv10->pipe.set_fragment_sampler_textures = nv10_set_sampler_texture;
|
|
||||||
|
|
||||||
nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create;
|
|
||||||
nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind;
|
|
||||||
nv10->pipe.delete_rasterizer_state = nv10_rasterizer_state_delete;
|
|
||||||
|
|
||||||
nv10->pipe.create_depth_stencil_alpha_state =
|
|
||||||
nv10_depth_stencil_alpha_state_create;
|
|
||||||
nv10->pipe.bind_depth_stencil_alpha_state =
|
|
||||||
nv10_depth_stencil_alpha_state_bind;
|
|
||||||
nv10->pipe.delete_depth_stencil_alpha_state =
|
|
||||||
nv10_depth_stencil_alpha_state_delete;
|
|
||||||
|
|
||||||
nv10->pipe.create_vs_state = nv10_vp_state_create;
|
|
||||||
nv10->pipe.bind_vs_state = nv10_vp_state_bind;
|
|
||||||
nv10->pipe.delete_vs_state = nv10_vp_state_delete;
|
|
||||||
|
|
||||||
nv10->pipe.create_fs_state = nv10_fp_state_create;
|
|
||||||
nv10->pipe.bind_fs_state = nv10_fp_state_bind;
|
|
||||||
nv10->pipe.delete_fs_state = nv10_fp_state_delete;
|
|
||||||
|
|
||||||
nv10->pipe.set_blend_color = nv10_set_blend_color;
|
|
||||||
nv10->pipe.set_clip_state = nv10_set_clip_state;
|
|
||||||
nv10->pipe.set_constant_buffer = nv10_set_constant_buffer;
|
|
||||||
nv10->pipe.set_framebuffer_state = nv10_set_framebuffer_state;
|
|
||||||
nv10->pipe.set_polygon_stipple = nv10_set_polygon_stipple;
|
|
||||||
nv10->pipe.set_scissor_state = nv10_set_scissor_state;
|
|
||||||
nv10->pipe.set_viewport_state = nv10_set_viewport_state;
|
|
||||||
|
|
||||||
nv10->pipe.set_vertex_buffers = nv10_set_vertex_buffers;
|
|
||||||
nv10->pipe.set_vertex_elements = nv10_set_vertex_elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
#ifndef __NV10_STATE_H__
|
|
||||||
#define __NV10_STATE_H__
|
|
||||||
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "tgsi/tgsi_scan.h"
|
|
||||||
|
|
||||||
struct nv10_blend_state {
|
|
||||||
uint32_t b_enable;
|
|
||||||
uint32_t b_srcfunc;
|
|
||||||
uint32_t b_dstfunc;
|
|
||||||
|
|
||||||
uint32_t c_mask;
|
|
||||||
|
|
||||||
uint32_t d_enable;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv10_sampler_state {
|
|
||||||
uint32_t wrap;
|
|
||||||
uint32_t en;
|
|
||||||
uint32_t filt;
|
|
||||||
uint32_t bcol;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv10_rasterizer_state {
|
|
||||||
uint32_t shade_model;
|
|
||||||
|
|
||||||
uint32_t line_width;
|
|
||||||
uint32_t line_smooth_en;
|
|
||||||
|
|
||||||
uint32_t point_size;
|
|
||||||
|
|
||||||
uint32_t poly_smooth_en;
|
|
||||||
|
|
||||||
uint32_t poly_mode_front;
|
|
||||||
uint32_t poly_mode_back;
|
|
||||||
|
|
||||||
uint32_t front_face;
|
|
||||||
uint32_t cull_face;
|
|
||||||
uint32_t cull_face_en;
|
|
||||||
|
|
||||||
uint32_t point_sprite;
|
|
||||||
|
|
||||||
const struct pipe_rasterizer_state *templ;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv10_vertex_program_exec {
|
|
||||||
uint32_t data[4];
|
|
||||||
boolean has_branch_offset;
|
|
||||||
int const_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv10_vertex_program_data {
|
|
||||||
int index; /* immediates == -1 */
|
|
||||||
float value[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv10_vertex_program {
|
|
||||||
const struct pipe_shader_state *pipe;
|
|
||||||
|
|
||||||
boolean translated;
|
|
||||||
struct nv10_vertex_program_exec *insns;
|
|
||||||
unsigned nr_insns;
|
|
||||||
struct nv10_vertex_program_data *consts;
|
|
||||||
unsigned nr_consts;
|
|
||||||
|
|
||||||
struct nouveau_resource *exec;
|
|
||||||
unsigned exec_start;
|
|
||||||
struct nouveau_resource *data;
|
|
||||||
unsigned data_start;
|
|
||||||
unsigned data_start_min;
|
|
||||||
|
|
||||||
uint32_t ir;
|
|
||||||
uint32_t or;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv10_fragment_program_data {
|
|
||||||
unsigned offset;
|
|
||||||
unsigned index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv10_fragment_program {
|
|
||||||
struct pipe_shader_state pipe;
|
|
||||||
struct tgsi_shader_info info;
|
|
||||||
|
|
||||||
boolean translated;
|
|
||||||
boolean on_hw;
|
|
||||||
unsigned samplers;
|
|
||||||
|
|
||||||
uint32_t *insn;
|
|
||||||
int insn_len;
|
|
||||||
|
|
||||||
struct nv10_fragment_program_data *consts;
|
|
||||||
unsigned nr_consts;
|
|
||||||
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
|
|
||||||
uint32_t fp_control;
|
|
||||||
uint32_t fp_reg_control;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct nv10_depth_stencil_alpha_state {
|
|
||||||
struct {
|
|
||||||
uint32_t func;
|
|
||||||
uint32_t write_enable;
|
|
||||||
uint32_t test_enable;
|
|
||||||
} depth;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint32_t enable;
|
|
||||||
uint32_t wmask;
|
|
||||||
uint32_t func;
|
|
||||||
uint32_t ref;
|
|
||||||
uint32_t vmask;
|
|
||||||
uint32_t fail;
|
|
||||||
uint32_t zfail;
|
|
||||||
uint32_t zpass;
|
|
||||||
} stencil;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint32_t enabled;
|
|
||||||
uint32_t func;
|
|
||||||
uint32_t ref;
|
|
||||||
} alpha;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv10_miptree {
|
|
||||||
struct pipe_texture base;
|
|
||||||
struct nouveau_bo *bo;
|
|
||||||
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
uint total_size;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint pitch;
|
|
||||||
uint *image_offset;
|
|
||||||
} level[PIPE_MAX_TEXTURE_LEVELS];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,333 +0,0 @@
|
||||||
#include "nv10_context.h"
|
|
||||||
#include "nv10_state.h"
|
|
||||||
|
|
||||||
static void nv10_state_emit_blend(struct nv10_context* nv10)
|
|
||||||
{
|
|
||||||
struct nv10_blend_state *b = nv10->blend;
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 1);
|
|
||||||
OUT_RING (chan, b->d_enable);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 3);
|
|
||||||
OUT_RING (chan, b->b_enable);
|
|
||||||
OUT_RING (chan, b->b_srcfunc);
|
|
||||||
OUT_RING (chan, b->b_dstfunc);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1);
|
|
||||||
OUT_RING (chan, b->c_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv10_state_emit_blend_color(struct nv10_context* nv10)
|
|
||||||
{
|
|
||||||
struct pipe_blend_color *c = nv10->blend_color;
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_BLEND_COLOR, 1);
|
|
||||||
OUT_RING (chan,
|
|
||||||
(float_to_ubyte(c->color[3]) << 24)|
|
|
||||||
(float_to_ubyte(c->color[0]) << 16)|
|
|
||||||
(float_to_ubyte(c->color[1]) << 8) |
|
|
||||||
(float_to_ubyte(c->color[2]) << 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv10_state_emit_rast(struct nv10_context* nv10)
|
|
||||||
{
|
|
||||||
struct nv10_rasterizer_state *r = nv10->rast;
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_SHADE_MODEL, 2);
|
|
||||||
OUT_RING (chan, r->shade_model);
|
|
||||||
OUT_RING (chan, r->line_width);
|
|
||||||
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1);
|
|
||||||
OUT_RING (chan, r->point_size);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
|
|
||||||
OUT_RING (chan, r->poly_mode_front);
|
|
||||||
OUT_RING (chan, r->poly_mode_back);
|
|
||||||
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2);
|
|
||||||
OUT_RING (chan, r->cull_face);
|
|
||||||
OUT_RING (chan, r->front_face);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2);
|
|
||||||
OUT_RING (chan, r->line_smooth_en);
|
|
||||||
OUT_RING (chan, r->poly_smooth_en);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1);
|
|
||||||
OUT_RING (chan, r->cull_face_en);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv10_state_emit_dsa(struct nv10_context* nv10)
|
|
||||||
{
|
|
||||||
struct nv10_depth_stencil_alpha_state *d = nv10->dsa;
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1);
|
|
||||||
OUT_RING (chan, d->depth.func);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1);
|
|
||||||
OUT_RING (chan, d->depth.write_enable);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1);
|
|
||||||
OUT_RING (chan, d->depth.test_enable);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_STENCIL_ENABLE, 1);
|
|
||||||
OUT_RING (chan, d->stencil.enable);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 7);
|
|
||||||
OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1);
|
|
||||||
OUT_RING (chan, d->alpha.enabled);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 1);
|
|
||||||
OUT_RING (chan, d->alpha.func);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_REF, 1);
|
|
||||||
OUT_RING (chan, d->alpha.ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv10_state_emit_viewport(struct nv10_context* nv10)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv10_state_emit_scissor(struct nv10_context* nv10)
|
|
||||||
{
|
|
||||||
// XXX this is so not working
|
|
||||||
/* struct pipe_scissor_state *s = nv10->scissor;
|
|
||||||
BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2);
|
|
||||||
OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
|
|
||||||
OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv10_state_emit_framebuffer(struct nv10_context* nv10)
|
|
||||||
{
|
|
||||||
struct pipe_framebuffer_state* fb = nv10->framebuffer;
|
|
||||||
struct nv04_surface *rt, *zeta = NULL;
|
|
||||||
uint32_t rt_format, w, h;
|
|
||||||
int colour_format = 0, zeta_format = 0;
|
|
||||||
struct nv10_miptree *nv10mt = 0;
|
|
||||||
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
|
|
||||||
w = fb->cbufs[0]->width;
|
|
||||||
h = fb->cbufs[0]->height;
|
|
||||||
colour_format = fb->cbufs[0]->format;
|
|
||||||
rt = (struct nv04_surface *)fb->cbufs[0];
|
|
||||||
|
|
||||||
if (fb->zsbuf) {
|
|
||||||
if (colour_format) {
|
|
||||||
assert(w == fb->zsbuf->width);
|
|
||||||
assert(h == fb->zsbuf->height);
|
|
||||||
} else {
|
|
||||||
w = fb->zsbuf->width;
|
|
||||||
h = fb->zsbuf->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
zeta_format = fb->zsbuf->format;
|
|
||||||
zeta = (struct nv04_surface *)fb->zsbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR;
|
|
||||||
|
|
||||||
switch (colour_format) {
|
|
||||||
case PIPE_FORMAT_X8R8G8B8_UNORM:
|
|
||||||
rt_format |= NV10TCL_RT_FORMAT_COLOR_X8R8G8B8;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case 0:
|
|
||||||
rt_format |= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
|
||||||
rt_format |= NV10TCL_RT_FORMAT_COLOR_R5G6B5;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zeta) {
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1);
|
|
||||||
OUT_RING (chan, rt->pitch | (zeta->pitch << 16));
|
|
||||||
} else {
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1);
|
|
||||||
OUT_RING (chan, rt->pitch | (rt->pitch << 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
nv10mt = (struct nv10_miptree *)rt->base.texture;
|
|
||||||
nv10->rt[0] = nv10mt->buffer;
|
|
||||||
|
|
||||||
if (zeta_format)
|
|
||||||
{
|
|
||||||
nv10mt = (struct nv10_miptree *)zeta->base.texture;
|
|
||||||
nv10->zeta = nv10mt->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 3);
|
|
||||||
OUT_RING (chan, (w << 16) | 0);
|
|
||||||
OUT_RING (chan, (h << 16) | 0);
|
|
||||||
OUT_RING (chan, rt_format);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2);
|
|
||||||
OUT_RING (chan, ((w - 1) << 16) | 0 | 0x08000800);
|
|
||||||
OUT_RING (chan, ((h - 1) << 16) | 0 | 0x08000800);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv10_vertex_layout(struct nv10_context *nv10)
|
|
||||||
{
|
|
||||||
struct nv10_fragment_program *fp = nv10->fragprog.current;
|
|
||||||
uint32_t src = 0;
|
|
||||||
int i;
|
|
||||||
struct vertex_info vinfo;
|
|
||||||
|
|
||||||
memset(&vinfo, 0, sizeof(vinfo));
|
|
||||||
|
|
||||||
for (i = 0; i < fp->info.num_inputs; i++) {
|
|
||||||
switch (fp->info.input_semantic_name[i]) {
|
|
||||||
case TGSI_SEMANTIC_POSITION:
|
|
||||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_COLOR:
|
|
||||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
case TGSI_SEMANTIC_GENERIC:
|
|
||||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_FOG:
|
|
||||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
draw_compute_vertex_size(&vinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv10_emit_hw_state(struct nv10_context *nv10)
|
|
||||||
{
|
|
||||||
struct nv10_screen *screen = nv10->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *celsius = screen->celsius;
|
|
||||||
struct nouveau_bo *rt_bo;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_VERTPROG) {
|
|
||||||
//nv10_vertprog_bind(nv10, nv10->vertprog.current);
|
|
||||||
nv10->dirty &= ~NV10_NEW_VERTPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_FRAGPROG) {
|
|
||||||
nv10_fragprog_bind(nv10, nv10->fragprog.current);
|
|
||||||
/*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */
|
|
||||||
nv10->dirty_samplers |= (1<<10);
|
|
||||||
nv10->dirty_samplers = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) {
|
|
||||||
nv10_fragtex_bind(nv10);
|
|
||||||
nv10->dirty &= ~NV10_NEW_FRAGPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_VTXARRAYS) {
|
|
||||||
nv10->dirty &= ~NV10_NEW_VTXARRAYS;
|
|
||||||
nv10_vertex_layout(nv10);
|
|
||||||
nv10_vtxbuf_bind(nv10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_BLEND) {
|
|
||||||
nv10->dirty &= ~NV10_NEW_BLEND;
|
|
||||||
nv10_state_emit_blend(nv10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_BLENDCOL) {
|
|
||||||
nv10->dirty &= ~NV10_NEW_BLENDCOL;
|
|
||||||
nv10_state_emit_blend_color(nv10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_RAST) {
|
|
||||||
nv10->dirty &= ~NV10_NEW_RAST;
|
|
||||||
nv10_state_emit_rast(nv10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_DSA) {
|
|
||||||
nv10->dirty &= ~NV10_NEW_DSA;
|
|
||||||
nv10_state_emit_dsa(nv10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_VIEWPORT) {
|
|
||||||
nv10->dirty &= ~NV10_NEW_VIEWPORT;
|
|
||||||
nv10_state_emit_viewport(nv10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_SCISSOR) {
|
|
||||||
nv10->dirty &= ~NV10_NEW_SCISSOR;
|
|
||||||
nv10_state_emit_scissor(nv10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv10->dirty & NV10_NEW_FRAMEBUFFER) {
|
|
||||||
nv10->dirty &= ~NV10_NEW_FRAMEBUFFER;
|
|
||||||
nv10_state_emit_framebuffer(nv10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emit relocs for every referenced buffer.
|
|
||||||
* This is to ensure the bufmgr has an accurate idea of how
|
|
||||||
* the buffer is used. This isn't very efficient, but we don't
|
|
||||||
* seem to take a significant performance hit. Will be improved
|
|
||||||
* at some point. Vertex arrays are emitted by nv10_vbo.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Render target */
|
|
||||||
rt_bo = nouveau_bo(nv10->rt[0]);
|
|
||||||
// XXX figre out who's who for NV10TCL_DMA_* and fill accordingly
|
|
||||||
// BEGIN_RING(chan, celsius, NV10TCL_DMA_COLOR0, 1);
|
|
||||||
// OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1);
|
|
||||||
OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
|
|
||||||
if (nv10->zeta) {
|
|
||||||
struct nouveau_bo *zeta_bo = nouveau_bo(nv10->zeta);
|
|
||||||
// XXX
|
|
||||||
// BEGIN_RING(chan, celsius, NV10TCL_DMA_ZETA, 1);
|
|
||||||
// OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_ZETA_OFFSET, 1);
|
|
||||||
OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
/* XXX for when we allocate LMA on nv17 */
|
|
||||||
/* BEGIN_RING(chan, celsius, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
|
|
||||||
OUT_RELOCl(chan, nouveau_bo(nv10->zeta + lma_offset));*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Vertex buffer */
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_DMA_VTXBUF0, 1);
|
|
||||||
OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1);
|
|
||||||
OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
|
|
||||||
/* Texture images */
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (!(nv10->fp_samplers & (1 << i)))
|
|
||||||
continue;
|
|
||||||
struct nouveau_bo *bo = nouveau_bo(nv10->tex[i].buffer);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_TX_OFFSET(i), 1);
|
|
||||||
OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM |
|
|
||||||
NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
|
||||||
BEGIN_RING(chan, celsius, NV10TCL_TX_FORMAT(i), 1);
|
|
||||||
OUT_RELOCd(chan, bo, nv10->tex[i].format,
|
|
||||||
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
|
|
||||||
NOUVEAU_BO_OR, NV10TCL_TX_FORMAT_DMA0,
|
|
||||||
NV10TCL_TX_FORMAT_DMA1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
||||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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 "nv10_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "util/u_simple_screen.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_tile.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_surface_copy(struct pipe_context *pipe,
|
|
||||||
struct pipe_surface *dest, unsigned destx, unsigned desty,
|
|
||||||
struct pipe_surface *src, unsigned srcx, unsigned srcy,
|
|
||||||
unsigned width, unsigned height)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
struct nv04_surface_2d *eng2d = nv10->screen->eng2d;
|
|
||||||
|
|
||||||
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
|
|
||||||
unsigned destx, unsigned desty, unsigned width,
|
|
||||||
unsigned height, unsigned value)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context(pipe);
|
|
||||||
struct nv04_surface_2d *eng2d = nv10->screen->eng2d;
|
|
||||||
|
|
||||||
eng2d->fill(eng2d, dest, destx, desty, width, height, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv10_init_surface_functions(struct nv10_context *nv10)
|
|
||||||
{
|
|
||||||
nv10->pipe.surface_copy = nv10_surface_copy;
|
|
||||||
nv10->pipe.surface_fill = nv10_surface_fill;
|
|
||||||
}
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
||||||
#include <pipe/p_state.h>
|
|
||||||
#include <pipe/p_defines.h>
|
|
||||||
#include <util/u_inlines.h>
|
|
||||||
#include <util/u_format.h>
|
|
||||||
#include <util/u_memory.h>
|
|
||||||
#include <util/u_math.h>
|
|
||||||
#include <nouveau/nouveau_winsys.h>
|
|
||||||
#include "nv10_context.h"
|
|
||||||
#include "nv10_screen.h"
|
|
||||||
#include "nv10_state.h"
|
|
||||||
|
|
||||||
struct nv10_transfer {
|
|
||||||
struct pipe_transfer base;
|
|
||||||
struct pipe_surface *surface;
|
|
||||||
boolean direct;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
|
|
||||||
struct pipe_texture *template)
|
|
||||||
{
|
|
||||||
memset(template, 0, sizeof(struct pipe_texture));
|
|
||||||
template->target = pt->target;
|
|
||||||
template->format = pt->format;
|
|
||||||
template->width0 = width;
|
|
||||||
template->height0 = height;
|
|
||||||
template->depth0 = 1;
|
|
||||||
template->last_level = 0;
|
|
||||||
template->nr_samples = pt->nr_samples;
|
|
||||||
|
|
||||||
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
|
|
||||||
NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_transfer *
|
|
||||||
nv10_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
|
|
||||||
unsigned face, unsigned level, unsigned zslice,
|
|
||||||
enum pipe_transfer_usage usage,
|
|
||||||
unsigned x, unsigned y, unsigned w, unsigned h)
|
|
||||||
{
|
|
||||||
struct nv10_miptree *mt = (struct nv10_miptree *)pt;
|
|
||||||
struct nv10_transfer *tx;
|
|
||||||
struct pipe_texture tx_tex_template, *tx_tex;
|
|
||||||
|
|
||||||
tx = CALLOC_STRUCT(nv10_transfer);
|
|
||||||
if (!tx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
pipe_texture_reference(&tx->base.texture, pt);
|
|
||||||
tx->base.x = x;
|
|
||||||
tx->base.y = y;
|
|
||||||
tx->base.width = w;
|
|
||||||
tx->base.height = h;
|
|
||||||
tx->base.stride = mt->level[level].pitch;
|
|
||||||
tx->base.usage = usage;
|
|
||||||
tx->base.face = face;
|
|
||||||
tx->base.level = level;
|
|
||||||
tx->base.zslice = zslice;
|
|
||||||
|
|
||||||
/* Direct access to texture */
|
|
||||||
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
|
|
||||||
debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
|
|
||||||
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
|
|
||||||
{
|
|
||||||
tx->direct = true;
|
|
||||||
tx->surface = pscreen->get_tex_surface(pscreen, pt,
|
|
||||||
0, 0, 0,
|
|
||||||
pipe_transfer_buffer_flags(&tx->base));
|
|
||||||
return &tx->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx->direct = false;
|
|
||||||
|
|
||||||
nv10_compatible_transfer_tex(pt, w, h, &tx_tex_template);
|
|
||||||
|
|
||||||
tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
|
|
||||||
if (!tx_tex)
|
|
||||||
{
|
|
||||||
FREE(tx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx->base.stride = ((struct nv10_miptree*)tx_tex)->level[0].pitch;
|
|
||||||
|
|
||||||
tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
|
|
||||||
face, level, zslice,
|
|
||||||
pipe_transfer_buffer_flags(&tx->base));
|
|
||||||
|
|
||||||
pipe_texture_reference(&tx_tex, NULL);
|
|
||||||
|
|
||||||
if (!tx->surface)
|
|
||||||
{
|
|
||||||
pipe_surface_reference(&tx->surface, NULL);
|
|
||||||
FREE(tx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usage & PIPE_TRANSFER_READ) {
|
|
||||||
struct nv10_screen *nvscreen = nv10_screen(pscreen);
|
|
||||||
struct pipe_surface *src;
|
|
||||||
|
|
||||||
src = pscreen->get_tex_surface(pscreen, pt,
|
|
||||||
face, level, zslice,
|
|
||||||
PIPE_BUFFER_USAGE_GPU_READ);
|
|
||||||
|
|
||||||
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
|
|
||||||
/* TODO: Check if SIFM can un-swizzle */
|
|
||||||
nvscreen->eng2d->copy(nvscreen->eng2d,
|
|
||||||
tx->surface, 0, 0,
|
|
||||||
src, x, y,
|
|
||||||
w, h);
|
|
||||||
|
|
||||||
pipe_surface_reference(&src, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return &tx->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_transfer_del(struct pipe_transfer *ptx)
|
|
||||||
{
|
|
||||||
struct nv10_transfer *tx = (struct nv10_transfer *)ptx;
|
|
||||||
|
|
||||||
if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
|
|
||||||
struct pipe_screen *pscreen = ptx->texture->screen;
|
|
||||||
struct nv10_screen *nvscreen = nv10_screen(pscreen);
|
|
||||||
struct pipe_surface *dst;
|
|
||||||
|
|
||||||
dst = pscreen->get_tex_surface(pscreen, ptx->texture,
|
|
||||||
ptx->face, ptx->level, ptx->zslice,
|
|
||||||
PIPE_BUFFER_USAGE_GPU_WRITE);
|
|
||||||
|
|
||||||
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
|
|
||||||
nvscreen->eng2d->copy(nvscreen->eng2d,
|
|
||||||
dst, tx->base.x, tx->base.y,
|
|
||||||
tx->surface, 0, 0,
|
|
||||||
tx->base.width, tx->base.height);
|
|
||||||
|
|
||||||
pipe_surface_reference(&dst, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_surface_reference(&tx->surface, NULL);
|
|
||||||
pipe_texture_reference(&ptx->texture, NULL);
|
|
||||||
FREE(ptx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv10_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
|
|
||||||
{
|
|
||||||
struct nv10_transfer *tx = (struct nv10_transfer *)ptx;
|
|
||||||
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
|
|
||||||
struct nv10_miptree *mt = (struct nv10_miptree *)tx->surface->texture;
|
|
||||||
void *map = pipe_buffer_map(pscreen, mt->buffer,
|
|
||||||
pipe_transfer_buffer_flags(ptx));
|
|
||||||
|
|
||||||
if(!tx->direct)
|
|
||||||
return map + ns->base.offset;
|
|
||||||
else
|
|
||||||
return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv10_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
|
|
||||||
{
|
|
||||||
struct nv10_transfer *tx = (struct nv10_transfer *)ptx;
|
|
||||||
struct nv10_miptree *mt = (struct nv10_miptree *)tx->surface->texture;
|
|
||||||
|
|
||||||
pipe_buffer_unmap(pscreen, mt->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv10_screen_init_transfer_functions(struct pipe_screen *pscreen)
|
|
||||||
{
|
|
||||||
pscreen->get_tex_transfer = nv10_transfer_new;
|
|
||||||
pscreen->tex_transfer_destroy = nv10_transfer_del;
|
|
||||||
pscreen->transfer_map = nv10_transfer_map;
|
|
||||||
pscreen->transfer_unmap = nv10_transfer_unmap;
|
|
||||||
}
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
#include "draw/draw_context.h"
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "nv10_context.h"
|
|
||||||
#include "nv10_state.h"
|
|
||||||
|
|
||||||
#include "nouveau/nouveau_channel.h"
|
|
||||||
#include "nouveau/nouveau_pushbuf.h"
|
|
||||||
|
|
||||||
void nv10_draw_elements( struct pipe_context *pipe,
|
|
||||||
struct pipe_buffer *indexBuffer,
|
|
||||||
unsigned indexSize,
|
|
||||||
unsigned prim, unsigned start, unsigned count)
|
|
||||||
{
|
|
||||||
struct nv10_context *nv10 = nv10_context( pipe );
|
|
||||||
struct draw_context *draw = nv10->draw;
|
|
||||||
struct pipe_screen *pscreen = pipe->screen;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
nv10_emit_hw_state(nv10);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map vertex buffers
|
|
||||||
*/
|
|
||||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
|
|
||||||
if (nv10->vtxbuf[i].buffer) {
|
|
||||||
void *buf =
|
|
||||||
pipe_buffer_map(pscreen, nv10->vtxbuf[i].buffer,
|
|
||||||
PIPE_BUFFER_USAGE_CPU_READ);
|
|
||||||
draw_set_mapped_vertex_buffer(draw, i, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Map index buffer, if present */
|
|
||||||
if (indexBuffer) {
|
|
||||||
void *mapped_indexes
|
|
||||||
= pipe_buffer_map(pscreen, indexBuffer,
|
|
||||||
PIPE_BUFFER_USAGE_CPU_READ);
|
|
||||||
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* no index/element buffer */
|
|
||||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_set_mapped_constant_buffer(draw,
|
|
||||||
PIPE_SHADER_VERTEX,
|
|
||||||
0,
|
|
||||||
nv10->constbuf[PIPE_SHADER_VERTEX],
|
|
||||||
nv10->constbuf_nr[PIPE_SHADER_VERTEX]);
|
|
||||||
|
|
||||||
/* draw! */
|
|
||||||
draw_arrays(nv10->draw, prim, start, count);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* unmap vertex/index buffers
|
|
||||||
*/
|
|
||||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
|
|
||||||
if (nv10->vtxbuf[i].buffer) {
|
|
||||||
pipe_buffer_unmap(pscreen, nv10->vtxbuf[i].buffer);
|
|
||||||
draw_set_mapped_vertex_buffer(draw, i, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (indexBuffer) {
|
|
||||||
pipe_buffer_unmap(pscreen, indexBuffer);
|
|
||||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nv10_draw_arrays( struct pipe_context *pipe,
|
|
||||||
unsigned prim, unsigned start, unsigned count)
|
|
||||||
{
|
|
||||||
nv10_draw_elements(pipe, NULL, 0, prim, start, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
TOP = ../../../..
|
|
||||||
include $(TOP)/configs/current
|
|
||||||
|
|
||||||
LIBNAME = nv20
|
|
||||||
|
|
||||||
C_SOURCES = \
|
|
||||||
nv20_clear.c \
|
|
||||||
nv20_context.c \
|
|
||||||
nv20_fragprog.c \
|
|
||||||
nv20_fragtex.c \
|
|
||||||
nv20_miptree.c \
|
|
||||||
nv20_prim_vbuf.c \
|
|
||||||
nv20_screen.c \
|
|
||||||
nv20_state.c \
|
|
||||||
nv20_state_emit.c \
|
|
||||||
nv20_surface.c \
|
|
||||||
nv20_transfer.c \
|
|
||||||
nv20_vbo.c
|
|
||||||
# nv20_vertprog.c
|
|
||||||
|
|
||||||
include ../../Makefile.template
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_clear.h"
|
|
||||||
|
|
||||||
#include "nv20_context.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_clear(struct pipe_context *pipe, unsigned buffers,
|
|
||||||
const float *rgba, double depth, unsigned stencil)
|
|
||||||
{
|
|
||||||
util_clear(pipe, nv20_context(pipe)->framebuffer, buffers, rgba, depth,
|
|
||||||
stencil);
|
|
||||||
}
|
|
||||||
|
|
@ -1,152 +0,0 @@
|
||||||
#ifndef __NV20_CONTEXT_H__
|
|
||||||
#define __NV20_CONTEXT_H__
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "pipe/p_compiler.h"
|
|
||||||
|
|
||||||
#include "util/u_memory.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
|
|
||||||
#include "draw/draw_vertex.h"
|
|
||||||
|
|
||||||
#include "nouveau/nouveau_winsys.h"
|
|
||||||
#include "nouveau/nouveau_gldefs.h"
|
|
||||||
#include "nouveau/nouveau_context.h"
|
|
||||||
|
|
||||||
#include "nv20_state.h"
|
|
||||||
|
|
||||||
#define NOUVEAU_ERR(fmt, args...) \
|
|
||||||
fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args);
|
|
||||||
#define NOUVEAU_MSG(fmt, args...) \
|
|
||||||
fprintf(stderr, "nouveau: "fmt, ##args);
|
|
||||||
|
|
||||||
#define NV20_NEW_VERTPROG (1 << 0)
|
|
||||||
#define NV20_NEW_FRAGPROG (1 << 1)
|
|
||||||
#define NV20_NEW_VTXARRAYS (1 << 2)
|
|
||||||
#define NV20_NEW_BLEND (1 << 3)
|
|
||||||
#define NV20_NEW_BLENDCOL (1 << 4)
|
|
||||||
#define NV20_NEW_RAST (1 << 5)
|
|
||||||
#define NV20_NEW_DSA (1 << 6)
|
|
||||||
#define NV20_NEW_VIEWPORT (1 << 7)
|
|
||||||
#define NV20_NEW_SCISSOR (1 << 8)
|
|
||||||
#define NV20_NEW_FRAMEBUFFER (1 << 9)
|
|
||||||
|
|
||||||
#include "nv20_screen.h"
|
|
||||||
|
|
||||||
struct nv20_context {
|
|
||||||
struct pipe_context pipe;
|
|
||||||
|
|
||||||
struct nouveau_winsys *nvws;
|
|
||||||
struct nv20_screen *screen;
|
|
||||||
unsigned pctx_id;
|
|
||||||
|
|
||||||
struct draw_context *draw;
|
|
||||||
|
|
||||||
uint32_t dirty;
|
|
||||||
|
|
||||||
struct nv20_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
|
|
||||||
struct nv20_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
|
|
||||||
unsigned dirty_samplers;
|
|
||||||
unsigned fp_samplers;
|
|
||||||
unsigned vp_samplers;
|
|
||||||
|
|
||||||
uint32_t rt_enable;
|
|
||||||
struct pipe_buffer *rt[4];
|
|
||||||
struct pipe_buffer *zeta;
|
|
||||||
uint32_t lma_offset;
|
|
||||||
|
|
||||||
struct nv20_blend_state *blend;
|
|
||||||
struct pipe_blend_color *blend_color;
|
|
||||||
struct nv20_rasterizer_state *rast;
|
|
||||||
struct nv20_depth_stencil_alpha_state *dsa;
|
|
||||||
struct pipe_viewport_state *viewport;
|
|
||||||
struct pipe_scissor_state *scissor;
|
|
||||||
struct pipe_framebuffer_state *framebuffer;
|
|
||||||
|
|
||||||
//struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
|
|
||||||
float *constbuf[PIPE_SHADER_TYPES][32][4];
|
|
||||||
unsigned constbuf_nr[PIPE_SHADER_TYPES];
|
|
||||||
|
|
||||||
struct vertex_info vertex_info;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
uint32_t format;
|
|
||||||
} tex[2];
|
|
||||||
|
|
||||||
unsigned vb_enable;
|
|
||||||
struct {
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
unsigned delta;
|
|
||||||
} vb[16];
|
|
||||||
|
|
||||||
/* struct {
|
|
||||||
|
|
||||||
struct nouveau_resource *exec_heap;
|
|
||||||
struct nouveau_resource *data_heap;
|
|
||||||
|
|
||||||
struct nv20_vertex_program *active;
|
|
||||||
|
|
||||||
struct nv20_vertex_program *current;
|
|
||||||
} vertprog;
|
|
||||||
*/
|
|
||||||
struct {
|
|
||||||
struct nv20_fragment_program *active;
|
|
||||||
|
|
||||||
struct nv20_fragment_program *current;
|
|
||||||
struct pipe_buffer *constant_buf;
|
|
||||||
} fragprog;
|
|
||||||
|
|
||||||
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
|
|
||||||
struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE struct nv20_context *
|
|
||||||
nv20_context(struct pipe_context *pipe)
|
|
||||||
{
|
|
||||||
return (struct nv20_context *)pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void nv20_init_state_functions(struct nv20_context *nv20);
|
|
||||||
extern void nv20_init_surface_functions(struct nv20_context *nv20);
|
|
||||||
|
|
||||||
extern void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen);
|
|
||||||
|
|
||||||
/* nv20_clear.c */
|
|
||||||
extern void nv20_clear(struct pipe_context *pipe, unsigned buffers,
|
|
||||||
const float *rgba, double depth, unsigned stencil);
|
|
||||||
|
|
||||||
/* nv20_draw.c */
|
|
||||||
extern struct draw_stage *nv20_draw_render_stage(struct nv20_context *nv20);
|
|
||||||
|
|
||||||
/* nv20_fragprog.c */
|
|
||||||
extern void nv20_fragprog_bind(struct nv20_context *,
|
|
||||||
struct nv20_fragment_program *);
|
|
||||||
extern void nv20_fragprog_destroy(struct nv20_context *,
|
|
||||||
struct nv20_fragment_program *);
|
|
||||||
|
|
||||||
/* nv20_fragtex.c */
|
|
||||||
extern void nv20_fragtex_bind(struct nv20_context *);
|
|
||||||
|
|
||||||
/* nv20_prim_vbuf.c */
|
|
||||||
struct draw_stage *nv20_draw_vbuf_stage( struct nv20_context *nv20 );
|
|
||||||
extern void nv20_vtxbuf_bind(struct nv20_context* nv20);
|
|
||||||
|
|
||||||
/* nv20_state.c and friends */
|
|
||||||
extern void nv20_emit_hw_state(struct nv20_context *nv20);
|
|
||||||
extern void nv20_state_tex_update(struct nv20_context *nv20);
|
|
||||||
|
|
||||||
/* nv20_vbo.c */
|
|
||||||
extern void nv20_draw_arrays(struct pipe_context *, unsigned mode,
|
|
||||||
unsigned start, unsigned count);
|
|
||||||
extern void nv20_draw_elements( struct pipe_context *pipe,
|
|
||||||
struct pipe_buffer *indexBuffer,
|
|
||||||
unsigned indexSize,
|
|
||||||
unsigned prim, unsigned start, unsigned count);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
|
|
||||||
#include "pipe/p_shader_tokens.h"
|
|
||||||
#include "tgsi/tgsi_parse.h"
|
|
||||||
#include "tgsi/tgsi_util.h"
|
|
||||||
|
|
||||||
#include "nv20_context.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_fragprog_bind(struct nv20_context *nv20, struct nv20_fragment_program *fp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_fragprog_destroy(struct nv20_context *nv20,
|
|
||||||
struct nv20_fragment_program *fp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,130 +0,0 @@
|
||||||
#include "nv20_context.h"
|
|
||||||
#include "nouveau/nouveau_util.h"
|
|
||||||
|
|
||||||
#define _(m,tf) \
|
|
||||||
{ \
|
|
||||||
TRUE, \
|
|
||||||
PIPE_FORMAT_##m, \
|
|
||||||
NV20TCL_TX_FORMAT_FORMAT_##tf, \
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nv20_texture_format {
|
|
||||||
boolean defined;
|
|
||||||
uint pipe;
|
|
||||||
int format;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct nv20_texture_format
|
|
||||||
nv20_texture_formats[] = {
|
|
||||||
_(A8R8G8B8_UNORM, A8R8G8B8),
|
|
||||||
_(A1R5G5B5_UNORM, A1R5G5B5),
|
|
||||||
_(A4R4G4B4_UNORM, A4R4G4B4),
|
|
||||||
_(L8_UNORM , L8 ),
|
|
||||||
_(A8_UNORM , A8 ),
|
|
||||||
_(A8L8_UNORM , A8L8 ),
|
|
||||||
/* _(RGB_DXT1 , DXT1, ), */
|
|
||||||
/* _(RGBA_DXT1 , DXT1, ), */
|
|
||||||
/* _(RGBA_DXT3 , DXT3, ), */
|
|
||||||
/* _(RGBA_DXT5 , DXT5, ), */
|
|
||||||
{},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct nv20_texture_format *
|
|
||||||
nv20_fragtex_format(uint pipe_format)
|
|
||||||
{
|
|
||||||
struct nv20_texture_format *tf = nv20_texture_formats;
|
|
||||||
|
|
||||||
while (tf->defined) {
|
|
||||||
if (tf->pipe == pipe_format)
|
|
||||||
return tf;
|
|
||||||
tf++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_fragtex_build(struct nv20_context *nv20, int unit)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
struct nv20_sampler_state *ps = nv20->tex_sampler[unit];
|
|
||||||
struct nv20_miptree *nv20mt = nv20->tex_miptree[unit];
|
|
||||||
struct pipe_texture *pt = &nv20mt->base;
|
|
||||||
struct nv20_texture_format *tf;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
uint32_t txf, txs, txp;
|
|
||||||
|
|
||||||
tf = nv20_fragtex_format(pt->format);
|
|
||||||
if (!tf || !tf->defined) {
|
|
||||||
NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
txf = tf->format << 8;
|
|
||||||
txf |= (pt->last_level + 1) << 16;
|
|
||||||
txf |= log2i(pt->width0) << 20;
|
|
||||||
txf |= log2i(pt->height0) << 24;
|
|
||||||
txf |= log2i(pt->depth0) << 28;
|
|
||||||
txf |= 8;
|
|
||||||
|
|
||||||
switch (pt->target) {
|
|
||||||
case PIPE_TEXTURE_CUBE:
|
|
||||||
txf |= NV10TCL_TX_FORMAT_CUBE_MAP;
|
|
||||||
/* fall-through */
|
|
||||||
case PIPE_TEXTURE_2D:
|
|
||||||
txf |= (2<<4);
|
|
||||||
break;
|
|
||||||
case PIPE_TEXTURE_1D:
|
|
||||||
txf |= (1<<4);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("Unknown target %d\n", pt->target);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV10TCL_TX_OFFSET(unit), 8);
|
|
||||||
OUT_RELOCl(chan, nouveau_bo(nv20mt->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
|
||||||
OUT_RELOCd(chan, nouveau_bo(nv20mt->buffer),txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
|
|
||||||
OUT_RING (chan, ps->wrap);
|
|
||||||
OUT_RING (chan, 0x40000000); /* enable */
|
|
||||||
OUT_RING (chan, txs);
|
|
||||||
OUT_RING (chan, ps->filt | 0x2000 /* magic */);
|
|
||||||
OUT_RING (chan, (pt->width0 << 16) | pt->height0);
|
|
||||||
OUT_RING (chan, ps->bcol);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_fragtex_bind(struct nv20_context *nv20)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
struct nv20_fragment_program *fp = nv20->fragprog.active;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
unsigned samplers, unit;
|
|
||||||
|
|
||||||
samplers = nv20->fp_samplers & ~fp->samplers;
|
|
||||||
while (samplers) {
|
|
||||||
unit = ffs(samplers) - 1;
|
|
||||||
samplers &= ~(1 << unit);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV10TCL_TX_ENABLE(unit), 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
samplers = nv20->dirty_samplers & fp->samplers;
|
|
||||||
while (samplers) {
|
|
||||||
unit = ffs(samplers) - 1;
|
|
||||||
samplers &= ~(1 << unit);
|
|
||||||
|
|
||||||
nv20_fragtex_build(nv20, unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
nv20->fp_samplers = fp->samplers;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,226 +0,0 @@
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_format.h"
|
|
||||||
#include "util/u_math.h"
|
|
||||||
|
|
||||||
#include "nv20_context.h"
|
|
||||||
#include "nv20_screen.h"
|
|
||||||
#include "../nv04/nv04_surface_2d.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_miptree_layout(struct nv20_miptree *nv20mt)
|
|
||||||
{
|
|
||||||
struct pipe_texture *pt = &nv20mt->base;
|
|
||||||
uint width = pt->width0;
|
|
||||||
uint offset = 0;
|
|
||||||
int nr_faces, l, f;
|
|
||||||
uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER |
|
|
||||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
|
|
||||||
PIPE_TEXTURE_USAGE_RENDER_TARGET |
|
|
||||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
|
|
||||||
PIPE_TEXTURE_USAGE_PRIMARY);
|
|
||||||
|
|
||||||
if (pt->target == PIPE_TEXTURE_CUBE) {
|
|
||||||
nr_faces = 6;
|
|
||||||
} else {
|
|
||||||
nr_faces = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (l = 0; l <= pt->last_level; l++) {
|
|
||||||
if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR))
|
|
||||||
nv20mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64);
|
|
||||||
else
|
|
||||||
nv20mt->level[l].pitch = util_format_get_stride(pt->format, width);
|
|
||||||
|
|
||||||
nv20mt->level[l].image_offset =
|
|
||||||
CALLOC(nr_faces, sizeof(unsigned));
|
|
||||||
|
|
||||||
width = u_minify(width, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (f = 0; f < nr_faces; f++) {
|
|
||||||
for (l = 0; l < pt->last_level; l++) {
|
|
||||||
nv20mt->level[l].image_offset[f] = offset;
|
|
||||||
|
|
||||||
if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) &&
|
|
||||||
u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1)
|
|
||||||
offset += align(nv20mt->level[l].pitch * u_minify(pt->height0, l), 64);
|
|
||||||
else
|
|
||||||
offset += nv20mt->level[l].pitch * u_minify(pt->height0, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
nv20mt->level[l].image_offset[f] = offset;
|
|
||||||
offset += nv20mt->level[l].pitch * u_minify(pt->height0, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
nv20mt->total_size = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_texture *
|
|
||||||
nv20_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
|
|
||||||
const unsigned *stride, struct pipe_buffer *pb)
|
|
||||||
{
|
|
||||||
struct nv20_miptree *mt;
|
|
||||||
|
|
||||||
/* Only supports 2D, non-mipmapped textures for the moment */
|
|
||||||
if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
|
|
||||||
pt->depth0 != 1)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mt = CALLOC_STRUCT(nv20_miptree);
|
|
||||||
if (!mt)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
mt->base = *pt;
|
|
||||||
pipe_reference_init(&mt->base.reference, 1);
|
|
||||||
mt->base.screen = pscreen;
|
|
||||||
mt->level[0].pitch = stride[0];
|
|
||||||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
|
|
||||||
|
|
||||||
pipe_buffer_reference(&mt->buffer, pb);
|
|
||||||
mt->bo = nouveau_bo(mt->buffer);
|
|
||||||
return &mt->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_texture *
|
|
||||||
nv20_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt)
|
|
||||||
{
|
|
||||||
struct nv20_miptree *mt;
|
|
||||||
unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL |
|
|
||||||
NOUVEAU_BUFFER_USAGE_TEXTURE;
|
|
||||||
|
|
||||||
mt = MALLOC(sizeof(struct nv20_miptree));
|
|
||||||
if (!mt)
|
|
||||||
return NULL;
|
|
||||||
mt->base = *pt;
|
|
||||||
pipe_reference_init(&mt->base.reference, 1);
|
|
||||||
mt->base.screen = screen;
|
|
||||||
|
|
||||||
/* Swizzled textures must be POT */
|
|
||||||
if (pt->width0 & (pt->width0 - 1) ||
|
|
||||||
pt->height0 & (pt->height0 - 1))
|
|
||||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
else
|
|
||||||
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
|
|
||||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
|
|
||||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
|
|
||||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
else
|
|
||||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
|
|
||||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
else {
|
|
||||||
switch (pt->format) {
|
|
||||||
/* TODO: Figure out which formats can be swizzled */
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case PIPE_FORMAT_X8R8G8B8_UNORM:
|
|
||||||
case PIPE_FORMAT_R16_SNORM:
|
|
||||||
{
|
|
||||||
if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE))
|
|
||||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
|
|
||||||
buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
|
|
||||||
|
|
||||||
/* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear.
|
|
||||||
* If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy.
|
|
||||||
* This also happens for small mipmaps of large textures. */
|
|
||||||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64)
|
|
||||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
|
|
||||||
nv20_miptree_layout(mt);
|
|
||||||
|
|
||||||
mt->buffer = screen->buffer_create(screen, 256, buf_usage, mt->total_size);
|
|
||||||
if (!mt->buffer) {
|
|
||||||
FREE(mt);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
mt->bo = nouveau_bo(mt->buffer);
|
|
||||||
|
|
||||||
return &mt->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_miptree_destroy(struct pipe_texture *pt)
|
|
||||||
{
|
|
||||||
struct nv20_miptree *nv20mt = (struct nv20_miptree *)pt;
|
|
||||||
int l;
|
|
||||||
|
|
||||||
pipe_buffer_reference(&nv20mt->buffer, NULL);
|
|
||||||
for (l = 0; l <= pt->last_level; l++) {
|
|
||||||
if (nv20mt->level[l].image_offset)
|
|
||||||
FREE(nv20mt->level[l].image_offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_surface *
|
|
||||||
nv20_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt,
|
|
||||||
unsigned face, unsigned level, unsigned zslice,
|
|
||||||
unsigned flags)
|
|
||||||
{
|
|
||||||
struct nv20_miptree *nv20mt = (struct nv20_miptree *)pt;
|
|
||||||
struct nv04_surface *ns;
|
|
||||||
|
|
||||||
ns = CALLOC_STRUCT(nv04_surface);
|
|
||||||
if (!ns)
|
|
||||||
return NULL;
|
|
||||||
pipe_texture_reference(&ns->base.texture, pt);
|
|
||||||
ns->base.format = pt->format;
|
|
||||||
ns->base.width = u_minify(pt->width0, level);
|
|
||||||
ns->base.height = u_minify(pt->height0, level);
|
|
||||||
ns->base.usage = flags;
|
|
||||||
pipe_reference_init(&ns->base.reference, 1);
|
|
||||||
ns->base.face = face;
|
|
||||||
ns->base.level = level;
|
|
||||||
ns->base.zslice = zslice;
|
|
||||||
ns->pitch = nv20mt->level[level].pitch;
|
|
||||||
|
|
||||||
if (pt->target == PIPE_TEXTURE_CUBE) {
|
|
||||||
ns->base.offset = nv20mt->level[level].image_offset[face];
|
|
||||||
} else
|
|
||||||
if (pt->target == PIPE_TEXTURE_3D) {
|
|
||||||
ns->base.offset = nv20mt->level[level].image_offset[zslice];
|
|
||||||
} else {
|
|
||||||
ns->base.offset = nv20mt->level[level].image_offset[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create a linear temporary that we can render into if necessary.
|
|
||||||
* Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so
|
|
||||||
* ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/
|
|
||||||
if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE)
|
|
||||||
return &nv04_surface_wrap_for_render(screen, ((struct nv20_screen*)screen)->eng2d, ns)->base;
|
|
||||||
|
|
||||||
return &ns->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_miptree_surface_destroy(struct pipe_surface *ps)
|
|
||||||
{
|
|
||||||
struct nv04_surface* ns = (struct nv04_surface*)ps;
|
|
||||||
if(ns->backing)
|
|
||||||
{
|
|
||||||
struct nv20_screen* screen = (struct nv20_screen*)ps->texture->screen;
|
|
||||||
if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE)
|
|
||||||
screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height);
|
|
||||||
nv20_miptree_surface_destroy(&ns->backing->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_texture_reference(&ps->texture, NULL);
|
|
||||||
FREE(ps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen)
|
|
||||||
{
|
|
||||||
pscreen->texture_create = nv20_miptree_create;
|
|
||||||
pscreen->texture_blanket = nv20_miptree_blanket;
|
|
||||||
pscreen->texture_destroy = nv20_miptree_destroy;
|
|
||||||
pscreen->get_tex_surface = nv20_miptree_surface_get;
|
|
||||||
pscreen->tex_surface_destroy = nv20_miptree_surface_destroy;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,440 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
||||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* Build post-transformation, post-clipping vertex buffers and element
|
|
||||||
* lists by hooking into the end of the primitive pipeline and
|
|
||||||
* manipulating the vertex_id field in the vertex headers.
|
|
||||||
*
|
|
||||||
* XXX: work in progress
|
|
||||||
*
|
|
||||||
* \author José Fonseca <jrfonseca@tungstengraphics.com>
|
|
||||||
* \author Keith Whitwell <keith@tungstengraphics.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "util/u_debug.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_simple_screen.h"
|
|
||||||
|
|
||||||
#include "nv20_context.h"
|
|
||||||
#include "nv20_state.h"
|
|
||||||
|
|
||||||
#include "draw/draw_vbuf.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Primitive renderer for nv20.
|
|
||||||
*/
|
|
||||||
struct nv20_vbuf_render {
|
|
||||||
struct vbuf_render base;
|
|
||||||
|
|
||||||
struct nv20_context *nv20;
|
|
||||||
|
|
||||||
/** Vertex buffer in VRAM */
|
|
||||||
struct pipe_buffer *pbuffer;
|
|
||||||
|
|
||||||
/** Vertex buffer in normal memory */
|
|
||||||
void *mbuffer;
|
|
||||||
|
|
||||||
/** Vertex size in bytes */
|
|
||||||
/*unsigned vertex_size;*/
|
|
||||||
|
|
||||||
/** Hardware primitive */
|
|
||||||
unsigned hwprim;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Basically a cast wrapper.
|
|
||||||
*/
|
|
||||||
static INLINE struct nv20_vbuf_render *
|
|
||||||
nv20_vbuf_render(struct vbuf_render *render)
|
|
||||||
{
|
|
||||||
assert(render);
|
|
||||||
return (struct nv20_vbuf_render *)render;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nv20_vtxbuf_bind( struct nv20_context* nv20 )
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < NV20TCL_VTXBUF_ADDRESS__SIZE; i++) {
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_VTXBUF_ADDRESS(i), 1);
|
|
||||||
OUT_RING(chan, 0/*nv20->vtxbuf*/);
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(i) ,1);
|
|
||||||
OUT_RING(chan, 0/*XXX*/);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct vertex_info *
|
|
||||||
nv20_vbuf_render_get_vertex_info( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
|
|
||||||
struct nv20_context *nv20 = nv20_render->nv20;
|
|
||||||
|
|
||||||
nv20_emit_hw_state(nv20);
|
|
||||||
|
|
||||||
return &nv20->vertex_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv20__allocate_mbuffer(struct nv20_vbuf_render *nv20_render, size_t size)
|
|
||||||
{
|
|
||||||
nv20_render->mbuffer = MALLOC(size);
|
|
||||||
return nv20_render->mbuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20__allocate_pbuffer(struct nv20_vbuf_render *nv20_render, size_t size)
|
|
||||||
{
|
|
||||||
struct pipe_screen *screen = nv20_render->nv20->pipe.screen;
|
|
||||||
nv20_render->pbuffer = screen->buffer_create(screen, 64,
|
|
||||||
PIPE_BUFFER_USAGE_VERTEX, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv20_vbuf_render_allocate_vertices( struct vbuf_render *render,
|
|
||||||
ushort vertex_size,
|
|
||||||
ushort nr_vertices )
|
|
||||||
{
|
|
||||||
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
|
|
||||||
size_t size = (size_t)vertex_size * (size_t)nr_vertices;
|
|
||||||
void *buf;
|
|
||||||
|
|
||||||
assert(!nv20_render->pbuffer);
|
|
||||||
assert(!nv20_render->mbuffer);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For small amount of vertices, don't bother with pipe vertex
|
|
||||||
* buffer, the data will be passed directly via the fifo.
|
|
||||||
*/
|
|
||||||
/* XXX: Pipe vertex buffers don't work. */
|
|
||||||
if (0 && size > 16 * 1024) {
|
|
||||||
nv20__allocate_pbuffer(nv20_render, size);
|
|
||||||
/* umm yeah so this is ugly */
|
|
||||||
buf = nv20_render->pbuffer;
|
|
||||||
} else {
|
|
||||||
buf = nv20__allocate_mbuffer(nv20_render, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf)
|
|
||||||
nv20_render->nv20->dirty |= NV20_NEW_VTXARRAYS;
|
|
||||||
|
|
||||||
return buf ? TRUE : FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv20_vbuf_render_map_vertices( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
|
|
||||||
struct pipe_screen *pscreen = nv20_render->nv20->pipe.screen;
|
|
||||||
|
|
||||||
if (nv20_render->pbuffer) {
|
|
||||||
return pipe_buffer_map(pscreen, nv20_render->pbuffer,
|
|
||||||
PIPE_BUFFER_USAGE_CPU_WRITE);
|
|
||||||
} else if (nv20_render->mbuffer) {
|
|
||||||
return nv20_render->mbuffer;
|
|
||||||
} else
|
|
||||||
assert(0);
|
|
||||||
|
|
||||||
/* warnings be gone */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_vbuf_render_unmap_vertices( struct vbuf_render *render,
|
|
||||||
ushort min_index,
|
|
||||||
ushort max_index )
|
|
||||||
{
|
|
||||||
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
|
|
||||||
struct pipe_screen *pscreen = nv20_render->nv20->pipe.screen;
|
|
||||||
|
|
||||||
if (nv20_render->pbuffer)
|
|
||||||
pipe_buffer_unmap(pscreen, nv20_render->pbuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv20_vbuf_render_set_primitive( struct vbuf_render *render,
|
|
||||||
unsigned prim )
|
|
||||||
{
|
|
||||||
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
|
|
||||||
unsigned hwp = nvgl_primitive(prim);
|
|
||||||
if (hwp == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
nv20_render->hwprim = hwp;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t
|
|
||||||
nv20__vtxhwformat(unsigned stride, unsigned fields, unsigned type)
|
|
||||||
{
|
|
||||||
return (stride << NV20TCL_VTXFMT_STRIDE_SHIFT) |
|
|
||||||
(fields << NV20TCL_VTXFMT_SIZE_SHIFT) |
|
|
||||||
(type << NV20TCL_VTXFMT_TYPE_SHIFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned
|
|
||||||
nv20__emit_format(struct nv20_context *nv20, enum attrib_emit type, int hwattr)
|
|
||||||
{
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
uint32_t hwfmt = 0;
|
|
||||||
unsigned fields;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case EMIT_OMIT:
|
|
||||||
hwfmt = nv20__vtxhwformat(0, 0, 2);
|
|
||||||
fields = 0;
|
|
||||||
break;
|
|
||||||
case EMIT_1F:
|
|
||||||
hwfmt = nv20__vtxhwformat(4, 1, 2);
|
|
||||||
fields = 1;
|
|
||||||
break;
|
|
||||||
case EMIT_2F:
|
|
||||||
hwfmt = nv20__vtxhwformat(8, 2, 2);
|
|
||||||
fields = 2;
|
|
||||||
break;
|
|
||||||
case EMIT_3F:
|
|
||||||
hwfmt = nv20__vtxhwformat(12, 3, 2);
|
|
||||||
fields = 3;
|
|
||||||
break;
|
|
||||||
case EMIT_4F:
|
|
||||||
hwfmt = nv20__vtxhwformat(16, 4, 2);
|
|
||||||
fields = 4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("unhandled attrib_emit %d\n", type);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(hwattr), 1);
|
|
||||||
OUT_RING(chan, hwfmt);
|
|
||||||
return fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned
|
|
||||||
nv20__emit_vertex_array_format(struct nv20_context *nv20)
|
|
||||||
{
|
|
||||||
struct vertex_info *vinfo = &nv20->vertex_info;
|
|
||||||
int hwattr = NV20TCL_VTXFMT__SIZE;
|
|
||||||
int attr = 0;
|
|
||||||
unsigned nr_fields = 0;
|
|
||||||
|
|
||||||
while (hwattr-- > 0) {
|
|
||||||
if (vinfo->hwfmt[0] & (1 << hwattr)) {
|
|
||||||
nr_fields += nv20__emit_format(nv20,
|
|
||||||
vinfo->attrib[attr].emit, hwattr);
|
|
||||||
attr++;
|
|
||||||
} else
|
|
||||||
nv20__emit_format(nv20, EMIT_OMIT, hwattr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nr_fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20__draw_mbuffer(struct nv20_vbuf_render *nv20_render,
|
|
||||||
const ushort *indices,
|
|
||||||
uint nr_indices)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_render->nv20;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
struct vertex_info *vinfo = &nv20->vertex_info;
|
|
||||||
unsigned nr_fields;
|
|
||||||
int max_push;
|
|
||||||
ubyte *data = nv20_render->mbuffer;
|
|
||||||
int vsz = 4 * vinfo->size;
|
|
||||||
|
|
||||||
nr_fields = nv20__emit_vertex_array_format(nv20);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1);
|
|
||||||
OUT_RING(chan, nv20_render->hwprim);
|
|
||||||
|
|
||||||
max_push = 1200 / nr_fields;
|
|
||||||
while (nr_indices) {
|
|
||||||
int i;
|
|
||||||
int push = MIN2(nr_indices, max_push);
|
|
||||||
|
|
||||||
BEGIN_RING_NI(chan, kelvin, NV20TCL_VERTEX_DATA, push * nr_fields);
|
|
||||||
for (i = 0; i < push; i++) {
|
|
||||||
/* XXX: fixme to handle other than floats? */
|
|
||||||
int f = nr_fields;
|
|
||||||
float *attrv = (float*)&data[indices[i] * vsz];
|
|
||||||
while (f-- > 0)
|
|
||||||
OUT_RINGf(chan, *attrv++);
|
|
||||||
}
|
|
||||||
|
|
||||||
nr_indices -= push;
|
|
||||||
indices += push;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1);
|
|
||||||
OUT_RING(chan, NV20TCL_VERTEX_BEGIN_END_STOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20__draw_pbuffer(struct nv20_vbuf_render *nv20_render,
|
|
||||||
const ushort *indices,
|
|
||||||
uint nr_indices)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_render->nv20;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
int push, i;
|
|
||||||
|
|
||||||
NOUVEAU_ERR("nv20__draw_pbuffer: this path is broken.\n");
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1);
|
|
||||||
OUT_RELOCl(chan, nouveau_bo(nv20_render->pbuffer), 0,
|
|
||||||
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
|
|
||||||
OUT_RING(chan, nv20_render->hwprim);
|
|
||||||
|
|
||||||
if (nr_indices & 1) {
|
|
||||||
BEGIN_RING(chan, kelvin, NV10TCL_VB_ELEMENT_U32, 1);
|
|
||||||
OUT_RING (chan, indices[0]);
|
|
||||||
indices++; nr_indices--;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (nr_indices) {
|
|
||||||
// XXX too big/small ? check the size
|
|
||||||
push = MIN2(nr_indices, 1200 * 2);
|
|
||||||
|
|
||||||
BEGIN_RING_NI(chan, kelvin, NV10TCL_VB_ELEMENT_U16, push >> 1);
|
|
||||||
for (i = 0; i < push; i+=2)
|
|
||||||
OUT_RING(chan, (indices[i+1] << 16) | indices[i]);
|
|
||||||
|
|
||||||
nr_indices -= push;
|
|
||||||
indices += push;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1);
|
|
||||||
OUT_RING (chan, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_vbuf_render_draw( struct vbuf_render *render,
|
|
||||||
const ushort *indices,
|
|
||||||
uint nr_indices)
|
|
||||||
{
|
|
||||||
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
|
|
||||||
|
|
||||||
nv20_emit_hw_state(nv20_render->nv20);
|
|
||||||
|
|
||||||
if (nv20_render->pbuffer)
|
|
||||||
nv20__draw_pbuffer(nv20_render, indices, nr_indices);
|
|
||||||
else if (nv20_render->mbuffer)
|
|
||||||
nv20__draw_mbuffer(nv20_render, indices, nr_indices);
|
|
||||||
else
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_vbuf_render_release_vertices( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
|
|
||||||
struct nv20_context *nv20 = nv20_render->nv20;
|
|
||||||
|
|
||||||
if (nv20_render->pbuffer) {
|
|
||||||
pipe_buffer_reference(&nv20_render->pbuffer, NULL);
|
|
||||||
} else if (nv20_render->mbuffer) {
|
|
||||||
FREE(nv20_render->mbuffer);
|
|
||||||
nv20_render->mbuffer = NULL;
|
|
||||||
} else
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_vbuf_render_destroy( struct vbuf_render *render )
|
|
||||||
{
|
|
||||||
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
|
|
||||||
|
|
||||||
assert(!nv20_render->pbuffer);
|
|
||||||
assert(!nv20_render->mbuffer);
|
|
||||||
|
|
||||||
FREE(nv20_render);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new primitive render.
|
|
||||||
*/
|
|
||||||
static struct vbuf_render *
|
|
||||||
nv20_vbuf_render_create( struct nv20_context *nv20 )
|
|
||||||
{
|
|
||||||
struct nv20_vbuf_render *nv20_render = CALLOC_STRUCT(nv20_vbuf_render);
|
|
||||||
|
|
||||||
nv20_render->nv20 = nv20;
|
|
||||||
|
|
||||||
nv20_render->base.max_vertex_buffer_bytes = 16*1024;
|
|
||||||
nv20_render->base.max_indices = 1024;
|
|
||||||
nv20_render->base.get_vertex_info = nv20_vbuf_render_get_vertex_info;
|
|
||||||
nv20_render->base.allocate_vertices =
|
|
||||||
nv20_vbuf_render_allocate_vertices;
|
|
||||||
nv20_render->base.map_vertices = nv20_vbuf_render_map_vertices;
|
|
||||||
nv20_render->base.unmap_vertices = nv20_vbuf_render_unmap_vertices;
|
|
||||||
nv20_render->base.set_primitive = nv20_vbuf_render_set_primitive;
|
|
||||||
nv20_render->base.draw = nv20_vbuf_render_draw;
|
|
||||||
nv20_render->base.release_vertices = nv20_vbuf_render_release_vertices;
|
|
||||||
nv20_render->base.destroy = nv20_vbuf_render_destroy;
|
|
||||||
|
|
||||||
return &nv20_render->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new primitive vbuf/render stage.
|
|
||||||
*/
|
|
||||||
struct draw_stage *nv20_draw_vbuf_stage( struct nv20_context *nv20 )
|
|
||||||
{
|
|
||||||
struct vbuf_render *render;
|
|
||||||
struct draw_stage *stage;
|
|
||||||
|
|
||||||
render = nv20_vbuf_render_create(nv20);
|
|
||||||
if(!render)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
stage = draw_vbuf_stage( nv20->draw, render );
|
|
||||||
if(!stage) {
|
|
||||||
render->destroy(render);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stage;
|
|
||||||
}
|
|
||||||
|
|
@ -1,204 +0,0 @@
|
||||||
#include "pipe/p_screen.h"
|
|
||||||
|
|
||||||
#include "nv20_context.h"
|
|
||||||
#include "nv20_screen.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
nv20_screen_get_param(struct pipe_screen *screen, int param)
|
|
||||||
{
|
|
||||||
switch (param) {
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
|
|
||||||
return 2;
|
|
||||||
case PIPE_CAP_NPOT_TEXTURES:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TWO_SIDED_STENCIL:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_GLSL:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_POINT_SPRITE:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_OCCLUSION_QUERY:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
|
||||||
return 12;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
|
||||||
return 12;
|
|
||||||
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TGSI_CONT_SUPPORTED:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
|
||||||
return 0;
|
|
||||||
case NOUVEAU_CAP_HW_VTXBUF:
|
|
||||||
case NOUVEAU_CAP_HW_IDXBUF:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_INDEP_BLEND_FUNC:
|
|
||||||
return 0;
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
|
|
||||||
return 1;
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
|
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static float
|
|
||||||
nv20_screen_get_paramf(struct pipe_screen *screen, int param)
|
|
||||||
{
|
|
||||||
switch (param) {
|
|
||||||
case PIPE_CAP_MAX_LINE_WIDTH:
|
|
||||||
case PIPE_CAP_MAX_LINE_WIDTH_AA:
|
|
||||||
return 10.0;
|
|
||||||
case PIPE_CAP_MAX_POINT_WIDTH:
|
|
||||||
case PIPE_CAP_MAX_POINT_WIDTH_AA:
|
|
||||||
return 64.0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
|
|
||||||
return 2.0;
|
|
||||||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
|
|
||||||
return 4.0;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv20_screen_is_format_supported(struct pipe_screen *screen,
|
|
||||||
enum pipe_format format,
|
|
||||||
enum pipe_texture_target target,
|
|
||||||
unsigned tex_usage, unsigned geom_flags)
|
|
||||||
{
|
|
||||||
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_Z24S8_UNORM:
|
|
||||||
case PIPE_FORMAT_Z24X8_UNORM:
|
|
||||||
case PIPE_FORMAT_Z16_UNORM:
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (format) {
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case PIPE_FORMAT_A1R5G5B5_UNORM:
|
|
||||||
case PIPE_FORMAT_A4R4G4B4_UNORM:
|
|
||||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
|
||||||
case PIPE_FORMAT_L8_UNORM:
|
|
||||||
case PIPE_FORMAT_A8_UNORM:
|
|
||||||
case PIPE_FORMAT_I8_UNORM:
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_screen_destroy(struct pipe_screen *pscreen)
|
|
||||||
{
|
|
||||||
struct nv20_screen *screen = nv20_screen(pscreen);
|
|
||||||
|
|
||||||
nouveau_notifier_free(&screen->sync);
|
|
||||||
nouveau_grobj_free(&screen->kelvin);
|
|
||||||
nv04_surface_2d_takedown(&screen->eng2d);
|
|
||||||
|
|
||||||
nouveau_screen_fini(&screen->base);
|
|
||||||
|
|
||||||
FREE(pscreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_buffer *
|
|
||||||
nv20_surface_buffer(struct pipe_surface *surf)
|
|
||||||
{
|
|
||||||
struct nv20_miptree *mt = (struct nv20_miptree *)surf->texture;
|
|
||||||
|
|
||||||
return mt->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pipe_screen *
|
|
||||||
nv20_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
|
|
||||||
{
|
|
||||||
struct nv20_screen *screen = CALLOC_STRUCT(nv20_screen);
|
|
||||||
struct nouveau_channel *chan;
|
|
||||||
struct pipe_screen *pscreen;
|
|
||||||
unsigned kelvin_class = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!screen)
|
|
||||||
return NULL;
|
|
||||||
pscreen = &screen->base.base;
|
|
||||||
|
|
||||||
ret = nouveau_screen_init(&screen->base, dev);
|
|
||||||
if (ret) {
|
|
||||||
nv20_screen_destroy(pscreen);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
chan = screen->base.channel;
|
|
||||||
|
|
||||||
pscreen->winsys = ws;
|
|
||||||
pscreen->destroy = nv20_screen_destroy;
|
|
||||||
pscreen->get_param = nv20_screen_get_param;
|
|
||||||
pscreen->get_paramf = nv20_screen_get_paramf;
|
|
||||||
pscreen->is_format_supported = nv20_screen_is_format_supported;
|
|
||||||
|
|
||||||
nv20_screen_init_miptree_functions(pscreen);
|
|
||||||
nv20_screen_init_transfer_functions(pscreen);
|
|
||||||
|
|
||||||
/* 3D object */
|
|
||||||
if (dev->chipset >= 0x25)
|
|
||||||
kelvin_class = NV25TCL;
|
|
||||||
else if (dev->chipset >= 0x20)
|
|
||||||
kelvin_class = NV20TCL;
|
|
||||||
|
|
||||||
if (!kelvin_class || dev->chipset >= 0x30) {
|
|
||||||
NOUVEAU_ERR("Unknown nv2x chipset: nv%02x\n", dev->chipset);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nouveau_grobj_alloc(chan, 0xbeef0097, kelvin_class,
|
|
||||||
&screen->kelvin);
|
|
||||||
if (ret) {
|
|
||||||
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 2D engine setup */
|
|
||||||
screen->eng2d = nv04_surface_2d_init(&screen->base);
|
|
||||||
screen->eng2d->buf = nv20_surface_buffer;
|
|
||||||
|
|
||||||
/* Notifier for sync purposes */
|
|
||||||
ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
|
|
||||||
if (ret) {
|
|
||||||
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
|
|
||||||
nv20_screen_destroy(pscreen);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pscreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef __NV20_SCREEN_H__
|
|
||||||
#define __NV20_SCREEN_H__
|
|
||||||
|
|
||||||
#include "nouveau/nouveau_screen.h"
|
|
||||||
#include "nv04/nv04_surface_2d.h"
|
|
||||||
|
|
||||||
struct nv20_screen {
|
|
||||||
struct nouveau_screen base;
|
|
||||||
|
|
||||||
struct nouveau_winsys *nvws;
|
|
||||||
|
|
||||||
/* HW graphics objects */
|
|
||||||
struct nv04_surface_2d *eng2d;
|
|
||||||
struct nouveau_grobj *kelvin;
|
|
||||||
struct nouveau_notifier *sync;
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE struct nv20_screen *
|
|
||||||
nv20_screen(struct pipe_screen *screen)
|
|
||||||
{
|
|
||||||
return (struct nv20_screen *)screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_screen_init_transfer_functions(struct pipe_screen *pscreen);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,583 +0,0 @@
|
||||||
#include "draw/draw_context.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_shader_tokens.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "tgsi/tgsi_parse.h"
|
|
||||||
|
|
||||||
#include "nv20_context.h"
|
|
||||||
#include "nv20_state.h"
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv20_blend_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_blend_state *cso)
|
|
||||||
{
|
|
||||||
struct nv20_blend_state *cb;
|
|
||||||
|
|
||||||
cb = MALLOC(sizeof(struct nv20_blend_state));
|
|
||||||
|
|
||||||
cb->b_enable = cso->rt[0].blend_enable ? 1 : 0;
|
|
||||||
cb->b_srcfunc = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) |
|
|
||||||
(nvgl_blend_func(cso->rt[0].rgb_src_factor)));
|
|
||||||
cb->b_dstfunc = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) |
|
|
||||||
(nvgl_blend_func(cso->rt[0].rgb_dst_factor)));
|
|
||||||
|
|
||||||
cb->c_mask = (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01<<24) : 0) |
|
|
||||||
((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01<<16) : 0) |
|
|
||||||
((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) |
|
|
||||||
((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01<< 0) : 0));
|
|
||||||
|
|
||||||
cb->d_enable = cso->dither ? 1 : 0;
|
|
||||||
|
|
||||||
return (void *)cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_blend_state_bind(struct pipe_context *pipe, void *blend)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
nv20->blend = (struct nv20_blend_state*)blend;
|
|
||||||
|
|
||||||
nv20->dirty |= NV20_NEW_BLEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_blend_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
FREE(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE unsigned
|
|
||||||
wrap_mode(unsigned wrap) {
|
|
||||||
unsigned ret;
|
|
||||||
|
|
||||||
switch (wrap) {
|
|
||||||
case PIPE_TEX_WRAP_REPEAT:
|
|
||||||
ret = NV20TCL_TX_WRAP_S_REPEAT;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_REPEAT:
|
|
||||||
ret = NV20TCL_TX_WRAP_S_MIRRORED_REPEAT;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
|
|
||||||
ret = NV20TCL_TX_WRAP_S_CLAMP_TO_EDGE;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
|
|
||||||
ret = NV20TCL_TX_WRAP_S_CLAMP_TO_BORDER;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_CLAMP:
|
|
||||||
ret = NV20TCL_TX_WRAP_S_CLAMP;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
|
|
||||||
case PIPE_TEX_WRAP_MIRROR_CLAMP:
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
|
|
||||||
ret = NV20TCL_TX_WRAP_S_REPEAT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ret >> NV20TCL_TX_WRAP_S_SHIFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv20_sampler_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_sampler_state *cso)
|
|
||||||
{
|
|
||||||
struct nv20_sampler_state *ps;
|
|
||||||
uint32_t filter = 0;
|
|
||||||
|
|
||||||
ps = MALLOC(sizeof(struct nv20_sampler_state));
|
|
||||||
|
|
||||||
ps->wrap = ((wrap_mode(cso->wrap_s) << NV20TCL_TX_WRAP_S_SHIFT) |
|
|
||||||
(wrap_mode(cso->wrap_t) << NV20TCL_TX_WRAP_T_SHIFT));
|
|
||||||
|
|
||||||
ps->en = 0;
|
|
||||||
if (cso->max_anisotropy > 1.0) {
|
|
||||||
/* no idea, binary driver sets it, works without it.. meh.. */
|
|
||||||
ps->wrap |= (1 << 5);
|
|
||||||
|
|
||||||
/* if (cso->max_anisotropy >= 8.0) {
|
|
||||||
ps->en |= NV20TCL_TX_ENABLE_ANISO_8X;
|
|
||||||
} else
|
|
||||||
if (cso->max_anisotropy >= 4.0) {
|
|
||||||
ps->en |= NV20TCL_TX_ENABLE_ANISO_4X;
|
|
||||||
} else {
|
|
||||||
ps->en |= NV20TCL_TX_ENABLE_ANISO_2X;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cso->mag_img_filter) {
|
|
||||||
case PIPE_TEX_FILTER_LINEAR:
|
|
||||||
filter |= NV20TCL_TX_FILTER_MAGNIFY_LINEAR;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_FILTER_NEAREST:
|
|
||||||
default:
|
|
||||||
filter |= NV20TCL_TX_FILTER_MAGNIFY_NEAREST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cso->min_img_filter) {
|
|
||||||
case PIPE_TEX_FILTER_LINEAR:
|
|
||||||
switch (cso->min_mip_filter) {
|
|
||||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
|
||||||
filter |=
|
|
||||||
NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
|
||||||
filter |= NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_NONE:
|
|
||||||
default:
|
|
||||||
filter |= NV20TCL_TX_FILTER_MINIFY_LINEAR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_FILTER_NEAREST:
|
|
||||||
default:
|
|
||||||
switch (cso->min_mip_filter) {
|
|
||||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
|
||||||
filter |=
|
|
||||||
NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
|
||||||
filter |=
|
|
||||||
NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
|
|
||||||
break;
|
|
||||||
case PIPE_TEX_MIPFILTER_NONE:
|
|
||||||
default:
|
|
||||||
filter |= NV20TCL_TX_FILTER_MINIFY_NEAREST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ps->filt = filter;
|
|
||||||
|
|
||||||
/* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
|
|
||||||
switch (cso->compare_func) {
|
|
||||||
case PIPE_FUNC_NEVER:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_GREATER:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_EQUAL:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_GEQUAL:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_LESS:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_NOTEQUAL:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_LEQUAL:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL;
|
|
||||||
break;
|
|
||||||
case PIPE_FUNC_ALWAYS:
|
|
||||||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
|
|
||||||
(float_to_ubyte(cso->border_color[0]) << 16) |
|
|
||||||
(float_to_ubyte(cso->border_color[1]) << 8) |
|
|
||||||
(float_to_ubyte(cso->border_color[2]) << 0));
|
|
||||||
|
|
||||||
return (void *)ps;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
unsigned unit;
|
|
||||||
|
|
||||||
for (unit = 0; unit < nr; unit++) {
|
|
||||||
nv20->tex_sampler[unit] = sampler[unit];
|
|
||||||
nv20->dirty_samplers |= (1 << unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
FREE(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
|
|
||||||
struct pipe_texture **miptree)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
unsigned unit;
|
|
||||||
|
|
||||||
for (unit = 0; unit < nr; unit++) {
|
|
||||||
nv20->tex_miptree[unit] = (struct nv20_miptree *)miptree[unit];
|
|
||||||
nv20->dirty_samplers |= (1 << unit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv20_rasterizer_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_rasterizer_state *cso)
|
|
||||||
{
|
|
||||||
struct nv20_rasterizer_state *rs;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/*XXX: ignored:
|
|
||||||
* light_twoside
|
|
||||||
* offset_cw/ccw -nohw
|
|
||||||
* scissor
|
|
||||||
* point_smooth -nohw
|
|
||||||
* multisample
|
|
||||||
* offset_units / offset_scale
|
|
||||||
*/
|
|
||||||
rs = MALLOC(sizeof(struct nv20_rasterizer_state));
|
|
||||||
|
|
||||||
rs->templ = cso;
|
|
||||||
|
|
||||||
rs->shade_model = cso->flatshade ? NV20TCL_SHADE_MODEL_FLAT :
|
|
||||||
NV20TCL_SHADE_MODEL_SMOOTH;
|
|
||||||
|
|
||||||
rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff;
|
|
||||||
rs->line_smooth_en = cso->line_smooth ? 1 : 0;
|
|
||||||
|
|
||||||
/* XXX: nv20 and nv25 different! */
|
|
||||||
rs->point_size = *(uint32_t*)&cso->point_size;
|
|
||||||
|
|
||||||
rs->poly_smooth_en = cso->poly_smooth ? 1 : 0;
|
|
||||||
|
|
||||||
if (cso->front_winding == PIPE_WINDING_CCW) {
|
|
||||||
rs->front_face = NV20TCL_FRONT_FACE_CCW;
|
|
||||||
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw);
|
|
||||||
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw);
|
|
||||||
} else {
|
|
||||||
rs->front_face = NV20TCL_FRONT_FACE_CW;
|
|
||||||
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw);
|
|
||||||
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cso->cull_mode) {
|
|
||||||
case PIPE_WINDING_CCW:
|
|
||||||
rs->cull_face_en = 1;
|
|
||||||
if (cso->front_winding == PIPE_WINDING_CCW)
|
|
||||||
rs->cull_face = NV20TCL_CULL_FACE_FRONT;
|
|
||||||
else
|
|
||||||
rs->cull_face = NV20TCL_CULL_FACE_BACK;
|
|
||||||
break;
|
|
||||||
case PIPE_WINDING_CW:
|
|
||||||
rs->cull_face_en = 1;
|
|
||||||
if (cso->front_winding == PIPE_WINDING_CW)
|
|
||||||
rs->cull_face = NV20TCL_CULL_FACE_FRONT;
|
|
||||||
else
|
|
||||||
rs->cull_face = NV20TCL_CULL_FACE_BACK;
|
|
||||||
break;
|
|
||||||
case PIPE_WINDING_BOTH:
|
|
||||||
rs->cull_face_en = 1;
|
|
||||||
rs->cull_face = NV20TCL_CULL_FACE_FRONT_AND_BACK;
|
|
||||||
break;
|
|
||||||
case PIPE_WINDING_NONE:
|
|
||||||
default:
|
|
||||||
rs->cull_face_en = 0;
|
|
||||||
rs->cull_face = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cso->point_sprite) {
|
|
||||||
rs->point_sprite = (1 << 0);
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE)
|
|
||||||
rs->point_sprite |= (1 << (8 + i));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rs->point_sprite = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (void *)rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_rasterizer_state_bind(struct pipe_context *pipe, void *rast)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
nv20->rast = (struct nv20_rasterizer_state*)rast;
|
|
||||||
|
|
||||||
draw_set_rasterizer_state(nv20->draw, (nv20->rast ? nv20->rast->templ : NULL));
|
|
||||||
|
|
||||||
nv20->dirty |= NV20_NEW_RAST;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
FREE(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv20_depth_stencil_alpha_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_depth_stencil_alpha_state *cso)
|
|
||||||
{
|
|
||||||
struct nv20_depth_stencil_alpha_state *hw;
|
|
||||||
|
|
||||||
hw = MALLOC(sizeof(struct nv20_depth_stencil_alpha_state));
|
|
||||||
|
|
||||||
hw->depth.func = nvgl_comparison_op(cso->depth.func);
|
|
||||||
hw->depth.write_enable = cso->depth.writemask ? 1 : 0;
|
|
||||||
hw->depth.test_enable = cso->depth.enabled ? 1 : 0;
|
|
||||||
|
|
||||||
hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0;
|
|
||||||
hw->stencil.wmask = cso->stencil[0].writemask;
|
|
||||||
hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func);
|
|
||||||
hw->stencil.ref = cso->stencil[0].ref_value;
|
|
||||||
hw->stencil.vmask = cso->stencil[0].valuemask;
|
|
||||||
hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op);
|
|
||||||
hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op);
|
|
||||||
hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op);
|
|
||||||
|
|
||||||
hw->alpha.enabled = cso->alpha.enabled ? 1 : 0;
|
|
||||||
hw->alpha.func = nvgl_comparison_op(cso->alpha.func);
|
|
||||||
hw->alpha.ref = float_to_ubyte(cso->alpha.ref_value);
|
|
||||||
|
|
||||||
return (void *)hw;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
nv20->dsa = (struct nv20_depth_stencil_alpha_state*)dsa;
|
|
||||||
|
|
||||||
nv20->dirty |= NV20_NEW_DSA;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
FREE(hwcso);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv20_vp_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_shader_state *templ)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
return draw_create_vertex_shader(nv20->draw, templ);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_vp_state_bind(struct pipe_context *pipe, void *shader)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
draw_bind_vertex_shader(nv20->draw, (struct draw_vertex_shader *) shader);
|
|
||||||
|
|
||||||
nv20->dirty |= NV20_NEW_VERTPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_vp_state_delete(struct pipe_context *pipe, void *shader)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
draw_delete_vertex_shader(nv20->draw, (struct draw_vertex_shader *) shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv20_fp_state_create(struct pipe_context *pipe,
|
|
||||||
const struct pipe_shader_state *cso)
|
|
||||||
{
|
|
||||||
struct nv20_fragment_program *fp;
|
|
||||||
|
|
||||||
fp = CALLOC(1, sizeof(struct nv20_fragment_program));
|
|
||||||
fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
|
|
||||||
|
|
||||||
tgsi_scan_shader(cso->tokens, &fp->info);
|
|
||||||
|
|
||||||
return (void *)fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_fp_state_bind(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
struct nv20_fragment_program *fp = hwcso;
|
|
||||||
|
|
||||||
nv20->fragprog.current = fp;
|
|
||||||
nv20->dirty |= NV20_NEW_FRAGPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_fp_state_delete(struct pipe_context *pipe, void *hwcso)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
struct nv20_fragment_program *fp = hwcso;
|
|
||||||
|
|
||||||
nv20_fragprog_destroy(nv20, fp);
|
|
||||||
FREE((void*)fp->pipe.tokens);
|
|
||||||
FREE(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_blend_color(struct pipe_context *pipe,
|
|
||||||
const struct pipe_blend_color *bcol)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
nv20->blend_color = (struct pipe_blend_color*)bcol;
|
|
||||||
|
|
||||||
nv20->dirty |= NV20_NEW_BLENDCOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_clip_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_clip_state *clip)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
draw_set_clip_state(nv20->draw, clip);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
|
||||||
struct pipe_buffer *buf )
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
struct pipe_screen *pscreen = pipe->screen;
|
|
||||||
|
|
||||||
assert(shader < PIPE_SHADER_TYPES);
|
|
||||||
assert(index == 0);
|
|
||||||
|
|
||||||
if (buf) {
|
|
||||||
void *mapped;
|
|
||||||
if (buf->size &&
|
|
||||||
(mapped = pipe_buffer_map(pscreen, buf, PIPE_BUFFER_USAGE_CPU_READ)))
|
|
||||||
{
|
|
||||||
memcpy(nv20->constbuf[shader], mapped, buf->size);
|
|
||||||
nv20->constbuf_nr[shader] =
|
|
||||||
buf->size / (4 * sizeof(float));
|
|
||||||
pipe_buffer_unmap(pscreen, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_framebuffer_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_framebuffer_state *fb)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
nv20->framebuffer = (struct pipe_framebuffer_state*)fb;
|
|
||||||
|
|
||||||
nv20->dirty |= NV20_NEW_FRAMEBUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_polygon_stipple(struct pipe_context *pipe,
|
|
||||||
const struct pipe_poly_stipple *stipple)
|
|
||||||
{
|
|
||||||
NOUVEAU_ERR("line stipple hahaha\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_scissor_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_scissor_state *s)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
nv20->scissor = (struct pipe_scissor_state*)s;
|
|
||||||
|
|
||||||
nv20->dirty |= NV20_NEW_SCISSOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_viewport_state(struct pipe_context *pipe,
|
|
||||||
const struct pipe_viewport_state *vpt)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
nv20->viewport = (struct pipe_viewport_state*)vpt;
|
|
||||||
|
|
||||||
draw_set_viewport_state(nv20->draw, nv20->viewport);
|
|
||||||
|
|
||||||
nv20->dirty |= NV20_NEW_VIEWPORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
|
|
||||||
const struct pipe_vertex_buffer *vb)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
memcpy(nv20->vtxbuf, vb, sizeof(*vb) * count);
|
|
||||||
nv20->dirty |= NV20_NEW_VTXARRAYS;
|
|
||||||
|
|
||||||
draw_set_vertex_buffers(nv20->draw, count, vb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_set_vertex_elements(struct pipe_context *pipe, unsigned count,
|
|
||||||
const struct pipe_vertex_element *ve)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
|
|
||||||
memcpy(nv20->vtxelt, ve, sizeof(*ve) * count);
|
|
||||||
nv20->dirty |= NV20_NEW_VTXARRAYS;
|
|
||||||
|
|
||||||
draw_set_vertex_elements(nv20->draw, count, ve);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_init_state_functions(struct nv20_context *nv20)
|
|
||||||
{
|
|
||||||
nv20->pipe.create_blend_state = nv20_blend_state_create;
|
|
||||||
nv20->pipe.bind_blend_state = nv20_blend_state_bind;
|
|
||||||
nv20->pipe.delete_blend_state = nv20_blend_state_delete;
|
|
||||||
|
|
||||||
nv20->pipe.create_sampler_state = nv20_sampler_state_create;
|
|
||||||
nv20->pipe.bind_fragment_sampler_states = nv20_sampler_state_bind;
|
|
||||||
nv20->pipe.delete_sampler_state = nv20_sampler_state_delete;
|
|
||||||
nv20->pipe.set_fragment_sampler_textures = nv20_set_sampler_texture;
|
|
||||||
|
|
||||||
nv20->pipe.create_rasterizer_state = nv20_rasterizer_state_create;
|
|
||||||
nv20->pipe.bind_rasterizer_state = nv20_rasterizer_state_bind;
|
|
||||||
nv20->pipe.delete_rasterizer_state = nv20_rasterizer_state_delete;
|
|
||||||
|
|
||||||
nv20->pipe.create_depth_stencil_alpha_state =
|
|
||||||
nv20_depth_stencil_alpha_state_create;
|
|
||||||
nv20->pipe.bind_depth_stencil_alpha_state =
|
|
||||||
nv20_depth_stencil_alpha_state_bind;
|
|
||||||
nv20->pipe.delete_depth_stencil_alpha_state =
|
|
||||||
nv20_depth_stencil_alpha_state_delete;
|
|
||||||
|
|
||||||
nv20->pipe.create_vs_state = nv20_vp_state_create;
|
|
||||||
nv20->pipe.bind_vs_state = nv20_vp_state_bind;
|
|
||||||
nv20->pipe.delete_vs_state = nv20_vp_state_delete;
|
|
||||||
|
|
||||||
nv20->pipe.create_fs_state = nv20_fp_state_create;
|
|
||||||
nv20->pipe.bind_fs_state = nv20_fp_state_bind;
|
|
||||||
nv20->pipe.delete_fs_state = nv20_fp_state_delete;
|
|
||||||
|
|
||||||
nv20->pipe.set_blend_color = nv20_set_blend_color;
|
|
||||||
nv20->pipe.set_clip_state = nv20_set_clip_state;
|
|
||||||
nv20->pipe.set_constant_buffer = nv20_set_constant_buffer;
|
|
||||||
nv20->pipe.set_framebuffer_state = nv20_set_framebuffer_state;
|
|
||||||
nv20->pipe.set_polygon_stipple = nv20_set_polygon_stipple;
|
|
||||||
nv20->pipe.set_scissor_state = nv20_set_scissor_state;
|
|
||||||
nv20->pipe.set_viewport_state = nv20_set_viewport_state;
|
|
||||||
|
|
||||||
nv20->pipe.set_vertex_buffers = nv20_set_vertex_buffers;
|
|
||||||
nv20->pipe.set_vertex_elements = nv20_set_vertex_elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
#ifndef __NV20_STATE_H__
|
|
||||||
#define __NV20_STATE_H__
|
|
||||||
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "tgsi/tgsi_scan.h"
|
|
||||||
|
|
||||||
struct nv20_blend_state {
|
|
||||||
uint32_t b_enable;
|
|
||||||
uint32_t b_srcfunc;
|
|
||||||
uint32_t b_dstfunc;
|
|
||||||
|
|
||||||
uint32_t c_mask;
|
|
||||||
|
|
||||||
uint32_t d_enable;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv20_sampler_state {
|
|
||||||
uint32_t wrap;
|
|
||||||
uint32_t en;
|
|
||||||
uint32_t filt;
|
|
||||||
uint32_t bcol;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv20_rasterizer_state {
|
|
||||||
uint32_t shade_model;
|
|
||||||
|
|
||||||
uint32_t line_width;
|
|
||||||
uint32_t line_smooth_en;
|
|
||||||
|
|
||||||
uint32_t point_size;
|
|
||||||
|
|
||||||
uint32_t poly_smooth_en;
|
|
||||||
|
|
||||||
uint32_t poly_mode_front;
|
|
||||||
uint32_t poly_mode_back;
|
|
||||||
|
|
||||||
uint32_t front_face;
|
|
||||||
uint32_t cull_face;
|
|
||||||
uint32_t cull_face_en;
|
|
||||||
|
|
||||||
uint32_t point_sprite;
|
|
||||||
|
|
||||||
const struct pipe_rasterizer_state *templ;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv20_vertex_program_exec {
|
|
||||||
uint32_t data[4];
|
|
||||||
boolean has_branch_offset;
|
|
||||||
int const_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv20_vertex_program_data {
|
|
||||||
int index; /* immediates == -1 */
|
|
||||||
float value[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv20_vertex_program {
|
|
||||||
const struct pipe_shader_state *pipe;
|
|
||||||
|
|
||||||
boolean translated;
|
|
||||||
struct nv20_vertex_program_exec *insns;
|
|
||||||
unsigned nr_insns;
|
|
||||||
struct nv20_vertex_program_data *consts;
|
|
||||||
unsigned nr_consts;
|
|
||||||
|
|
||||||
struct nouveau_resource *exec;
|
|
||||||
unsigned exec_start;
|
|
||||||
struct nouveau_resource *data;
|
|
||||||
unsigned data_start;
|
|
||||||
unsigned data_start_min;
|
|
||||||
|
|
||||||
uint32_t ir;
|
|
||||||
uint32_t or;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv20_fragment_program_data {
|
|
||||||
unsigned offset;
|
|
||||||
unsigned index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv20_fragment_program {
|
|
||||||
struct pipe_shader_state pipe;
|
|
||||||
struct tgsi_shader_info info;
|
|
||||||
|
|
||||||
boolean translated;
|
|
||||||
boolean on_hw;
|
|
||||||
unsigned samplers;
|
|
||||||
|
|
||||||
uint32_t *insn;
|
|
||||||
int insn_len;
|
|
||||||
|
|
||||||
struct nv20_fragment_program_data *consts;
|
|
||||||
unsigned nr_consts;
|
|
||||||
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
|
|
||||||
uint32_t fp_control;
|
|
||||||
uint32_t fp_reg_control;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct nv20_depth_stencil_alpha_state {
|
|
||||||
struct {
|
|
||||||
uint32_t func;
|
|
||||||
uint32_t write_enable;
|
|
||||||
uint32_t test_enable;
|
|
||||||
} depth;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint32_t enable;
|
|
||||||
uint32_t wmask;
|
|
||||||
uint32_t func;
|
|
||||||
uint32_t ref;
|
|
||||||
uint32_t vmask;
|
|
||||||
uint32_t fail;
|
|
||||||
uint32_t zfail;
|
|
||||||
uint32_t zpass;
|
|
||||||
} stencil;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint32_t enabled;
|
|
||||||
uint32_t func;
|
|
||||||
uint32_t ref;
|
|
||||||
} alpha;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nv20_miptree {
|
|
||||||
struct pipe_texture base;
|
|
||||||
struct nouveau_bo *bo;
|
|
||||||
|
|
||||||
struct pipe_buffer *buffer;
|
|
||||||
uint total_size;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint pitch;
|
|
||||||
uint *image_offset;
|
|
||||||
} level[PIPE_MAX_TEXTURE_LEVELS];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,426 +0,0 @@
|
||||||
#include "nv20_context.h"
|
|
||||||
#include "nv20_state.h"
|
|
||||||
#include "draw/draw_context.h"
|
|
||||||
|
|
||||||
static void nv20_state_emit_blend(struct nv20_context* nv20)
|
|
||||||
{
|
|
||||||
struct nv20_blend_state *b = nv20->blend;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_DITHER_ENABLE, 1);
|
|
||||||
OUT_RING (chan, b->d_enable);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1);
|
|
||||||
OUT_RING (chan, b->b_enable);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_SRC, 2);
|
|
||||||
OUT_RING (chan, b->b_srcfunc);
|
|
||||||
OUT_RING (chan, b->b_dstfunc);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MASK, 1);
|
|
||||||
OUT_RING (chan, b->c_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv20_state_emit_blend_color(struct nv20_context* nv20)
|
|
||||||
{
|
|
||||||
struct pipe_blend_color *c = nv20->blend_color;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_BLEND_COLOR, 1);
|
|
||||||
OUT_RING (chan,
|
|
||||||
(float_to_ubyte(c->color[3]) << 24)|
|
|
||||||
(float_to_ubyte(c->color[0]) << 16)|
|
|
||||||
(float_to_ubyte(c->color[1]) << 8) |
|
|
||||||
(float_to_ubyte(c->color[2]) << 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv20_state_emit_rast(struct nv20_context* nv20)
|
|
||||||
{
|
|
||||||
struct nv20_rasterizer_state *r = nv20->rast;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_SHADE_MODEL, 2);
|
|
||||||
OUT_RING (chan, r->shade_model);
|
|
||||||
OUT_RING (chan, r->line_width);
|
|
||||||
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1);
|
|
||||||
OUT_RING (chan, r->point_size);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_MODE_FRONT, 2);
|
|
||||||
OUT_RING (chan, r->poly_mode_front);
|
|
||||||
OUT_RING (chan, r->poly_mode_back);
|
|
||||||
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE, 2);
|
|
||||||
OUT_RING (chan, r->cull_face);
|
|
||||||
OUT_RING (chan, r->front_face);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 2);
|
|
||||||
OUT_RING (chan, r->line_smooth_en);
|
|
||||||
OUT_RING (chan, r->poly_smooth_en);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE_ENABLE, 1);
|
|
||||||
OUT_RING (chan, r->cull_face_en);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv20_state_emit_dsa(struct nv20_context* nv20)
|
|
||||||
{
|
|
||||||
struct nv20_depth_stencil_alpha_state *d = nv20->dsa;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_FUNC, 1);
|
|
||||||
OUT_RING (chan, d->depth.func);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1);
|
|
||||||
OUT_RING (chan, d->depth.write_enable);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1);
|
|
||||||
OUT_RING (chan, d->depth.test_enable);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_UNK17D8, 1);
|
|
||||||
OUT_RING (chan, 1);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_ENABLE, 1);
|
|
||||||
OUT_RING (chan, d->stencil.enable);
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_MASK, 7);
|
|
||||||
OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1);
|
|
||||||
OUT_RING (chan, d->alpha.enabled);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_FUNC, 1);
|
|
||||||
OUT_RING (chan, d->alpha.func);
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_REF, 1);
|
|
||||||
OUT_RING (chan, d->alpha.ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv20_state_emit_viewport(struct nv20_context* nv20)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv20_state_emit_scissor(struct nv20_context* nv20)
|
|
||||||
{
|
|
||||||
/* NV20TCL_SCISSOR_* is probably a software method */
|
|
||||||
/* struct pipe_scissor_state *s = nv20->scissor;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_SCISSOR_HORIZ, 2);
|
|
||||||
OUT_RING (chan, ((s->maxx - s->minx) << 16) | s->minx);
|
|
||||||
OUT_RING (chan, ((s->maxy - s->miny) << 16) | s->miny);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv20_state_emit_framebuffer(struct nv20_context* nv20)
|
|
||||||
{
|
|
||||||
struct pipe_framebuffer_state* fb = nv20->framebuffer;
|
|
||||||
struct nv04_surface *rt, *zeta = NULL;
|
|
||||||
uint32_t rt_format, w, h;
|
|
||||||
int colour_format = 0, zeta_format = 0;
|
|
||||||
struct nv20_miptree *nv20mt = 0;
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
|
|
||||||
w = fb->cbufs[0]->width;
|
|
||||||
h = fb->cbufs[0]->height;
|
|
||||||
colour_format = fb->cbufs[0]->format;
|
|
||||||
rt = (struct nv04_surface *)fb->cbufs[0];
|
|
||||||
|
|
||||||
if (fb->zsbuf) {
|
|
||||||
if (colour_format) {
|
|
||||||
assert(w == fb->zsbuf->width);
|
|
||||||
assert(h == fb->zsbuf->height);
|
|
||||||
} else {
|
|
||||||
w = fb->zsbuf->width;
|
|
||||||
h = fb->zsbuf->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
zeta_format = fb->zsbuf->format;
|
|
||||||
zeta = (struct nv04_surface *)fb->zsbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_format = NV20TCL_RT_FORMAT_TYPE_LINEAR | 0x20;
|
|
||||||
|
|
||||||
switch (colour_format) {
|
|
||||||
case PIPE_FORMAT_X8R8G8B8_UNORM:
|
|
||||||
rt_format |= NV20TCL_RT_FORMAT_COLOR_X8R8G8B8;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
|
||||||
case 0:
|
|
||||||
rt_format |= NV20TCL_RT_FORMAT_COLOR_A8R8G8B8;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
|
||||||
rt_format |= NV20TCL_RT_FORMAT_COLOR_R5G6B5;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zeta) {
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1);
|
|
||||||
OUT_RING (chan, rt->pitch | (zeta->pitch << 16));
|
|
||||||
} else {
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1);
|
|
||||||
OUT_RING (chan, rt->pitch | (rt->pitch << 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
nv20mt = (struct nv20_miptree *)rt->base.texture;
|
|
||||||
nv20->rt[0] = nv20mt->buffer;
|
|
||||||
|
|
||||||
if (zeta_format)
|
|
||||||
{
|
|
||||||
nv20mt = (struct nv20_miptree *)zeta->base.texture;
|
|
||||||
nv20->zeta = nv20mt->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 3);
|
|
||||||
OUT_RING (chan, (w << 16) | 0);
|
|
||||||
OUT_RING (chan, (h << 16) | 0); /*NV20TCL_RT_VERT */
|
|
||||||
OUT_RING (chan, rt_format); /* NV20TCL_RT_FORMAT */
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 2);
|
|
||||||
OUT_RING (chan, ((w - 1) << 16) | 0);
|
|
||||||
OUT_RING (chan, ((h - 1) << 16) | 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nv20_vertex_layout(struct nv20_context *nv20)
|
|
||||||
{
|
|
||||||
struct nv20_fragment_program *fp = nv20->fragprog.current;
|
|
||||||
struct draw_context *dc = nv20->draw;
|
|
||||||
int src;
|
|
||||||
int i;
|
|
||||||
struct vertex_info *vinfo = &nv20->vertex_info;
|
|
||||||
const enum interp_mode colorInterp = INTERP_LINEAR;
|
|
||||||
boolean colors[2] = { FALSE };
|
|
||||||
boolean generics[12] = { FALSE };
|
|
||||||
boolean fog = FALSE;
|
|
||||||
|
|
||||||
memset(vinfo, 0, sizeof(*vinfo));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Assumed NV20 hardware vertex attribute order:
|
|
||||||
* 0 position, 1 ?, 2 ?, 3 col0,
|
|
||||||
* 4 col1?, 5 ?, 6 ?, 7 ?,
|
|
||||||
* 8 ?, 9 tex0, 10 tex1, 11 tex2,
|
|
||||||
* 12 tex3, 13 ?, 14 ?, 15 ?
|
|
||||||
* unaccounted: wgh, nor, fog
|
|
||||||
* There are total 16 attrs.
|
|
||||||
* vinfo->hwfmt[0] has a used-bit corresponding to each of these.
|
|
||||||
* relation to TGSI_SEMANTIC_*:
|
|
||||||
* - POSITION: position (always used)
|
|
||||||
* - COLOR: col1, col0
|
|
||||||
* - GENERIC: tex3, tex2, tex1, tex0, normal, weight
|
|
||||||
* - FOG: fog
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = 0; i < fp->info.num_inputs; i++) {
|
|
||||||
int isn = fp->info.input_semantic_name[i];
|
|
||||||
int isi = fp->info.input_semantic_index[i];
|
|
||||||
switch (isn) {
|
|
||||||
case TGSI_SEMANTIC_POSITION:
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_COLOR:
|
|
||||||
assert(isi < 2);
|
|
||||||
colors[isi] = TRUE;
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_GENERIC:
|
|
||||||
assert(isi < 12);
|
|
||||||
generics[isi] = TRUE;
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_FOG:
|
|
||||||
fog = TRUE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0 && "unknown input_semantic_name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* always do position */ {
|
|
||||||
src = draw_find_shader_output(dc, TGSI_SEMANTIC_POSITION, 0);
|
|
||||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src);
|
|
||||||
vinfo->hwfmt[0] |= (1 << 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* two unnamed generics */
|
|
||||||
for (i = 4; i < 6; i++) {
|
|
||||||
if (!generics[i])
|
|
||||||
continue;
|
|
||||||
src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
|
|
||||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
|
||||||
vinfo->hwfmt[0] |= (1 << (i - 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colors[0]) {
|
|
||||||
src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 0);
|
|
||||||
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
|
|
||||||
vinfo->hwfmt[0] |= (1 << 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colors[1]) {
|
|
||||||
src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 1);
|
|
||||||
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
|
|
||||||
vinfo->hwfmt[0] |= (1 << 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* four unnamed generics */
|
|
||||||
for (i = 6; i < 10; i++) {
|
|
||||||
if (!generics[i])
|
|
||||||
continue;
|
|
||||||
src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
|
|
||||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
|
||||||
vinfo->hwfmt[0] |= (1 << (i - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tex0, tex1, tex2, tex3 */
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (!generics[i])
|
|
||||||
continue;
|
|
||||||
src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
|
|
||||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
|
||||||
vinfo->hwfmt[0] |= (1 << (i + 9));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* two unnamed generics */
|
|
||||||
for (i = 10; i < 12; i++) {
|
|
||||||
if (!generics[i])
|
|
||||||
continue;
|
|
||||||
src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
|
|
||||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
|
||||||
vinfo->hwfmt[0] |= (1 << (i + 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fog) {
|
|
||||||
src = draw_find_shader_output(dc, TGSI_SEMANTIC_FOG, 0);
|
|
||||||
draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
|
|
||||||
vinfo->hwfmt[0] |= (1 << 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_compute_vertex_size(vinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_emit_hw_state(struct nv20_context *nv20)
|
|
||||||
{
|
|
||||||
struct nv20_screen *screen = nv20->screen;
|
|
||||||
struct nouveau_channel *chan = screen->base.channel;
|
|
||||||
struct nouveau_grobj *kelvin = screen->kelvin;
|
|
||||||
struct nouveau_bo *rt_bo;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_VERTPROG) {
|
|
||||||
//nv20_vertprog_bind(nv20, nv20->vertprog.current);
|
|
||||||
nv20->dirty &= ~NV20_NEW_VERTPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_FRAGPROG) {
|
|
||||||
nv20_fragprog_bind(nv20, nv20->fragprog.current);
|
|
||||||
/*XXX: clear NV20_NEW_FRAGPROG if no new program uploaded */
|
|
||||||
nv20->dirty_samplers |= (1<<10);
|
|
||||||
nv20->dirty_samplers = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty_samplers || (nv20->dirty & NV20_NEW_FRAGPROG)) {
|
|
||||||
nv20_fragtex_bind(nv20);
|
|
||||||
nv20->dirty &= ~NV20_NEW_FRAGPROG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_VTXARRAYS) {
|
|
||||||
nv20->dirty &= ~NV20_NEW_VTXARRAYS;
|
|
||||||
nv20_vertex_layout(nv20);
|
|
||||||
nv20_vtxbuf_bind(nv20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_BLEND) {
|
|
||||||
nv20->dirty &= ~NV20_NEW_BLEND;
|
|
||||||
nv20_state_emit_blend(nv20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_BLENDCOL) {
|
|
||||||
nv20->dirty &= ~NV20_NEW_BLENDCOL;
|
|
||||||
nv20_state_emit_blend_color(nv20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_RAST) {
|
|
||||||
nv20->dirty &= ~NV20_NEW_RAST;
|
|
||||||
nv20_state_emit_rast(nv20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_DSA) {
|
|
||||||
nv20->dirty &= ~NV20_NEW_DSA;
|
|
||||||
nv20_state_emit_dsa(nv20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_VIEWPORT) {
|
|
||||||
nv20->dirty &= ~NV20_NEW_VIEWPORT;
|
|
||||||
nv20_state_emit_viewport(nv20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_SCISSOR) {
|
|
||||||
nv20->dirty &= ~NV20_NEW_SCISSOR;
|
|
||||||
nv20_state_emit_scissor(nv20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nv20->dirty & NV20_NEW_FRAMEBUFFER) {
|
|
||||||
nv20->dirty &= ~NV20_NEW_FRAMEBUFFER;
|
|
||||||
nv20_state_emit_framebuffer(nv20);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emit relocs for every referenced buffer.
|
|
||||||
* This is to ensure the bufmgr has an accurate idea of how
|
|
||||||
* the buffer is used. This isn't very efficient, but we don't
|
|
||||||
* seem to take a significant performance hit. Will be improved
|
|
||||||
* at some point. Vertex arrays are emitted by nv20_vbo.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Render target */
|
|
||||||
rt_bo = nouveau_bo(nv20->rt[0]);
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_DMA_COLOR, 1);
|
|
||||||
OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1);
|
|
||||||
OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
|
|
||||||
if (nv20->zeta) {
|
|
||||||
struct nouveau_bo *zeta_bo = nouveau_bo(nv20->zeta);
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_DMA_ZETA, 1);
|
|
||||||
OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_ZETA_OFFSET, 1);
|
|
||||||
OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
/* XXX for when we allocate LMA on nv17 */
|
|
||||||
/* BEGIN_RING(chan, kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
|
|
||||||
OUT_RELOCl(chan, nouveau_bo(nv20->zeta + lma_offset));*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Vertex buffer */
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_DMA_VTXBUF0, 1);
|
|
||||||
OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1);
|
|
||||||
OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
|
||||||
|
|
||||||
/* Texture images */
|
|
||||||
for (i = 0; i < 2; i++) {
|
|
||||||
if (!(nv20->fp_samplers & (1 << i)))
|
|
||||||
continue;
|
|
||||||
struct nouveau_bo *bo = nouveau_bo(nv20->tex[i].buffer);
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_TX_OFFSET(i), 1);
|
|
||||||
OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM |
|
|
||||||
NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
|
||||||
BEGIN_RING(chan, kelvin, NV20TCL_TX_FORMAT(i), 1);
|
|
||||||
OUT_RELOCd(chan, bo, nv20->tex[i].format,
|
|
||||||
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
|
|
||||||
NOUVEAU_BO_OR, NV20TCL_TX_FORMAT_DMA0,
|
|
||||||
NV20TCL_TX_FORMAT_DMA1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
||||||
* 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, sub license, 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 NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS 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 "nv20_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "util/u_simple_screen.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
#include "util/u_tile.h"
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_surface_copy(struct pipe_context *pipe,
|
|
||||||
struct pipe_surface *dest, unsigned destx, unsigned desty,
|
|
||||||
struct pipe_surface *src, unsigned srcx, unsigned srcy,
|
|
||||||
unsigned width, unsigned height)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
struct nv04_surface_2d *eng2d = nv20->screen->eng2d;
|
|
||||||
|
|
||||||
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
|
|
||||||
unsigned destx, unsigned desty, unsigned width,
|
|
||||||
unsigned height, unsigned value)
|
|
||||||
{
|
|
||||||
struct nv20_context *nv20 = nv20_context(pipe);
|
|
||||||
struct nv04_surface_2d *eng2d = nv20->screen->eng2d;
|
|
||||||
|
|
||||||
eng2d->fill(eng2d, dest, destx, desty, width, height, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_init_surface_functions(struct nv20_context *nv20)
|
|
||||||
{
|
|
||||||
nv20->pipe.surface_copy = nv20_surface_copy;
|
|
||||||
nv20->pipe.surface_fill = nv20_surface_fill;
|
|
||||||
}
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
||||||
#include <pipe/p_state.h>
|
|
||||||
#include <pipe/p_defines.h>
|
|
||||||
#include <util/u_inlines.h>
|
|
||||||
#include <util/u_format.h>
|
|
||||||
#include <util/u_memory.h>
|
|
||||||
#include <util/u_math.h>
|
|
||||||
#include <nouveau/nouveau_winsys.h>
|
|
||||||
#include "nv20_context.h"
|
|
||||||
#include "nv20_screen.h"
|
|
||||||
#include "nv20_state.h"
|
|
||||||
|
|
||||||
struct nv20_transfer {
|
|
||||||
struct pipe_transfer base;
|
|
||||||
struct pipe_surface *surface;
|
|
||||||
boolean direct;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
|
|
||||||
struct pipe_texture *template)
|
|
||||||
{
|
|
||||||
memset(template, 0, sizeof(struct pipe_texture));
|
|
||||||
template->target = pt->target;
|
|
||||||
template->format = pt->format;
|
|
||||||
template->width0 = width;
|
|
||||||
template->height0 = height;
|
|
||||||
template->depth0 = 1;
|
|
||||||
template->last_level = 0;
|
|
||||||
template->nr_samples = pt->nr_samples;
|
|
||||||
|
|
||||||
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
|
|
||||||
NOUVEAU_TEXTURE_USAGE_LINEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pipe_transfer *
|
|
||||||
nv20_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
|
|
||||||
unsigned face, unsigned level, unsigned zslice,
|
|
||||||
enum pipe_transfer_usage usage,
|
|
||||||
unsigned x, unsigned y, unsigned w, unsigned h)
|
|
||||||
{
|
|
||||||
struct nv20_miptree *mt = (struct nv20_miptree *)pt;
|
|
||||||
struct nv20_transfer *tx;
|
|
||||||
struct pipe_texture tx_tex_template, *tx_tex;
|
|
||||||
|
|
||||||
tx = CALLOC_STRUCT(nv20_transfer);
|
|
||||||
if (!tx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
pipe_texture_reference(&tx->base.texture, pt);
|
|
||||||
tx->base.x = x;
|
|
||||||
tx->base.y = y;
|
|
||||||
tx->base.width = w;
|
|
||||||
tx->base.height = h;
|
|
||||||
tx->base.stride = mt->level[level].pitch;
|
|
||||||
tx->base.usage = usage;
|
|
||||||
tx->base.face = face;
|
|
||||||
tx->base.level = level;
|
|
||||||
tx->base.zslice = zslice;
|
|
||||||
|
|
||||||
/* Direct access to texture */
|
|
||||||
if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
|
|
||||||
debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
|
|
||||||
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
|
|
||||||
{
|
|
||||||
tx->direct = true;
|
|
||||||
tx->surface = pscreen->get_tex_surface(pscreen, pt,
|
|
||||||
0, 0, 0,
|
|
||||||
pipe_transfer_buffer_flags(&tx->base));
|
|
||||||
return &tx->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx->direct = false;
|
|
||||||
|
|
||||||
nv20_compatible_transfer_tex(pt, w, h, &tx_tex_template);
|
|
||||||
|
|
||||||
tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
|
|
||||||
if (!tx_tex)
|
|
||||||
{
|
|
||||||
FREE(tx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx->base.stride = ((struct nv20_miptree*)tx_tex)->level[0].pitch;
|
|
||||||
|
|
||||||
tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
|
|
||||||
face, level, zslice,
|
|
||||||
pipe_transfer_buffer_flags(&tx->base));
|
|
||||||
|
|
||||||
pipe_texture_reference(&tx_tex, NULL);
|
|
||||||
|
|
||||||
if (!tx->surface)
|
|
||||||
{
|
|
||||||
pipe_surface_reference(&tx->surface, NULL);
|
|
||||||
FREE(tx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usage & PIPE_TRANSFER_READ) {
|
|
||||||
struct nv20_screen *nvscreen = nv20_screen(pscreen);
|
|
||||||
struct pipe_surface *src;
|
|
||||||
|
|
||||||
src = pscreen->get_tex_surface(pscreen, pt,
|
|
||||||
face, level, zslice,
|
|
||||||
PIPE_BUFFER_USAGE_GPU_READ);
|
|
||||||
|
|
||||||
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
|
|
||||||
/* TODO: Check if SIFM can un-swizzle */
|
|
||||||
nvscreen->eng2d->copy(nvscreen->eng2d,
|
|
||||||
tx->surface, 0, 0,
|
|
||||||
src, x, y,
|
|
||||||
w, h);
|
|
||||||
|
|
||||||
pipe_surface_reference(&src, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return &tx->base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_transfer_del(struct pipe_transfer *ptx)
|
|
||||||
{
|
|
||||||
struct nv20_transfer *tx = (struct nv20_transfer *)ptx;
|
|
||||||
|
|
||||||
if (!tx->direct && (ptx->usage = PIPE_TRANSFER_WRITE)) {
|
|
||||||
struct pipe_screen *pscreen = ptx->texture->screen;
|
|
||||||
struct nv20_screen *nvscreen = nv20_screen(pscreen);
|
|
||||||
struct pipe_surface *dst;
|
|
||||||
|
|
||||||
dst = pscreen->get_tex_surface(pscreen, ptx->texture,
|
|
||||||
ptx->face, ptx->level, ptx->zslice,
|
|
||||||
PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);
|
|
||||||
|
|
||||||
/* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
|
|
||||||
nvscreen->eng2d->copy(nvscreen->eng2d,
|
|
||||||
dst, tx->base.x, tx->base.y,
|
|
||||||
tx->surface, 0, 0,
|
|
||||||
tx->base.width, tx->base.height);
|
|
||||||
|
|
||||||
pipe_surface_reference(&dst, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_surface_reference(&tx->surface, NULL);
|
|
||||||
pipe_texture_reference(&ptx->texture, NULL);
|
|
||||||
FREE(ptx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
nv20_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
|
|
||||||
{
|
|
||||||
struct nv20_transfer *tx = (struct nv20_transfer *)ptx;
|
|
||||||
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
|
|
||||||
struct nv20_miptree *mt = (struct nv20_miptree *)tx->surface->texture;
|
|
||||||
void *map = pipe_buffer_map(pscreen, mt->buffer,
|
|
||||||
pipe_transfer_buffer_flags(ptx));
|
|
||||||
|
|
||||||
if(!tx->direct)
|
|
||||||
return map + ns->base.offset;
|
|
||||||
else
|
|
||||||
return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
|
|
||||||
{
|
|
||||||
struct nv20_transfer *tx = (struct nv20_transfer *)ptx;
|
|
||||||
struct nv20_miptree *mt = (struct nv20_miptree *)tx->surface->texture;
|
|
||||||
|
|
||||||
pipe_buffer_unmap(pscreen, mt->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_screen_init_transfer_functions(struct pipe_screen *pscreen)
|
|
||||||
{
|
|
||||||
pscreen->get_tex_transfer = nv20_transfer_new;
|
|
||||||
pscreen->tex_transfer_destroy = nv20_transfer_del;
|
|
||||||
pscreen->transfer_map = nv20_transfer_map;
|
|
||||||
pscreen->transfer_unmap = nv20_transfer_unmap;
|
|
||||||
}
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
#include "draw/draw_context.h"
|
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "nv20_context.h"
|
|
||||||
#include "nv20_state.h"
|
|
||||||
|
|
||||||
#include "nouveau/nouveau_channel.h"
|
|
||||||
#include "nouveau/nouveau_pushbuf.h"
|
|
||||||
|
|
||||||
void nv20_draw_elements( struct pipe_context *pipe,
|
|
||||||
struct pipe_buffer *indexBuffer,
|
|
||||||
unsigned indexSize,
|
|
||||||
unsigned prim, unsigned start, unsigned count)
|
|
||||||
{
|
|
||||||
struct pipe_screen *pscreen = pipe->screen;
|
|
||||||
struct nv20_context *nv20 = nv20_context( pipe );
|
|
||||||
struct draw_context *draw = nv20->draw;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
nv20_emit_hw_state(nv20);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map vertex buffers
|
|
||||||
*/
|
|
||||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
|
|
||||||
if (nv20->vtxbuf[i].buffer) {
|
|
||||||
void *buf
|
|
||||||
= pipe_buffer_map(pscreen,
|
|
||||||
nv20->vtxbuf[i].buffer,
|
|
||||||
PIPE_BUFFER_USAGE_CPU_READ);
|
|
||||||
draw_set_mapped_vertex_buffer(draw, i, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Map index buffer, if present */
|
|
||||||
if (indexBuffer) {
|
|
||||||
void *mapped_indexes
|
|
||||||
= pipe_buffer_map(pscreen, indexBuffer,
|
|
||||||
PIPE_BUFFER_USAGE_CPU_READ);
|
|
||||||
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* no index/element buffer */
|
|
||||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
|
|
||||||
nv20->constbuf[PIPE_SHADER_VERTEX],
|
|
||||||
nv20->constbuf_nr[PIPE_SHADER_VERTEX]);
|
|
||||||
|
|
||||||
/* draw! */
|
|
||||||
draw_arrays(nv20->draw, prim, start, count);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* unmap vertex/index buffers
|
|
||||||
*/
|
|
||||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
|
|
||||||
if (nv20->vtxbuf[i].buffer) {
|
|
||||||
pipe_buffer_unmap(pscreen, nv20->vtxbuf[i].buffer);
|
|
||||||
draw_set_mapped_vertex_buffer(draw, i, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (indexBuffer) {
|
|
||||||
pipe_buffer_unmap(pscreen, indexBuffer);
|
|
||||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_flush(nv20->draw);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nv20_draw_arrays( struct pipe_context *pipe,
|
|
||||||
unsigned prim, unsigned start, unsigned count)
|
|
||||||
{
|
|
||||||
nv20_draw_elements(pipe, NULL, 0, prim, start, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,841 +0,0 @@
|
||||||
#include "pipe/p_context.h"
|
|
||||||
#include "pipe/p_defines.h"
|
|
||||||
#include "pipe/p_state.h"
|
|
||||||
#include "util/u_inlines.h"
|
|
||||||
|
|
||||||
#include "pipe/p_shader_tokens.h"
|
|
||||||
#include "tgsi/tgsi_parse.h"
|
|
||||||
#include "tgsi/tgsi_dump.h"
|
|
||||||
|
|
||||||
#include "nv20_context.h"
|
|
||||||
#include "nv20_state.h"
|
|
||||||
|
|
||||||
/* TODO (at least...):
|
|
||||||
* 1. Indexed consts + ARL
|
|
||||||
* 2. Arb. swz/negation
|
|
||||||
* 3. NV_vp11, NV_vp2, NV_vp3 features
|
|
||||||
* - extra arith opcodes
|
|
||||||
* - branching
|
|
||||||
* - texture sampling
|
|
||||||
* - indexed attribs
|
|
||||||
* - indexed results
|
|
||||||
* 4. bugs
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SWZ_X 0
|
|
||||||
#define SWZ_Y 1
|
|
||||||
#define SWZ_Z 2
|
|
||||||
#define SWZ_W 3
|
|
||||||
#define MASK_X 8
|
|
||||||
#define MASK_Y 4
|
|
||||||
#define MASK_Z 2
|
|
||||||
#define MASK_W 1
|
|
||||||
#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W)
|
|
||||||
#define DEF_SCALE 0
|
|
||||||
#define DEF_CTEST 0
|
|
||||||
#include "nv20_shader.h"
|
|
||||||
|
|
||||||
#define swz(s,x,y,z,w) nv20_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w)
|
|
||||||
#define neg(s) nv20_sr_neg((s))
|
|
||||||
#define abs(s) nv20_sr_abs((s))
|
|
||||||
|
|
||||||
struct nv20_vpc {
|
|
||||||
struct nv20_vertex_program *vp;
|
|
||||||
|
|
||||||
struct nv20_vertex_program_exec *vpi;
|
|
||||||
|
|
||||||
unsigned output_map[PIPE_MAX_SHADER_OUTPUTS];
|
|
||||||
|
|
||||||
int high_temp;
|
|
||||||
int temp_temp_count;
|
|
||||||
|
|
||||||
struct nv20_sreg *imm;
|
|
||||||
unsigned nr_imm;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct nv20_sreg
|
|
||||||
temp(struct nv20_vpc *vpc)
|
|
||||||
{
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
idx = vpc->temp_temp_count++;
|
|
||||||
idx += vpc->high_temp + 1;
|
|
||||||
return nv20_sr(NV30SR_TEMP, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nv20_sreg
|
|
||||||
constant(struct nv20_vpc *vpc, int pipe, float x, float y, float z, float w)
|
|
||||||
{
|
|
||||||
struct nv20_vertex_program *vp = vpc->vp;
|
|
||||||
struct nv20_vertex_program_data *vpd;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
if (pipe >= 0) {
|
|
||||||
for (idx = 0; idx < vp->nr_consts; idx++) {
|
|
||||||
if (vp->consts[idx].index == pipe)
|
|
||||||
return nv20_sr(NV30SR_CONST, idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = vp->nr_consts++;
|
|
||||||
vp->consts = realloc(vp->consts, sizeof(*vpd) * vp->nr_consts);
|
|
||||||
vpd = &vp->consts[idx];
|
|
||||||
|
|
||||||
vpd->index = pipe;
|
|
||||||
vpd->value[0] = x;
|
|
||||||
vpd->value[1] = y;
|
|
||||||
vpd->value[2] = z;
|
|
||||||
vpd->value[3] = w;
|
|
||||||
return nv20_sr(NV30SR_CONST, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define arith(cc,s,o,d,m,s0,s1,s2) \
|
|
||||||
nv20_vp_arith((cc), (s), NV30_VP_INST_##o, (d), (m), (s0), (s1), (s2))
|
|
||||||
|
|
||||||
static void
|
|
||||||
emit_src(struct nv20_vpc *vpc, uint32_t *hw, int pos, struct nv20_sreg src)
|
|
||||||
{
|
|
||||||
struct nv20_vertex_program *vp = vpc->vp;
|
|
||||||
uint32_t sr = 0;
|
|
||||||
|
|
||||||
switch (src.type) {
|
|
||||||
case NV30SR_TEMP:
|
|
||||||
sr |= (NV30_VP_SRC_REG_TYPE_TEMP << NV30_VP_SRC_REG_TYPE_SHIFT);
|
|
||||||
sr |= (src.index << NV30_VP_SRC_TEMP_SRC_SHIFT);
|
|
||||||
break;
|
|
||||||
case NV30SR_INPUT:
|
|
||||||
sr |= (NV30_VP_SRC_REG_TYPE_INPUT <<
|
|
||||||
NV30_VP_SRC_REG_TYPE_SHIFT);
|
|
||||||
vp->ir |= (1 << src.index);
|
|
||||||
hw[1] |= (src.index << NV30_VP_INST_INPUT_SRC_SHIFT);
|
|
||||||
break;
|
|
||||||
case NV30SR_CONST:
|
|
||||||
sr |= (NV30_VP_SRC_REG_TYPE_CONST <<
|
|
||||||
NV30_VP_SRC_REG_TYPE_SHIFT);
|
|
||||||
assert(vpc->vpi->const_index == -1 ||
|
|
||||||
vpc->vpi->const_index == src.index);
|
|
||||||
vpc->vpi->const_index = src.index;
|
|
||||||
break;
|
|
||||||
case NV30SR_NONE:
|
|
||||||
sr |= (NV30_VP_SRC_REG_TYPE_INPUT <<
|
|
||||||
NV30_VP_SRC_REG_TYPE_SHIFT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (src.negate)
|
|
||||||
sr |= NV30_VP_SRC_NEGATE;
|
|
||||||
|
|
||||||
if (src.abs)
|
|
||||||
hw[0] |= (1 << (21 + pos));
|
|
||||||
|
|
||||||
sr |= ((src.swz[0] << NV30_VP_SRC_SWZ_X_SHIFT) |
|
|
||||||
(src.swz[1] << NV30_VP_SRC_SWZ_Y_SHIFT) |
|
|
||||||
(src.swz[2] << NV30_VP_SRC_SWZ_Z_SHIFT) |
|
|
||||||
(src.swz[3] << NV30_VP_SRC_SWZ_W_SHIFT));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* |VVV|
|
|
||||||
* d<EFBFBD>.<EFBFBD>b
|
|
||||||
* \u/
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (pos) {
|
|
||||||
case 0:
|
|
||||||
hw[1] |= ((sr & NV30_VP_SRC0_HIGH_MASK) >>
|
|
||||||
NV30_VP_SRC0_HIGH_SHIFT) << NV30_VP_INST_SRC0H_SHIFT;
|
|
||||||
hw[2] |= (sr & NV30_VP_SRC0_LOW_MASK) <<
|
|
||||||
NV30_VP_INST_SRC0L_SHIFT;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
hw[2] |= sr << NV30_VP_INST_SRC1_SHIFT;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
hw[2] |= ((sr & NV30_VP_SRC2_HIGH_MASK) >>
|
|
||||||
NV30_VP_SRC2_HIGH_SHIFT) << NV30_VP_INST_SRC2H_SHIFT;
|
|
||||||
hw[3] |= (sr & NV30_VP_SRC2_LOW_MASK) <<
|
|
||||||
NV30_VP_INST_SRC2L_SHIFT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
emit_dst(struct nv20_vpc *vpc, uint32_t *hw, int slot, struct nv20_sreg dst)
|
|
||||||
{
|
|
||||||
struct nv20_vertex_program *vp = vpc->vp;
|
|
||||||
|
|
||||||
switch (dst.type) {
|
|
||||||
case NV30SR_TEMP:
|
|
||||||
hw[0] |= (dst.index << NV30_VP_INST_DEST_TEMP_ID_SHIFT);
|
|
||||||
break;
|
|
||||||
case NV30SR_OUTPUT:
|
|
||||||
switch (dst.index) {
|
|
||||||
case NV30_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break;
|
|
||||||
case NV30_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break;
|
|
||||||
case NV30_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break;
|
|
||||||
case NV30_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break;
|
|
||||||
case NV30_VP_INST_DEST_FOGC : vp->or |= (1 << 4); break;
|
|
||||||
case NV30_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break;
|
|
||||||
case NV30_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break;
|
|
||||||
case NV30_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break;
|
|
||||||
case NV30_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break;
|
|
||||||
case NV30_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break;
|
|
||||||
case NV30_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break;
|
|
||||||
case NV30_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break;
|
|
||||||
case NV30_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break;
|
|
||||||
case NV30_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hw[3] |= (dst.index << NV30_VP_INST_DEST_SHIFT);
|
|
||||||
hw[0] |= NV30_VP_INST_VEC_DEST_TEMP_MASK | (1<<20);
|
|
||||||
|
|
||||||
/*XXX: no way this is entirely correct, someone needs to
|
|
||||||
* figure out what exactly it is.
|
|
||||||
*/
|
|
||||||
hw[3] |= 0x800;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_vp_arith(struct nv20_vpc *vpc, int slot, int op,
|
|
||||||
struct nv20_sreg dst, int mask,
|
|
||||||
struct nv20_sreg s0, struct nv20_sreg s1,
|
|
||||||
struct nv20_sreg s2)
|
|
||||||
{
|
|
||||||
struct nv20_vertex_program *vp = vpc->vp;
|
|
||||||
uint32_t *hw;
|
|
||||||
|
|
||||||
vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi));
|
|
||||||
vpc->vpi = &vp->insns[vp->nr_insns - 1];
|
|
||||||
memset(vpc->vpi, 0, sizeof(*vpc->vpi));
|
|
||||||
vpc->vpi->const_index = -1;
|
|
||||||
|
|
||||||
hw = vpc->vpi->data;
|
|
||||||
|
|
||||||
hw[0] |= (NV30_VP_INST_COND_TR << NV30_VP_INST_COND_SHIFT);
|
|
||||||
hw[0] |= ((0 << NV30_VP_INST_COND_SWZ_X_SHIFT) |
|
|
||||||
(1 << NV30_VP_INST_COND_SWZ_Y_SHIFT) |
|
|
||||||
(2 << NV30_VP_INST_COND_SWZ_Z_SHIFT) |
|
|
||||||
(3 << NV30_VP_INST_COND_SWZ_W_SHIFT));
|
|
||||||
|
|
||||||
hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT);
|
|
||||||
// hw[3] |= NV30_VP_INST_SCA_DEST_TEMP_MASK;
|
|
||||||
// hw[3] |= (mask << NV30_VP_INST_VEC_WRITEMASK_SHIFT);
|
|
||||||
|
|
||||||
if (dst.type == NV30SR_OUTPUT) {
|
|
||||||
if (slot)
|
|
||||||
hw[3] |= (mask << NV30_VP_INST_SDEST_WRITEMASK_SHIFT);
|
|
||||||
else
|
|
||||||
hw[3] |= (mask << NV30_VP_INST_VDEST_WRITEMASK_SHIFT);
|
|
||||||
} else {
|
|
||||||
if (slot)
|
|
||||||
hw[3] |= (mask << NV30_VP_INST_STEMP_WRITEMASK_SHIFT);
|
|
||||||
else
|
|
||||||
hw[3] |= (mask << NV30_VP_INST_VTEMP_WRITEMASK_SHIFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit_dst(vpc, hw, slot, dst);
|
|
||||||
emit_src(vpc, hw, 0, s0);
|
|
||||||
emit_src(vpc, hw, 1, s1);
|
|
||||||
emit_src(vpc, hw, 2, s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE struct nv20_sreg
|
|
||||||
tgsi_src(struct nv20_vpc *vpc, const struct tgsi_full_src_register *fsrc) {
|
|
||||||
struct nv20_sreg src;
|
|
||||||
|
|
||||||
switch (fsrc->Register.File) {
|
|
||||||
case TGSI_FILE_INPUT:
|
|
||||||
src = nv20_sr(NV30SR_INPUT, fsrc->Register.Index);
|
|
||||||
break;
|
|
||||||
case TGSI_FILE_CONSTANT:
|
|
||||||
src = constant(vpc, fsrc->Register.Index, 0, 0, 0, 0);
|
|
||||||
break;
|
|
||||||
case TGSI_FILE_IMMEDIATE:
|
|
||||||
src = vpc->imm[fsrc->Register.Index];
|
|
||||||
break;
|
|
||||||
case TGSI_FILE_TEMPORARY:
|
|
||||||
if (vpc->high_temp < fsrc->Register.Index)
|
|
||||||
vpc->high_temp = fsrc->Register.Index;
|
|
||||||
src = nv20_sr(NV30SR_TEMP, fsrc->Register.Index);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("bad src file\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
src.abs = fsrc->Register.Absolute;
|
|
||||||
src.negate = fsrc->Register.Negate;
|
|
||||||
src.swz[0] = fsrc->Register.SwizzleX;
|
|
||||||
src.swz[1] = fsrc->Register.SwizzleY;
|
|
||||||
src.swz[2] = fsrc->Register.SwizzleZ;
|
|
||||||
src.swz[3] = fsrc->Register.SwizzleW;
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE struct nv20_sreg
|
|
||||||
tgsi_dst(struct nv20_vpc *vpc, const struct tgsi_full_dst_register *fdst) {
|
|
||||||
struct nv20_sreg dst;
|
|
||||||
|
|
||||||
switch (fdst->Register.File) {
|
|
||||||
case TGSI_FILE_OUTPUT:
|
|
||||||
dst = nv20_sr(NV30SR_OUTPUT,
|
|
||||||
vpc->output_map[fdst->Register.Index]);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case TGSI_FILE_TEMPORARY:
|
|
||||||
dst = nv20_sr(NV30SR_TEMP, fdst->Register.Index);
|
|
||||||
if (vpc->high_temp < dst.index)
|
|
||||||
vpc->high_temp = dst.index;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("bad dst file\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE int
|
|
||||||
tgsi_mask(uint tgsi)
|
|
||||||
{
|
|
||||||
int mask = 0;
|
|
||||||
|
|
||||||
if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X;
|
|
||||||
if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y;
|
|
||||||
if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z;
|
|
||||||
if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W;
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv20_vertprog_parse_instruction(struct nv20_vpc *vpc,
|
|
||||||
const struct tgsi_full_instruction *finst)
|
|
||||||
{
|
|
||||||
struct nv20_sreg src[3], dst, tmp;
|
|
||||||
struct nv20_sreg none = nv20_sr(NV30SR_NONE, 0);
|
|
||||||
int mask;
|
|
||||||
int ai = -1, ci = -1;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (finst->Instruction.Opcode == TGSI_OPCODE_END)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
vpc->temp_temp_count = 0;
|
|
||||||
for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
|
|
||||||
const struct tgsi_full_src_register *fsrc;
|
|
||||||
|
|
||||||
fsrc = &finst->Src[i];
|
|
||||||
if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
|
|
||||||
src[i] = tgsi_src(vpc, fsrc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
|
|
||||||
const struct tgsi_full_src_register *fsrc;
|
|
||||||
|
|
||||||
fsrc = &finst->Src[i];
|
|
||||||
switch (fsrc->Register.File) {
|
|
||||||
case TGSI_FILE_INPUT:
|
|
||||||
if (ai == -1 || ai == fsrc->Register.Index) {
|
|
||||||
ai = fsrc->Register.Index;
|
|
||||||
src[i] = tgsi_src(vpc, fsrc);
|
|
||||||
} else {
|
|
||||||
src[i] = temp(vpc);
|
|
||||||
arith(vpc, 0, OP_MOV, src[i], MASK_ALL,
|
|
||||||
tgsi_src(vpc, fsrc), none, none);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/*XXX: index comparison is broken now that consts come from
|
|
||||||
* two different register files.
|
|
||||||
*/
|
|
||||||
case TGSI_FILE_CONSTANT:
|
|
||||||
case TGSI_FILE_IMMEDIATE:
|
|
||||||
if (ci == -1 || ci == fsrc->Register.Index) {
|
|
||||||
ci = fsrc->Register.Index;
|
|
||||||
src[i] = tgsi_src(vpc, fsrc);
|
|
||||||
} else {
|
|
||||||
src[i] = temp(vpc);
|
|
||||||
arith(vpc, 0, OP_MOV, src[i], MASK_ALL,
|
|
||||||
tgsi_src(vpc, fsrc), none, none);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TGSI_FILE_TEMPORARY:
|
|
||||||
/* handled above */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("bad src file\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dst = tgsi_dst(vpc, &finst->Dst[0]);
|
|
||||||
mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
|
|
||||||
|
|
||||||
switch (finst->Instruction.Opcode) {
|
|
||||||
case TGSI_OPCODE_ABS:
|
|
||||||
arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_ADD:
|
|
||||||
arith(vpc, 0, OP_ADD, dst, mask, src[0], none, src[1]);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_ARL:
|
|
||||||
arith(vpc, 0, OP_ARL, dst, mask, src[0], none, none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_DP3:
|
|
||||||
arith(vpc, 0, OP_DP3, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_DP4:
|
|
||||||
arith(vpc, 0, OP_DP4, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_DPH:
|
|
||||||
arith(vpc, 0, OP_DPH, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_DST:
|
|
||||||
arith(vpc, 0, OP_DST, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_EX2:
|
|
||||||
arith(vpc, 1, OP_EX2, dst, mask, none, none, src[0]);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_EXP:
|
|
||||||
arith(vpc, 1, OP_EXP, dst, mask, none, none, src[0]);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_FLR:
|
|
||||||
arith(vpc, 0, OP_FLR, dst, mask, src[0], none, none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_FRC:
|
|
||||||
arith(vpc, 0, OP_FRC, dst, mask, src[0], none, none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_LG2:
|
|
||||||
arith(vpc, 1, OP_LG2, dst, mask, none, none, src[0]);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_LIT:
|
|
||||||
arith(vpc, 1, OP_LIT, dst, mask, none, none, src[0]);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_LOG:
|
|
||||||
arith(vpc, 1, OP_LOG, dst, mask, none, none, src[0]);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_MAD:
|
|
||||||
arith(vpc, 0, OP_MAD, dst, mask, src[0], src[1], src[2]);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_MAX:
|
|
||||||
arith(vpc, 0, OP_MAX, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_MIN:
|
|
||||||
arith(vpc, 0, OP_MIN, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_MOV:
|
|
||||||
arith(vpc, 0, OP_MOV, dst, mask, src[0], none, none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_MUL:
|
|
||||||
arith(vpc, 0, OP_MUL, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_POW:
|
|
||||||
tmp = temp(vpc);
|
|
||||||
arith(vpc, 1, OP_LG2, tmp, MASK_X, none, none,
|
|
||||||
swz(src[0], X, X, X, X));
|
|
||||||
arith(vpc, 0, OP_MUL, tmp, MASK_X, swz(tmp, X, X, X, X),
|
|
||||||
swz(src[1], X, X, X, X), none);
|
|
||||||
arith(vpc, 1, OP_EX2, dst, mask, none, none,
|
|
||||||
swz(tmp, X, X, X, X));
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_RCP:
|
|
||||||
arith(vpc, 1, OP_RCP, dst, mask, none, none, src[0]);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_RET:
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_RSQ:
|
|
||||||
arith(vpc, 1, OP_RSQ, dst, mask, none, none, src[0]);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_SGE:
|
|
||||||
arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_SGT:
|
|
||||||
arith(vpc, 0, OP_SGT, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_SLT:
|
|
||||||
arith(vpc, 0, OP_SLT, dst, mask, src[0], src[1], none);
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_SUB:
|
|
||||||
arith(vpc, 0, OP_ADD, dst, mask, src[0], none, neg(src[1]));
|
|
||||||
break;
|
|
||||||
case TGSI_OPCODE_XPD:
|
|
||||||
tmp = temp(vpc);
|
|
||||||
arith(vpc, 0, OP_MUL, tmp, mask,
|
|
||||||
swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none);
|
|
||||||
arith(vpc, 0, OP_MAD, dst, (mask & ~MASK_W),
|
|
||||||
swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y),
|
|
||||||
neg(tmp));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv20_vertprog_parse_decl_output(struct nv20_vpc *vpc,
|
|
||||||
const struct tgsi_full_declaration *fdec)
|
|
||||||
{
|
|
||||||
int hw;
|
|
||||||
|
|
||||||
switch (fdec->Semantic.Name) {
|
|
||||||
case TGSI_SEMANTIC_POSITION:
|
|
||||||
hw = NV30_VP_INST_DEST_POS;
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_COLOR:
|
|
||||||
if (fdec->Semantic.Index == 0) {
|
|
||||||
hw = NV30_VP_INST_DEST_COL0;
|
|
||||||
} else
|
|
||||||
if (fdec->Semantic.Index == 1) {
|
|
||||||
hw = NV30_VP_INST_DEST_COL1;
|
|
||||||
} else {
|
|
||||||
NOUVEAU_ERR("bad colour semantic index\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_BCOLOR:
|
|
||||||
if (fdec->Semantic.Index == 0) {
|
|
||||||
hw = NV30_VP_INST_DEST_BFC0;
|
|
||||||
} else
|
|
||||||
if (fdec->Semantic.Index == 1) {
|
|
||||||
hw = NV30_VP_INST_DEST_BFC1;
|
|
||||||
} else {
|
|
||||||
NOUVEAU_ERR("bad bcolour semantic index\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_FOG:
|
|
||||||
hw = NV30_VP_INST_DEST_FOGC;
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_PSIZE:
|
|
||||||
hw = NV30_VP_INST_DEST_PSZ;
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_GENERIC:
|
|
||||||
if (fdec->Semantic.Index <= 7) {
|
|
||||||
hw = NV30_VP_INST_DEST_TC(fdec->Semantic.Index);
|
|
||||||
} else {
|
|
||||||
NOUVEAU_ERR("bad generic semantic index\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TGSI_SEMANTIC_EDGEFLAG:
|
|
||||||
NOUVEAU_ERR("cannot handle edgeflag output\n");
|
|
||||||
return FALSE;
|
|
||||||
default:
|
|
||||||
NOUVEAU_ERR("bad output semantic\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpc->output_map[fdec->Range.First] = hw;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv20_vertprog_prepare(struct nv20_vpc *vpc)
|
|
||||||
{
|
|
||||||
struct tgsi_parse_context p;
|
|
||||||
int nr_imm = 0;
|
|
||||||
|
|
||||||
tgsi_parse_init(&p, vpc->vp->pipe.tokens);
|
|
||||||
while (!tgsi_parse_end_of_tokens(&p)) {
|
|
||||||
const union tgsi_full_token *tok = &p.FullToken;
|
|
||||||
|
|
||||||
tgsi_parse_token(&p);
|
|
||||||
switch(tok->Token.Type) {
|
|
||||||
case TGSI_TOKEN_TYPE_IMMEDIATE:
|
|
||||||
nr_imm++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tgsi_parse_free(&p);
|
|
||||||
|
|
||||||
if (nr_imm) {
|
|
||||||
vpc->imm = CALLOC(nr_imm, sizeof(struct nv20_sreg));
|
|
||||||
assert(vpc->imm);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nv20_vertprog_translate(struct nv20_context *nv20,
|
|
||||||
struct nv20_vertex_program *vp)
|
|
||||||
{
|
|
||||||
struct tgsi_parse_context parse;
|
|
||||||
struct nv20_vpc *vpc = NULL;
|
|
||||||
|
|
||||||
tgsi_dump(vp->pipe.tokens,0);
|
|
||||||
|
|
||||||
vpc = CALLOC(1, sizeof(struct nv20_vpc));
|
|
||||||
if (!vpc)
|
|
||||||
return;
|
|
||||||
vpc->vp = vp;
|
|
||||||
vpc->high_temp = -1;
|
|
||||||
|
|
||||||
if (!nv20_vertprog_prepare(vpc)) {
|
|
||||||
FREE(vpc);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tgsi_parse_init(&parse, vp->pipe.tokens);
|
|
||||||
|
|
||||||
while (!tgsi_parse_end_of_tokens(&parse)) {
|
|
||||||
tgsi_parse_token(&parse);
|
|
||||||
|
|
||||||
switch (parse.FullToken.Token.Type) {
|
|
||||||
case TGSI_TOKEN_TYPE_DECLARATION:
|
|
||||||
{
|
|
||||||
const struct tgsi_full_declaration *fdec;
|
|
||||||
fdec = &parse.FullToken.FullDeclaration;
|
|
||||||
switch (fdec->Declaration.File) {
|
|
||||||
case TGSI_FILE_OUTPUT:
|
|
||||||
if (!nv20_vertprog_parse_decl_output(vpc, fdec))
|
|
||||||
goto out_err;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TGSI_TOKEN_TYPE_IMMEDIATE:
|
|
||||||
{
|
|
||||||
const struct tgsi_full_immediate *imm;
|
|
||||||
|
|
||||||
imm = &parse.FullToken.FullImmediate;
|
|
||||||
assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
|
|
||||||
assert(imm->Immediate.NrTokens == 4 + 1);
|
|
||||||
vpc->imm[vpc->nr_imm++] =
|
|
||||||
constant(vpc, -1,
|
|
||||||
imm->u[0].Float,
|
|
||||||
imm->u[1].Float,
|
|
||||||
imm->u[2].Float,
|
|
||||||
imm->u[3].Float);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TGSI_TOKEN_TYPE_INSTRUCTION:
|
|
||||||
{
|
|
||||||
const struct tgsi_full_instruction *finst;
|
|
||||||
finst = &parse.FullToken.FullInstruction;
|
|
||||||
if (!nv20_vertprog_parse_instruction(vpc, finst))
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vp->insns[vp->nr_insns - 1].data[3] |= NV30_VP_INST_LAST;
|
|
||||||
vp->translated = TRUE;
|
|
||||||
out_err:
|
|
||||||
tgsi_parse_free(&parse);
|
|
||||||
FREE(vpc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean
|
|
||||||
nv20_vertprog_validate(struct nv20_context *nv20)
|
|
||||||
{
|
|
||||||
struct pipe_screen *pscreen = nv20->pipe.screen;
|
|
||||||
struct nouveau_winsys *nvws = nv20->nvws;
|
|
||||||
struct nouveau_grobj *rankine = nv20->screen->rankine;
|
|
||||||
struct nv20_vertex_program *vp;
|
|
||||||
struct pipe_buffer *constbuf;
|
|
||||||
boolean upload_code = FALSE, upload_data = FALSE;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
vp = nv20->vertprog;
|
|
||||||
constbuf = nv20->constbuf[PIPE_SHADER_VERTEX];
|
|
||||||
|
|
||||||
/* Translate TGSI shader into hw bytecode */
|
|
||||||
if (!vp->translated) {
|
|
||||||
nv20_vertprog_translate(nv20, vp);
|
|
||||||
if (!vp->translated)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate hw vtxprog exec slots */
|
|
||||||
if (!vp->exec) {
|
|
||||||
struct nouveau_resource *heap = nv20->screen->vp_exec_heap;
|
|
||||||
struct nouveau_stateobj *so;
|
|
||||||
uint vplen = vp->nr_insns;
|
|
||||||
|
|
||||||
if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) {
|
|
||||||
while (heap->next && heap->size < vplen) {
|
|
||||||
struct nv20_vertex_program *evict;
|
|
||||||
|
|
||||||
evict = heap->next->priv;
|
|
||||||
nvws->res_free(&evict->exec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvws->res_alloc(heap, vplen, vp, &vp->exec))
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
so = so_new(2, 0);
|
|
||||||
so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1);
|
|
||||||
so_data (so, vp->exec->start);
|
|
||||||
so_ref(so, &vp->so);
|
|
||||||
|
|
||||||
upload_code = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate hw vtxprog const slots */
|
|
||||||
if (vp->nr_consts && !vp->data) {
|
|
||||||
struct nouveau_resource *heap = nv20->screen->vp_data_heap;
|
|
||||||
|
|
||||||
if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) {
|
|
||||||
while (heap->next && heap->size < vp->nr_consts) {
|
|
||||||
struct nv20_vertex_program *evict;
|
|
||||||
|
|
||||||
evict = heap->next->priv;
|
|
||||||
nvws->res_free(&evict->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data))
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*XXX: handle this some day */
|
|
||||||
assert(vp->data->start >= vp->data_start_min);
|
|
||||||
|
|
||||||
upload_data = TRUE;
|
|
||||||
if (vp->data_start != vp->data->start)
|
|
||||||
upload_code = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If exec or data segments moved we need to patch the program to
|
|
||||||
* fixup offsets and register IDs.
|
|
||||||
*/
|
|
||||||
if (vp->exec_start != vp->exec->start) {
|
|
||||||
for (i = 0; i < vp->nr_insns; i++) {
|
|
||||||
struct nv20_vertex_program_exec *vpi = &vp->insns[i];
|
|
||||||
|
|
||||||
if (vpi->has_branch_offset) {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vp->exec_start = vp->exec->start;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vp->nr_consts && vp->data_start != vp->data->start) {
|
|
||||||
for (i = 0; i < vp->nr_insns; i++) {
|
|
||||||
struct nv20_vertex_program_exec *vpi = &vp->insns[i];
|
|
||||||
|
|
||||||
if (vpi->const_index >= 0) {
|
|
||||||
vpi->data[1] &= ~NV30_VP_INST_CONST_SRC_MASK;
|
|
||||||
vpi->data[1] |=
|
|
||||||
(vpi->const_index + vp->data->start) <<
|
|
||||||
NV30_VP_INST_CONST_SRC_SHIFT;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vp->data_start = vp->data->start;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update + Upload constant values */
|
|
||||||
if (vp->nr_consts) {
|
|
||||||
float *map = NULL;
|
|
||||||
|
|
||||||
if (constbuf) {
|
|
||||||
map = pipe_buffer_map(pscreen, constbuf,
|
|
||||||
PIPE_BUFFER_USAGE_CPU_READ);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < vp->nr_consts; i++) {
|
|
||||||
struct nv20_vertex_program_data *vpd = &vp->consts[i];
|
|
||||||
|
|
||||||
if (vpd->index >= 0) {
|
|
||||||
if (!upload_data &&
|
|
||||||
!memcmp(vpd->value, &map[vpd->index * 4],
|
|
||||||
4 * sizeof(float)))
|
|
||||||
continue;
|
|
||||||
memcpy(vpd->value, &map[vpd->index * 4],
|
|
||||||
4 * sizeof(float));
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_CONST_ID, 5);
|
|
||||||
OUT_RING (i + vp->data->start);
|
|
||||||
OUT_RINGp ((uint32_t *)vpd->value, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (constbuf)
|
|
||||||
pipe_buffer_unmap(pscreen, constbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Upload vtxprog */
|
|
||||||
if (upload_code) {
|
|
||||||
#if 0
|
|
||||||
for (i = 0; i < vp->nr_insns; i++) {
|
|
||||||
NOUVEAU_MSG("VP inst %d: 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
|
||||||
i, vp->insns[i].data[0], vp->insns[i].data[1],
|
|
||||||
vp->insns[i].data[2], vp->insns[i].data[3]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_FROM_ID, 1);
|
|
||||||
OUT_RING (vp->exec->start);
|
|
||||||
for (i = 0; i < vp->nr_insns; i++) {
|
|
||||||
BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_INST(0), 4);
|
|
||||||
OUT_RINGp (vp->insns[i].data, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vp->so != nv20->state.hw[NV30_STATE_VERTPROG]) {
|
|
||||||
so_ref(vp->so, &nv20->state.hw[NV30_STATE_VERTPROG]);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nv20_vertprog_destroy(struct nv20_context *nv20, struct nv20_vertex_program *vp)
|
|
||||||
{
|
|
||||||
struct nouveau_winsys *nvws = nv20->screen->nvws;
|
|
||||||
|
|
||||||
vp->translated = FALSE;
|
|
||||||
|
|
||||||
if (vp->nr_insns) {
|
|
||||||
FREE(vp->insns);
|
|
||||||
vp->insns = NULL;
|
|
||||||
vp->nr_insns = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vp->nr_consts) {
|
|
||||||
FREE(vp->consts);
|
|
||||||
vp->consts = NULL;
|
|
||||||
vp->nr_consts = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nvws->res_free(&vp->exec);
|
|
||||||
vp->exec_start = 0;
|
|
||||||
nvws->res_free(&vp->data);
|
|
||||||
vp->data_start = 0;
|
|
||||||
vp->data_start_min = 0;
|
|
||||||
|
|
||||||
vp->ir = vp->or = 0;
|
|
||||||
so_ref(NULL, &vp->so);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nv20_state_entry nv20_state_vertprog = {
|
|
||||||
.validate = nv20_vertprog_validate,
|
|
||||||
.dirty = {
|
|
||||||
.pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/,
|
|
||||||
.hw = NV30_STATE_VERTPROG,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
|
|
||||||
#include "nv30_context.h"
|
#include "nv30_context.h"
|
||||||
#include "../nv04/nv04_surface_2d.h"
|
#include "../nouveau/nv04_surface_2d.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv30_miptree_layout(struct nv30_miptree *nv30mt)
|
nv30_miptree_layout(struct nv30_miptree *nv30mt)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "nouveau/nouveau_screen.h"
|
#include "nouveau/nouveau_screen.h"
|
||||||
|
|
||||||
#include "nv04/nv04_surface_2d.h"
|
#include "nouveau/nv04_surface_2d.h"
|
||||||
|
|
||||||
struct nv30_screen {
|
struct nv30_screen {
|
||||||
struct nouveau_screen base;
|
struct nouveau_screen base;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
|
|
||||||
#include "nv40_context.h"
|
#include "nv40_context.h"
|
||||||
#include "../nv04/nv04_surface_2d.h"
|
#include "../nouveau/nv04_surface_2d.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#define __NV40_SCREEN_H__
|
#define __NV40_SCREEN_H__
|
||||||
|
|
||||||
#include "nouveau/nouveau_screen.h"
|
#include "nouveau/nouveau_screen.h"
|
||||||
#include "nv04/nv04_surface_2d.h"
|
#include "nouveau/nv04_surface_2d.h"
|
||||||
|
|
||||||
struct nv40_screen {
|
struct nv40_screen {
|
||||||
struct nouveau_screen base;
|
struct nouveau_screen base;
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@ LIBNAME = nouveau_dri.so
|
||||||
PIPE_DRIVERS = \
|
PIPE_DRIVERS = \
|
||||||
$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
|
$(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
|
||||||
$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
|
$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
|
||||||
$(TOP)/src/gallium/drivers/nv04/libnv04.a \
|
|
||||||
$(TOP)/src/gallium/drivers/nv10/libnv10.a \
|
|
||||||
$(TOP)/src/gallium/drivers/nv20/libnv20.a \
|
|
||||||
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
|
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
|
||||||
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
|
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
|
||||||
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
|
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
|
||||||
|
|
|
||||||
|
|
@ -81,15 +81,6 @@ nouveau_drm_create_screen(struct drm_api *api, int fd,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
switch (dev->chipset & 0xf0) {
|
switch (dev->chipset & 0xf0) {
|
||||||
case 0x00:
|
|
||||||
init = nv04_screen_create;
|
|
||||||
break;
|
|
||||||
case 0x10:
|
|
||||||
init = nv10_screen_create;
|
|
||||||
break;
|
|
||||||
case 0x20:
|
|
||||||
init = nv20_screen_create;
|
|
||||||
break;
|
|
||||||
case 0x30:
|
case 0x30:
|
||||||
init = nv30_screen_create;
|
init = nv30_screen_create;
|
||||||
break;
|
break;
|
||||||
|
|
@ -160,15 +151,6 @@ nouveau_drm_create_context(struct drm_api *api, struct pipe_screen *pscreen)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch (chipset & 0xf0) {
|
switch (chipset & 0xf0) {
|
||||||
case 0x00:
|
|
||||||
init = nv04_create;
|
|
||||||
break;
|
|
||||||
case 0x10:
|
|
||||||
init = nv10_create;
|
|
||||||
break;
|
|
||||||
case 0x20:
|
|
||||||
init = nv20_create;
|
|
||||||
break;
|
|
||||||
case 0x30:
|
case 0x30:
|
||||||
init = nv30_create;
|
init = nv30_create;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,6 @@ EGL_DRIVER_LIBS = -ldrm_nouveau
|
||||||
|
|
||||||
EGL_DRIVER_PIPES = \
|
EGL_DRIVER_PIPES = \
|
||||||
$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
|
$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
|
||||||
$(TOP)/src/gallium/drivers/nv04/libnv04.a \
|
|
||||||
$(TOP)/src/gallium/drivers/nv10/libnv10.a \
|
|
||||||
$(TOP)/src/gallium/drivers/nv20/libnv20.a \
|
|
||||||
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
|
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
|
||||||
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
|
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
|
||||||
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
|
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,6 @@ INCLUDES = \
|
||||||
LIBS = \
|
LIBS = \
|
||||||
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
|
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
|
||||||
$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
|
$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
|
||||||
$(TOP)/src/gallium/drivers/nv04/libnv04.a \
|
|
||||||
$(TOP)/src/gallium/drivers/nv10/libnv10.a \
|
|
||||||
$(TOP)/src/gallium/drivers/nv20/libnv20.a \
|
|
||||||
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
|
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
|
||||||
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
|
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
|
||||||
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
|
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,11 @@ LDFLAGS += -L${DRMDIR}/lib \
|
||||||
-L${DRIDIR}/lib \
|
-L${DRIDIR}/lib \
|
||||||
-L${GALLIUMDIR}/winsys/drm/nouveau/common \
|
-L${GALLIUMDIR}/winsys/drm/nouveau/common \
|
||||||
-L${GALLIUMDIR}/auxiliary \
|
-L${GALLIUMDIR}/auxiliary \
|
||||||
-L${GALLIUMDIR}/drivers/nv04 \
|
|
||||||
-L${GALLIUMDIR}/drivers/nv10 \
|
|
||||||
-L${GALLIUMDIR}/drivers/nv20 \
|
|
||||||
-L${GALLIUMDIR}/drivers/nv30 \
|
-L${GALLIUMDIR}/drivers/nv30 \
|
||||||
-L${GALLIUMDIR}/drivers/nv40 \
|
-L${GALLIUMDIR}/drivers/nv40 \
|
||||||
-L${GALLIUMDIR}/drivers/nv50
|
-L${GALLIUMDIR}/drivers/nv50
|
||||||
|
|
||||||
LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv04 -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -lgallium -lm
|
LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv30 -lnv40 -lnv50 -lgallium -lm
|
||||||
|
|
||||||
#############################################
|
#############################################
|
||||||
|
|
||||||
|
|
|
||||||
59
src/mesa/drivers/dri/nouveau/Makefile
Normal file
59
src/mesa/drivers/dri/nouveau/Makefile
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
# src/mesa/drivers/dri/nouveau/Makefile
|
||||||
|
|
||||||
|
TOP = ../../../../..
|
||||||
|
include $(TOP)/configs/current
|
||||||
|
|
||||||
|
CFLAGS += $(shell pkg-config libdrm libdrm_nouveau --cflags)
|
||||||
|
DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
|
||||||
|
|
||||||
|
LIBNAME = nouveau_vieux_dri.so
|
||||||
|
|
||||||
|
MINIGLX_SOURCES =
|
||||||
|
|
||||||
|
DRIVER_SOURCES = \
|
||||||
|
nouveau_screen.c \
|
||||||
|
nouveau_context.c \
|
||||||
|
nouveau_fbo.c \
|
||||||
|
nouveau_driver.c \
|
||||||
|
nouveau_state.c \
|
||||||
|
nouveau_bufferobj.c \
|
||||||
|
nouveau_span.c \
|
||||||
|
nouveau_bo_state.c \
|
||||||
|
nouveau_texture.c \
|
||||||
|
nouveau_surface.c \
|
||||||
|
nv04_context.c \
|
||||||
|
nv04_screen.c \
|
||||||
|
nv04_render.c \
|
||||||
|
nv04_state_fb.c \
|
||||||
|
nv04_state_raster.c \
|
||||||
|
nv04_state_tex.c \
|
||||||
|
nv04_state_frag.c \
|
||||||
|
nv04_surface.c \
|
||||||
|
nv10_context.c \
|
||||||
|
nv10_screen.c \
|
||||||
|
nv10_render.c \
|
||||||
|
nv10_state_fb.c \
|
||||||
|
nv10_state_polygon.c \
|
||||||
|
nv10_state_raster.c \
|
||||||
|
nv10_state_tex.c \
|
||||||
|
nv10_state_frag.c \
|
||||||
|
nv10_state_tnl.c \
|
||||||
|
nv20_context.c \
|
||||||
|
nv20_screen.c \
|
||||||
|
nv20_render.c \
|
||||||
|
nv20_state_fb.c \
|
||||||
|
nv20_state_polygon.c \
|
||||||
|
nv20_state_raster.c \
|
||||||
|
nv20_state_tex.c \
|
||||||
|
nv20_state_tnl.c
|
||||||
|
|
||||||
|
C_SOURCES = \
|
||||||
|
$(COMMON_SOURCES) \
|
||||||
|
$(DRIVER_SOURCES)
|
||||||
|
|
||||||
|
ASM_SOURCES =
|
||||||
|
|
||||||
|
|
||||||
|
include ../Makefile.template
|
||||||
|
|
||||||
|
symlinks:
|
||||||
184
src/mesa/drivers/dri/nouveau/nouveau_bo_state.c
Normal file
184
src/mesa/drivers/dri/nouveau/nouveau_bo_state.c
Normal file
|
|
@ -0,0 +1,184 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
nouveau_bo_marker_emit(GLcontext *ctx, struct nouveau_bo_marker *m,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_pushbuf *push = chan->pushbuf;
|
||||||
|
uint32_t packet;
|
||||||
|
|
||||||
|
if (m->gr->bound == NOUVEAU_GROBJ_UNBOUND)
|
||||||
|
nouveau_grobj_autobind(m->gr);
|
||||||
|
|
||||||
|
if (MARK_RING(chan, 2, 2))
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
push->remaining -= 2;
|
||||||
|
packet = (m->gr->subc << 13) | (1 << 18) | m->mthd;
|
||||||
|
|
||||||
|
if (flags) {
|
||||||
|
if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo,
|
||||||
|
packet, 0, flags |
|
||||||
|
(m->flags & (NOUVEAU_BO_VRAM |
|
||||||
|
NOUVEAU_BO_GART |
|
||||||
|
NOUVEAU_BO_RDWR)),
|
||||||
|
0, 0))
|
||||||
|
goto fail;
|
||||||
|
} else {
|
||||||
|
*(push->cur++) = packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, m->data,
|
||||||
|
m->data2, flags | m->flags,
|
||||||
|
m->vor, m->tor))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
MARK_UNDO(chan);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
nouveau_bo_context_grow(struct nouveau_bo_context *bctx)
|
||||||
|
{
|
||||||
|
struct nouveau_bo_marker *marker = bctx->marker;
|
||||||
|
int allocated = bctx->allocated + 1;
|
||||||
|
|
||||||
|
marker = realloc(marker, allocated * sizeof(struct nouveau_bo_marker));
|
||||||
|
if (!marker)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
bctx->marker = marker;
|
||||||
|
bctx->allocated = allocated;
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_bo_mark(struct nouveau_bo_context *bctx, struct nouveau_grobj *gr,
|
||||||
|
uint32_t mthd, struct nouveau_bo *bo,
|
||||||
|
uint32_t data, uint32_t data2, uint32_t vor, uint32_t tor,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
struct nouveau_bo_state *s = &to_nouveau_context(bctx->ctx)->bo;
|
||||||
|
struct nouveau_bo_marker *m;
|
||||||
|
|
||||||
|
if (bctx->count == bctx->allocated) {
|
||||||
|
if (!nouveau_bo_context_grow(bctx))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
m = &bctx->marker[bctx->count];
|
||||||
|
|
||||||
|
*m = (struct nouveau_bo_marker) {
|
||||||
|
.gr = gr,
|
||||||
|
.mthd = mthd,
|
||||||
|
.data = data,
|
||||||
|
.data2 = data2,
|
||||||
|
.vor = vor,
|
||||||
|
.tor = tor,
|
||||||
|
.flags = flags,
|
||||||
|
};
|
||||||
|
nouveau_bo_ref(bo, &m->bo);
|
||||||
|
|
||||||
|
s->count++;
|
||||||
|
bctx->count++;
|
||||||
|
|
||||||
|
if (!nouveau_bo_marker_emit(bctx->ctx, m, 0))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
nouveau_bo_context_reset(bctx);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_bo_context_reset(struct nouveau_bo_context *bctx)
|
||||||
|
{
|
||||||
|
struct nouveau_bo_state *s = &to_nouveau_context(bctx->ctx)->bo;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < bctx->count; i++)
|
||||||
|
nouveau_bo_ref(NULL, &bctx->marker[i].bo);
|
||||||
|
|
||||||
|
s->count -= bctx->count;
|
||||||
|
bctx->count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_bo_state_emit(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) {
|
||||||
|
struct nouveau_bo_context *bctx = &s->context[i];
|
||||||
|
|
||||||
|
for (j = 0; j < bctx->count; j++) {
|
||||||
|
if (!nouveau_bo_marker_emit(ctx, &bctx->marker[j],
|
||||||
|
NOUVEAU_BO_DUMMY))
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_bo_state_init(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++)
|
||||||
|
s->context[i].ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_bo_state_destroy(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) {
|
||||||
|
struct nouveau_bo_context *bctx = &s->context[i];
|
||||||
|
|
||||||
|
for (j = 0; j < bctx->count; j++)
|
||||||
|
nouveau_bo_ref(NULL, &bctx->marker[j].bo);
|
||||||
|
|
||||||
|
if (bctx->marker)
|
||||||
|
free(bctx->marker);
|
||||||
|
}
|
||||||
|
}
|
||||||
107
src/mesa/drivers/dri/nouveau/nouveau_bo_state.h
Normal file
107
src/mesa/drivers/dri/nouveau/nouveau_bo_state.h
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_BO_STATE_H__
|
||||||
|
#define __NOUVEAU_BO_STATE_H__
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NOUVEAU_BO_CONTEXT_FRAMEBUFFER = 0,
|
||||||
|
NOUVEAU_BO_CONTEXT_LMA_DEPTH,
|
||||||
|
NOUVEAU_BO_CONTEXT_SURFACE,
|
||||||
|
NOUVEAU_BO_CONTEXT_TEXTURE0,
|
||||||
|
NOUVEAU_BO_CONTEXT_TEXTURE1,
|
||||||
|
NOUVEAU_BO_CONTEXT_TEXTURE2,
|
||||||
|
NOUVEAU_BO_CONTEXT_TEXTURE3,
|
||||||
|
NOUVEAU_BO_CONTEXT_VERTEX,
|
||||||
|
NUM_NOUVEAU_BO_CONTEXT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nouveau_bo_marker {
|
||||||
|
struct nouveau_grobj *gr;
|
||||||
|
uint32_t mthd;
|
||||||
|
|
||||||
|
struct nouveau_bo *bo;
|
||||||
|
uint32_t data;
|
||||||
|
uint32_t data2;
|
||||||
|
uint32_t vor;
|
||||||
|
uint32_t tor;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nouveau_bo_context {
|
||||||
|
GLcontext *ctx;
|
||||||
|
|
||||||
|
struct nouveau_bo_marker *marker;
|
||||||
|
int allocated;
|
||||||
|
int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nouveau_bo_state {
|
||||||
|
struct nouveau_bo_context context[NUM_NOUVEAU_BO_CONTEXT];
|
||||||
|
int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_bo_mark(struct nouveau_bo_context *bctx, struct nouveau_grobj *gr,
|
||||||
|
uint32_t mthd, struct nouveau_bo *bo,
|
||||||
|
uint32_t data, uint32_t data2, uint32_t vor, uint32_t tor,
|
||||||
|
uint32_t flags);
|
||||||
|
|
||||||
|
#define nouveau_bo_markl(bctx, gr, mthd, bo, data, flags) \
|
||||||
|
nouveau_bo_mark(bctx, gr, mthd, bo, data, 0, 0, 0, \
|
||||||
|
flags | NOUVEAU_BO_LOW);
|
||||||
|
|
||||||
|
#define nouveau_bo_marko(bctx, gr, mthd, bo, flags) \
|
||||||
|
nouveau_bo_mark(bctx, gr, mthd, bo, 0, 0, \
|
||||||
|
context_chan(ctx)->vram->handle, \
|
||||||
|
context_chan(ctx)->gart->handle, \
|
||||||
|
flags | NOUVEAU_BO_OR);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_bo_context_reset(struct nouveau_bo_context *bctx);
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_bo_state_emit(GLcontext *ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_bo_state_init(GLcontext *ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_bo_state_destroy(GLcontext *ctx);
|
||||||
|
|
||||||
|
#define __context_bctx(ctx, i) \
|
||||||
|
({ \
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx); \
|
||||||
|
struct nouveau_bo_context *bctx = &nctx->bo.context[i]; \
|
||||||
|
nouveau_bo_context_reset(bctx); \
|
||||||
|
bctx; \
|
||||||
|
})
|
||||||
|
#define context_bctx(ctx, s) \
|
||||||
|
__context_bctx(ctx, NOUVEAU_BO_CONTEXT_##s)
|
||||||
|
#define context_bctx_i(ctx, s, i) \
|
||||||
|
__context_bctx(ctx, NOUVEAU_BO_CONTEXT_##s##0 + (i))
|
||||||
|
|
||||||
|
#endif
|
||||||
172
src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
Normal file
172
src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
Normal file
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_bufferobj.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
|
||||||
|
#include "main/bufferobj.h"
|
||||||
|
|
||||||
|
static struct gl_buffer_object *
|
||||||
|
nouveau_bufferobj_new(GLcontext *ctx, GLuint buffer, GLenum target)
|
||||||
|
{
|
||||||
|
struct nouveau_bufferobj *nbo;
|
||||||
|
|
||||||
|
nbo = CALLOC_STRUCT(nouveau_bufferobj);
|
||||||
|
if (!nbo)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
_mesa_initialize_buffer_object(&nbo->base, buffer, target);
|
||||||
|
|
||||||
|
return &nbo->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_bufferobj_del(GLcontext *ctx, struct gl_buffer_object *obj)
|
||||||
|
{
|
||||||
|
struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
|
||||||
|
|
||||||
|
nouveau_bo_ref(NULL, &nbo->bo);
|
||||||
|
FREE(nbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
nouveau_bufferobj_data(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
|
||||||
|
const GLvoid *data, GLenum usage,
|
||||||
|
struct gl_buffer_object *obj)
|
||||||
|
{
|
||||||
|
struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
obj->Size = size;
|
||||||
|
obj->Usage = usage;
|
||||||
|
|
||||||
|
nouveau_bo_ref(NULL, &nbo->bo);
|
||||||
|
ret = nouveau_bo_new(context_dev(ctx),
|
||||||
|
NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
|
||||||
|
size, &nbo->bo);
|
||||||
|
assert(!ret);
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
nouveau_bo_map(nbo->bo, NOUVEAU_BO_WR);
|
||||||
|
_mesa_memcpy(nbo->bo->map, data, size);
|
||||||
|
nouveau_bo_unmap(nbo->bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_bufferobj_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset,
|
||||||
|
GLsizeiptrARB size, const GLvoid *data,
|
||||||
|
struct gl_buffer_object *obj)
|
||||||
|
{
|
||||||
|
struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
|
||||||
|
|
||||||
|
nouveau_bo_map(nbo->bo, NOUVEAU_BO_WR);
|
||||||
|
_mesa_memcpy(nbo->bo->map + offset, data, size);
|
||||||
|
nouveau_bo_unmap(nbo->bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_bufferobj_get_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset,
|
||||||
|
GLsizeiptrARB size, GLvoid *data,
|
||||||
|
struct gl_buffer_object *obj)
|
||||||
|
{
|
||||||
|
struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
|
||||||
|
|
||||||
|
nouveau_bo_map(nbo->bo, NOUVEAU_BO_RD);
|
||||||
|
_mesa_memcpy(data, nbo->bo->map + offset, size);
|
||||||
|
nouveau_bo_unmap(nbo->bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
nouveau_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,
|
||||||
|
struct gl_buffer_object *obj)
|
||||||
|
{
|
||||||
|
return ctx->Driver.MapBufferRange(ctx, target, 0, obj->Size, access,
|
||||||
|
obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
nouveau_bufferobj_map_range(GLcontext *ctx, GLenum target, GLintptr offset,
|
||||||
|
GLsizeiptr length, GLenum access,
|
||||||
|
struct gl_buffer_object *obj)
|
||||||
|
{
|
||||||
|
struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
|
||||||
|
uint32_t flags = 0;
|
||||||
|
|
||||||
|
assert(!obj->Pointer);
|
||||||
|
|
||||||
|
if (!nbo->bo)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (access == GL_READ_ONLY_ARB ||
|
||||||
|
access == GL_READ_WRITE_ARB)
|
||||||
|
flags |= NOUVEAU_BO_RD;
|
||||||
|
if (access == GL_WRITE_ONLY_ARB ||
|
||||||
|
access == GL_READ_WRITE_ARB)
|
||||||
|
flags |= NOUVEAU_BO_WR;
|
||||||
|
|
||||||
|
nouveau_bo_map_range(nbo->bo, offset, length, flags);
|
||||||
|
|
||||||
|
obj->Pointer = nbo->bo->map;
|
||||||
|
obj->Offset = offset;
|
||||||
|
obj->Length = length;
|
||||||
|
obj->AccessFlags = access;
|
||||||
|
|
||||||
|
return obj->Pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
nouveau_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj)
|
||||||
|
{
|
||||||
|
struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj);
|
||||||
|
|
||||||
|
assert(obj->Pointer);
|
||||||
|
|
||||||
|
nouveau_bo_unmap(nbo->bo);
|
||||||
|
|
||||||
|
obj->Pointer = NULL;
|
||||||
|
obj->Offset = 0;
|
||||||
|
obj->Length = 0;
|
||||||
|
obj->AccessFlags = 0;
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_bufferobj_functions_init(struct dd_function_table *functions)
|
||||||
|
{
|
||||||
|
functions->NewBufferObject = nouveau_bufferobj_new;
|
||||||
|
functions->DeleteBuffer = nouveau_bufferobj_del;
|
||||||
|
functions->BufferData = nouveau_bufferobj_data;
|
||||||
|
functions->BufferSubData = nouveau_bufferobj_subdata;
|
||||||
|
functions->GetBufferSubData = nouveau_bufferobj_get_subdata;
|
||||||
|
functions->MapBuffer = nouveau_bufferobj_map;
|
||||||
|
functions->MapBufferRange = nouveau_bufferobj_map_range;
|
||||||
|
functions->UnmapBuffer = nouveau_bufferobj_unmap;
|
||||||
|
}
|
||||||
39
src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
Normal file
39
src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_BUFFEROBJ_H__
|
||||||
|
#define __NOUVEAU_BUFFEROBJ_H__
|
||||||
|
|
||||||
|
struct nouveau_bufferobj {
|
||||||
|
struct gl_buffer_object base;
|
||||||
|
struct nouveau_bo *bo;
|
||||||
|
};
|
||||||
|
#define to_nouveau_bufferobj(x) ((struct nouveau_bufferobj *)(x))
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_bufferobj_functions_init(struct dd_function_table *functions);
|
||||||
|
|
||||||
|
#endif
|
||||||
273
src/mesa/drivers/dri/nouveau/nouveau_context.c
Normal file
273
src/mesa/drivers/dri/nouveau/nouveau_context.c
Normal file
|
|
@ -0,0 +1,273 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_bufferobj.h"
|
||||||
|
#include "nouveau_fbo.h"
|
||||||
|
|
||||||
|
#include "main/dd.h"
|
||||||
|
#include "main/framebuffer.h"
|
||||||
|
#include "main/light.h"
|
||||||
|
#include "main/state.h"
|
||||||
|
#include "drivers/common/meta.h"
|
||||||
|
#include "drivers/common/driverfuncs.h"
|
||||||
|
#include "swrast/swrast.h"
|
||||||
|
#include "vbo/vbo.h"
|
||||||
|
#include "tnl/tnl.h"
|
||||||
|
|
||||||
|
#define need_GL_EXT_framebuffer_object
|
||||||
|
#define need_GL_EXT_fog_coord
|
||||||
|
|
||||||
|
#include "main/remap_helper.h"
|
||||||
|
|
||||||
|
static const struct dri_extension nouveau_extensions[] = {
|
||||||
|
{ "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
|
||||||
|
{ "GL_ARB_multitexture", NULL },
|
||||||
|
{ "GL_EXT_texture_lod_bias", NULL },
|
||||||
|
{ "GL_SGIS_generate_mipmap", NULL },
|
||||||
|
{ "GL_ARB_texture_env_combine", NULL },
|
||||||
|
{ "GL_ARB_texture_env_dot3", NULL },
|
||||||
|
{ "GL_ARB_texture_env_add", NULL },
|
||||||
|
{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_context_create(const __GLcontextModes *visual, __DRIcontext *dri_ctx,
|
||||||
|
void *share_ctx)
|
||||||
|
{
|
||||||
|
__DRIscreen *dri_screen = dri_ctx->driScreenPriv;
|
||||||
|
struct nouveau_screen *screen = dri_screen->private;
|
||||||
|
struct nouveau_context *nctx;
|
||||||
|
GLcontext *ctx;
|
||||||
|
|
||||||
|
ctx = screen->driver->context_create(screen, visual, share_ctx);
|
||||||
|
if (!ctx)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
nctx = to_nouveau_context(ctx);
|
||||||
|
nctx->dri_context = dri_ctx;
|
||||||
|
dri_ctx->driverPrivate = ctx;
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_context_init(GLcontext *ctx, struct nouveau_screen *screen,
|
||||||
|
const GLvisual *visual, GLcontext *share_ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||||
|
struct dd_function_table functions;
|
||||||
|
|
||||||
|
nctx->screen = screen;
|
||||||
|
nctx->fallback = HWTNL;
|
||||||
|
|
||||||
|
/* Initialize the function pointers */
|
||||||
|
_mesa_init_driver_functions(&functions);
|
||||||
|
nouveau_driver_functions_init(&functions);
|
||||||
|
nouveau_bufferobj_functions_init(&functions);
|
||||||
|
nouveau_texture_functions_init(&functions);
|
||||||
|
nouveau_fbo_functions_init(&functions);
|
||||||
|
|
||||||
|
/* Initialize the mesa context */
|
||||||
|
_mesa_initialize_context(ctx, visual, share_ctx, &functions, NULL);
|
||||||
|
|
||||||
|
nouveau_state_init(ctx);
|
||||||
|
nouveau_bo_state_init(ctx);
|
||||||
|
_mesa_meta_init(ctx);
|
||||||
|
_swrast_CreateContext(ctx);
|
||||||
|
_vbo_CreateContext(ctx);
|
||||||
|
_tnl_CreateContext(ctx);
|
||||||
|
nouveau_span_functions_init(ctx);
|
||||||
|
_mesa_allow_light_in_model(ctx, GL_FALSE);
|
||||||
|
|
||||||
|
/* Enable any supported extensions */
|
||||||
|
driInitExtensions(ctx, nouveau_extensions, GL_TRUE);
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_context_destroy(__DRIcontext *dri_ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = dri_ctx->driverPrivate;
|
||||||
|
GLcontext *ctx = &nctx->base;
|
||||||
|
|
||||||
|
if (nctx->screen->context == nctx)
|
||||||
|
nctx->screen->context = NULL;
|
||||||
|
|
||||||
|
_tnl_DestroyContext(ctx);
|
||||||
|
_vbo_DestroyContext(ctx);
|
||||||
|
_swrast_DestroyContext(ctx);
|
||||||
|
_mesa_meta_free(ctx);
|
||||||
|
nouveau_bo_state_destroy(ctx);
|
||||||
|
context_drv(ctx)->context_destroy(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable,
|
||||||
|
unsigned int *stamp)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = context->driverPrivate;
|
||||||
|
GLcontext *ctx = &nctx->base;
|
||||||
|
__DRIscreen *screen = context->driScreenPriv;
|
||||||
|
struct gl_framebuffer *fb = drawable->driverPrivate;
|
||||||
|
unsigned int attachments[10];
|
||||||
|
__DRIbuffer *buffers = NULL;
|
||||||
|
int i = 0, count, ret;
|
||||||
|
|
||||||
|
attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
|
||||||
|
if (fb->Visual.doubleBufferMode)
|
||||||
|
attachments[i++] = __DRI_BUFFER_BACK_LEFT;
|
||||||
|
if (fb->Visual.haveDepthBuffer && fb->Visual.haveStencilBuffer)
|
||||||
|
attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
|
||||||
|
else if (fb->Visual.haveDepthBuffer)
|
||||||
|
attachments[i++] = __DRI_BUFFER_DEPTH;
|
||||||
|
else if (fb->Visual.haveStencilBuffer)
|
||||||
|
attachments[i++] = __DRI_BUFFER_STENCIL;
|
||||||
|
|
||||||
|
buffers = (*screen->dri2.loader->getBuffers)(drawable,
|
||||||
|
&drawable->w, &drawable->h,
|
||||||
|
attachments, i, &count,
|
||||||
|
drawable->loaderPrivate);
|
||||||
|
if (buffers == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
struct gl_renderbuffer *rb;
|
||||||
|
struct nouveau_surface *s;
|
||||||
|
uint32_t old_handle;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
switch (buffers[i].attachment) {
|
||||||
|
case __DRI_BUFFER_FRONT_LEFT:
|
||||||
|
case __DRI_BUFFER_FAKE_FRONT_LEFT:
|
||||||
|
index = BUFFER_FRONT_LEFT;
|
||||||
|
break;
|
||||||
|
case __DRI_BUFFER_BACK_LEFT:
|
||||||
|
index = BUFFER_BACK_LEFT;
|
||||||
|
break;
|
||||||
|
case __DRI_BUFFER_DEPTH:
|
||||||
|
case __DRI_BUFFER_DEPTH_STENCIL:
|
||||||
|
index = BUFFER_DEPTH;
|
||||||
|
break;
|
||||||
|
case __DRI_BUFFER_STENCIL:
|
||||||
|
index = BUFFER_STENCIL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
rb = fb->Attachment[index].Renderbuffer;
|
||||||
|
s = &to_nouveau_renderbuffer(rb)->surface;
|
||||||
|
|
||||||
|
s->width = drawable->w;
|
||||||
|
s->height = drawable->h;
|
||||||
|
s->pitch = buffers[i].pitch;
|
||||||
|
s->cpp = buffers[i].cpp;
|
||||||
|
|
||||||
|
/* Don't bother to reopen the bo if it happens to be
|
||||||
|
* the same. */
|
||||||
|
if (s->bo) {
|
||||||
|
ret = nouveau_bo_handle_get(s->bo, &old_handle);
|
||||||
|
assert(!ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s->bo || old_handle != buffers[i].name) {
|
||||||
|
nouveau_bo_ref(NULL, &s->bo);
|
||||||
|
ret = nouveau_bo_handle_ref(context_dev(ctx),
|
||||||
|
buffers[i].name, &s->bo);
|
||||||
|
assert(!ret);
|
||||||
|
|
||||||
|
context_dirty(ctx, FRAMEBUFFER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_mesa_resize_framebuffer(ctx, fb, drawable->w, drawable->h);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_context_make_current(__DRIcontext *dri_ctx, __DRIdrawable *dri_draw,
|
||||||
|
__DRIdrawable *dri_read)
|
||||||
|
{
|
||||||
|
if (dri_ctx) {
|
||||||
|
struct nouveau_context *nctx = dri_ctx->driverPrivate;
|
||||||
|
GLcontext *ctx = &nctx->base;
|
||||||
|
|
||||||
|
if (nctx->screen->context != nctx) {
|
||||||
|
nctx->screen->context = nctx;
|
||||||
|
BITSET_ONES(nctx->dirty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ask the X server for new renderbuffers. */
|
||||||
|
nouveau_update_renderbuffers(dri_ctx, dri_draw,
|
||||||
|
&nctx->drawable.d_stamp);
|
||||||
|
if (dri_draw != dri_read)
|
||||||
|
nouveau_update_renderbuffers(dri_ctx, dri_read,
|
||||||
|
&nctx->drawable.r_stamp);
|
||||||
|
|
||||||
|
/* Pass it down to mesa. */
|
||||||
|
_mesa_make_current(ctx, dri_draw->driverPrivate,
|
||||||
|
dri_read->driverPrivate);
|
||||||
|
_mesa_update_state(ctx);
|
||||||
|
|
||||||
|
FIRE_RING(context_chan(ctx));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_mesa_make_current(NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_context_unbind(__DRIcontext *dri_ctx)
|
||||||
|
{
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||||
|
|
||||||
|
nctx->fallback = MAX2(HWTNL, mode);
|
||||||
|
|
||||||
|
if (mode < SWRAST)
|
||||||
|
nouveau_state_emit(ctx);
|
||||||
|
else
|
||||||
|
FIRE_RING(context_chan(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_validate_framebuffer(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||||
|
|
||||||
|
/* Someone's planning to draw something really soon. */
|
||||||
|
nctx->drawable.dirty = GL_TRUE;
|
||||||
|
}
|
||||||
105
src/mesa/drivers/dri/nouveau/nouveau_context.h
Normal file
105
src/mesa/drivers/dri/nouveau/nouveau_context.h
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_CONTEXT_H__
|
||||||
|
#define __NOUVEAU_CONTEXT_H__
|
||||||
|
|
||||||
|
#include "nouveau_screen.h"
|
||||||
|
#include "nouveau_state.h"
|
||||||
|
#include "nouveau_bo_state.h"
|
||||||
|
#include "nouveau_render.h"
|
||||||
|
|
||||||
|
#include "main/bitset.h"
|
||||||
|
|
||||||
|
enum nouveau_fallback {
|
||||||
|
HWTNL = 0,
|
||||||
|
SWTNL,
|
||||||
|
SWRAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nouveau_drawable_state {
|
||||||
|
GLboolean dirty;
|
||||||
|
unsigned int d_stamp;
|
||||||
|
unsigned int r_stamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nouveau_context {
|
||||||
|
GLcontext base;
|
||||||
|
__DRIcontext *dri_context;
|
||||||
|
struct nouveau_screen *screen;
|
||||||
|
|
||||||
|
BITSET_DECLARE(dirty, MAX_NOUVEAU_STATE);
|
||||||
|
enum nouveau_fallback fallback;
|
||||||
|
|
||||||
|
struct nouveau_bo_state bo;
|
||||||
|
struct nouveau_render_state render;
|
||||||
|
struct nouveau_drawable_state drawable;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_nouveau_context(ctx) ((struct nouveau_context *)(ctx))
|
||||||
|
|
||||||
|
#define context_dev(ctx) \
|
||||||
|
(to_nouveau_context(ctx)->screen->device)
|
||||||
|
#define context_chipset(ctx) \
|
||||||
|
(context_dev(ctx)->chipset)
|
||||||
|
#define context_chan(ctx) \
|
||||||
|
(to_nouveau_context(ctx)->screen->chan)
|
||||||
|
#define context_eng3d(ctx) \
|
||||||
|
(to_nouveau_context(ctx)->screen->eng3d)
|
||||||
|
#define context_drv(ctx) \
|
||||||
|
(to_nouveau_context(ctx)->screen->driver)
|
||||||
|
#define context_dirty(ctx, s) \
|
||||||
|
BITSET_SET(to_nouveau_context(ctx)->dirty, NOUVEAU_STATE_##s)
|
||||||
|
#define context_dirty_i(ctx, s, i) \
|
||||||
|
BITSET_SET(to_nouveau_context(ctx)->dirty, NOUVEAU_STATE_##s##0 + i)
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_context_create(const __GLcontextModes *visual, __DRIcontext *dri_ctx,
|
||||||
|
void *share_ctx);
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_context_init(GLcontext *ctx, struct nouveau_screen *screen,
|
||||||
|
const GLvisual *visual, GLcontext *share_ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_context_destroy(__DRIcontext *dri_ctx);
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_context_make_current(__DRIcontext *dri_ctx,
|
||||||
|
__DRIdrawable *ddraw,
|
||||||
|
__DRIdrawable *rdraw);
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nouveau_context_unbind(__DRIcontext *dri_ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_validate_framebuffer(GLcontext *ctx);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
140
src/mesa/drivers/dri/nouveau/nouveau_driver.c
Normal file
140
src/mesa/drivers/dri/nouveau/nouveau_driver.c
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_fbo.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
|
||||||
|
#include "drivers/common/meta.h"
|
||||||
|
|
||||||
|
static const GLubyte *
|
||||||
|
nouveau_get_string(GLcontext *ctx, GLenum name)
|
||||||
|
{
|
||||||
|
static char buffer[128];
|
||||||
|
char hardware_name[32];
|
||||||
|
|
||||||
|
switch (name) {
|
||||||
|
case GL_VENDOR:
|
||||||
|
return (GLubyte *)"Nouveau";
|
||||||
|
|
||||||
|
case GL_RENDERER:
|
||||||
|
sprintf(hardware_name, "nv%02X", context_chipset(ctx));
|
||||||
|
driGetRendererString(buffer, hardware_name, DRIVER_DATE, 0);
|
||||||
|
|
||||||
|
return (GLubyte *)buffer;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_flush(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
|
||||||
|
FIRE_RING(chan);
|
||||||
|
|
||||||
|
if (ctx->DrawBuffer->Name == 0 &&
|
||||||
|
ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
|
||||||
|
__DRIscreen *screen = nctx->screen->dri_screen;
|
||||||
|
__DRIdri2LoaderExtension *dri2 = screen->dri2.loader;
|
||||||
|
__DRIdrawable *drawable = nctx->dri_context->driDrawablePriv;
|
||||||
|
|
||||||
|
dri2->flushFrontBuffer(drawable, drawable->loaderPrivate);
|
||||||
|
}
|
||||||
|
|
||||||
|
nctx->drawable.dirty = GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_finish(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
nouveau_flush(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_clear(GLcontext *ctx, GLbitfield buffers)
|
||||||
|
{
|
||||||
|
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||||
|
int x, y, w, h;
|
||||||
|
int i, buf;
|
||||||
|
|
||||||
|
nouveau_validate_framebuffer(ctx);
|
||||||
|
get_scissors(fb, &x, &y, &w, &h);
|
||||||
|
|
||||||
|
for (i = 0; i < BUFFER_COUNT; i++) {
|
||||||
|
struct nouveau_surface *s;
|
||||||
|
unsigned mask, value;
|
||||||
|
|
||||||
|
buf = buffers & (1 << i);
|
||||||
|
if (!buf)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
s = &to_nouveau_renderbuffer(
|
||||||
|
fb->Attachment[i].Renderbuffer->Wrapped)->surface;
|
||||||
|
|
||||||
|
if (buf & BUFFER_BITS_COLOR) {
|
||||||
|
mask = pack_rgba_i(s->format, ctx->Color.ColorMask[0]);
|
||||||
|
value = pack_rgba_f(s->format, ctx->Color.ClearColor);
|
||||||
|
|
||||||
|
if (mask)
|
||||||
|
context_drv(ctx)->surface_fill(
|
||||||
|
ctx, s, mask, value, x, y, w, h);
|
||||||
|
|
||||||
|
buffers &= ~buf;
|
||||||
|
|
||||||
|
} else if (buf & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
|
||||||
|
mask = pack_zs_i(s->format,
|
||||||
|
(buffers & BUFFER_BIT_DEPTH &&
|
||||||
|
ctx->Depth.Mask) ? ~0 : 0,
|
||||||
|
(buffers & BUFFER_BIT_STENCIL &&
|
||||||
|
ctx->Stencil.WriteMask[0]) ? ~0 : 0);
|
||||||
|
value = pack_zs_f(s->format,
|
||||||
|
ctx->Depth.Clear,
|
||||||
|
ctx->Stencil.Clear);
|
||||||
|
|
||||||
|
if (mask)
|
||||||
|
context_drv(ctx)->surface_fill(
|
||||||
|
ctx, s, mask, value, x, y, w, h);
|
||||||
|
|
||||||
|
buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffers)
|
||||||
|
_mesa_meta_Clear(ctx, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_driver_functions_init(struct dd_function_table *functions)
|
||||||
|
{
|
||||||
|
functions->GetString = nouveau_get_string;
|
||||||
|
functions->Flush = nouveau_flush;
|
||||||
|
functions->Finish = nouveau_finish;
|
||||||
|
functions->Clear = nouveau_clear;
|
||||||
|
}
|
||||||
89
src/mesa/drivers/dri/nouveau/nouveau_driver.h
Normal file
89
src/mesa/drivers/dri/nouveau/nouveau_driver.h
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_DRIVER_H__
|
||||||
|
#define __NOUVEAU_DRIVER_H__
|
||||||
|
|
||||||
|
#include "main/imports.h"
|
||||||
|
#include "main/mtypes.h"
|
||||||
|
#include "main/macros.h"
|
||||||
|
#include "main/formats.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "dri_util.h"
|
||||||
|
|
||||||
|
#undef NDEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "nouveau_device.h"
|
||||||
|
#include "nouveau_pushbuf.h"
|
||||||
|
#include "nouveau_grobj.h"
|
||||||
|
#include "nouveau_channel.h"
|
||||||
|
#include "nouveau_bo.h"
|
||||||
|
#include "nouveau_notifier.h"
|
||||||
|
#include "nouveau_screen.h"
|
||||||
|
#include "nouveau_state.h"
|
||||||
|
#include "nouveau_surface.h"
|
||||||
|
|
||||||
|
#define DRIVER_DATE "20091015"
|
||||||
|
#define DRIVER_AUTHOR "Nouveau"
|
||||||
|
|
||||||
|
struct nouveau_driver {
|
||||||
|
void (*screen_destroy)(struct nouveau_screen *screen);
|
||||||
|
|
||||||
|
GLcontext *(*context_create)(struct nouveau_screen *screen,
|
||||||
|
const GLvisual *visual,
|
||||||
|
GLcontext *share_ctx);
|
||||||
|
void (*context_destroy)(GLcontext *ctx);
|
||||||
|
|
||||||
|
void (*surface_copy)(GLcontext *ctx,
|
||||||
|
struct nouveau_surface *dst,
|
||||||
|
struct nouveau_surface *src,
|
||||||
|
int dx, int dy, int sx, int sy, int w, int h);
|
||||||
|
void (*surface_fill)(GLcontext *ctx,
|
||||||
|
struct nouveau_surface *dst,
|
||||||
|
unsigned mask, unsigned value,
|
||||||
|
int dx, int dy, int w, int h);
|
||||||
|
|
||||||
|
nouveau_state_func *emit;
|
||||||
|
int num_emit;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define nouveau_error(format, ...) \
|
||||||
|
_mesa_fprintf(stderr, "%s: " format, __func__, ## __VA_ARGS__)
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_clear(GLcontext *ctx, GLbitfield buffers);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_span_functions_init(GLcontext *ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_driver_functions_init(struct dd_function_table *functions);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_texture_functions_init(struct dd_function_table *functions);
|
||||||
|
|
||||||
|
#endif
|
||||||
277
src/mesa/drivers/dri/nouveau/nouveau_fbo.c
Normal file
277
src/mesa/drivers/dri/nouveau/nouveau_fbo.c
Normal file
|
|
@ -0,0 +1,277 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_fbo.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_texture.h"
|
||||||
|
|
||||||
|
#include "main/framebuffer.h"
|
||||||
|
#include "main/renderbuffer.h"
|
||||||
|
#include "main/fbobject.h"
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
set_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat)
|
||||||
|
{
|
||||||
|
struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
|
||||||
|
|
||||||
|
rb->InternalFormat = internalFormat;
|
||||||
|
|
||||||
|
switch (internalFormat) {
|
||||||
|
case GL_RGB:
|
||||||
|
case GL_RGB8:
|
||||||
|
rb->_BaseFormat = GL_RGB;
|
||||||
|
rb->Format = MESA_FORMAT_XRGB8888;
|
||||||
|
rb->DataType = GL_UNSIGNED_BYTE;
|
||||||
|
s->cpp = 4;
|
||||||
|
break;
|
||||||
|
case GL_RGBA:
|
||||||
|
case GL_RGBA8:
|
||||||
|
rb->_BaseFormat = GL_RGBA;
|
||||||
|
rb->Format = MESA_FORMAT_ARGB8888;
|
||||||
|
rb->DataType = GL_UNSIGNED_BYTE;
|
||||||
|
s->cpp = 4;
|
||||||
|
break;
|
||||||
|
case GL_RGB5:
|
||||||
|
rb->_BaseFormat = GL_RGB;
|
||||||
|
rb->Format = MESA_FORMAT_RGB565;
|
||||||
|
rb->DataType = GL_UNSIGNED_BYTE;
|
||||||
|
s->cpp = 2;
|
||||||
|
break;
|
||||||
|
case GL_DEPTH_COMPONENT16:
|
||||||
|
rb->_BaseFormat = GL_DEPTH_COMPONENT;
|
||||||
|
rb->Format = MESA_FORMAT_Z16;
|
||||||
|
rb->DataType = GL_UNSIGNED_SHORT;
|
||||||
|
s->cpp = 2;
|
||||||
|
break;
|
||||||
|
case GL_DEPTH_COMPONENT24:
|
||||||
|
case GL_STENCIL_INDEX8_EXT:
|
||||||
|
case GL_DEPTH24_STENCIL8_EXT:
|
||||||
|
rb->_BaseFormat = GL_DEPTH_COMPONENT;
|
||||||
|
rb->Format = MESA_FORMAT_Z24_S8;
|
||||||
|
rb->DataType = GL_UNSIGNED_INT;
|
||||||
|
s->cpp = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->format = rb->Format;
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||||
|
GLenum internalFormat,
|
||||||
|
GLuint width, GLuint height)
|
||||||
|
{
|
||||||
|
struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
|
||||||
|
|
||||||
|
if (!set_renderbuffer_format(rb, internalFormat))
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
rb->Width = width;
|
||||||
|
rb->Height = height;
|
||||||
|
|
||||||
|
nouveau_surface_alloc(ctx, s, TILED, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP,
|
||||||
|
rb->Format, width, height);
|
||||||
|
|
||||||
|
context_dirty(ctx, FRAMEBUFFER);
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_renderbuffer_del(struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
|
||||||
|
|
||||||
|
nouveau_surface_ref(NULL, s);
|
||||||
|
FREE(rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct gl_renderbuffer *
|
||||||
|
nouveau_renderbuffer_new(GLcontext *ctx, GLuint name)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *rb;
|
||||||
|
|
||||||
|
rb = (struct gl_renderbuffer *)
|
||||||
|
CALLOC_STRUCT(nouveau_renderbuffer);
|
||||||
|
if (!rb)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
_mesa_init_renderbuffer(rb, name);
|
||||||
|
|
||||||
|
rb->AllocStorage = nouveau_renderbuffer_storage;
|
||||||
|
rb->Delete = nouveau_renderbuffer_del;
|
||||||
|
|
||||||
|
return rb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
nouveau_renderbuffer_dri_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
|
||||||
|
GLenum internalFormat,
|
||||||
|
GLuint width, GLuint height)
|
||||||
|
{
|
||||||
|
if (!set_renderbuffer_format(rb, internalFormat))
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
rb->Width = width;
|
||||||
|
rb->Height = height;
|
||||||
|
|
||||||
|
context_dirty(ctx, FRAMEBUFFER);
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gl_renderbuffer *
|
||||||
|
nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *rb;
|
||||||
|
|
||||||
|
rb = nouveau_renderbuffer_new(NULL, 0);
|
||||||
|
if (!rb)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rb->AllocStorage = nouveau_renderbuffer_dri_storage;
|
||||||
|
|
||||||
|
if (!set_renderbuffer_format(rb, format)) {
|
||||||
|
nouveau_renderbuffer_del(rb);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct gl_framebuffer *
|
||||||
|
nouveau_framebuffer_new(GLcontext *ctx, GLuint name)
|
||||||
|
{
|
||||||
|
struct nouveau_framebuffer *nfb;
|
||||||
|
|
||||||
|
nfb = CALLOC_STRUCT(nouveau_framebuffer);
|
||||||
|
if (!nfb)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
_mesa_initialize_user_framebuffer(&nfb->base, name);
|
||||||
|
|
||||||
|
return &nfb->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gl_framebuffer *
|
||||||
|
nouveau_framebuffer_dri_new(const GLvisual *visual)
|
||||||
|
{
|
||||||
|
struct nouveau_framebuffer *nfb;
|
||||||
|
|
||||||
|
nfb = CALLOC_STRUCT(nouveau_framebuffer);
|
||||||
|
if (!nfb)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
_mesa_initialize_window_framebuffer(&nfb->base, visual);
|
||||||
|
|
||||||
|
return &nfb->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_bind_framebuffer(GLcontext *ctx, GLenum target,
|
||||||
|
struct gl_framebuffer *dfb,
|
||||||
|
struct gl_framebuffer *rfb)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, FRAMEBUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||||
|
GLenum attachment, struct gl_renderbuffer *rb)
|
||||||
|
{
|
||||||
|
_mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
|
||||||
|
|
||||||
|
context_dirty(ctx, FRAMEBUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLenum
|
||||||
|
get_tex_format(struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
switch (ti->TexFormat) {
|
||||||
|
case MESA_FORMAT_ARGB8888:
|
||||||
|
return GL_RGBA8;
|
||||||
|
case MESA_FORMAT_RGB565:
|
||||||
|
return GL_RGB5;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb,
|
||||||
|
struct gl_renderbuffer_attachment *att)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *rb = att->Renderbuffer;
|
||||||
|
struct gl_texture_image *ti =
|
||||||
|
att->Texture->Image[att->CubeMapFace][att->TextureLevel];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Allocate a renderbuffer object for the texture if we
|
||||||
|
* haven't already done so. */
|
||||||
|
if (!rb) {
|
||||||
|
rb = nouveau_renderbuffer_new(ctx, 0);
|
||||||
|
assert(rb);
|
||||||
|
|
||||||
|
rb->AllocStorage = NULL;
|
||||||
|
_mesa_reference_renderbuffer(&att->Renderbuffer, rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the renderbuffer fields from the texture. */
|
||||||
|
ret = set_renderbuffer_format(rb, get_tex_format(ti));
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
rb->Width = ti->Width;
|
||||||
|
rb->Height = ti->Height;
|
||||||
|
nouveau_surface_ref(&to_nouveau_teximage(ti)->surface,
|
||||||
|
&to_nouveau_renderbuffer(rb)->surface);
|
||||||
|
|
||||||
|
context_dirty(ctx, FRAMEBUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_finish_render_texture(GLcontext *ctx,
|
||||||
|
struct gl_renderbuffer_attachment *att)
|
||||||
|
{
|
||||||
|
struct nouveau_renderbuffer *nrb
|
||||||
|
= to_nouveau_renderbuffer(att->Renderbuffer);
|
||||||
|
|
||||||
|
texture_dirty(att->Texture);
|
||||||
|
nouveau_surface_ref(NULL, &nrb->surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_fbo_functions_init(struct dd_function_table *functions)
|
||||||
|
{
|
||||||
|
functions->NewFramebuffer = nouveau_framebuffer_new;
|
||||||
|
functions->NewRenderbuffer = nouveau_renderbuffer_new;
|
||||||
|
functions->BindFramebuffer = nouveau_bind_framebuffer;
|
||||||
|
functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer;
|
||||||
|
functions->RenderTexture = nouveau_render_texture;
|
||||||
|
functions->FinishRenderTexture = nouveau_finish_render_texture;
|
||||||
|
}
|
||||||
51
src/mesa/drivers/dri/nouveau/nouveau_fbo.h
Normal file
51
src/mesa/drivers/dri/nouveau/nouveau_fbo.h
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_FBO_H__
|
||||||
|
#define __NOUVEAU_FBO_H__
|
||||||
|
|
||||||
|
struct nouveau_framebuffer {
|
||||||
|
struct gl_framebuffer base;
|
||||||
|
struct nouveau_bo *lma_bo;
|
||||||
|
};
|
||||||
|
#define to_nouveau_framebuffer(x) ((struct nouveau_framebuffer *)(x))
|
||||||
|
|
||||||
|
struct nouveau_renderbuffer {
|
||||||
|
struct gl_renderbuffer base;
|
||||||
|
struct nouveau_surface surface;
|
||||||
|
};
|
||||||
|
#define to_nouveau_renderbuffer(x) ((struct nouveau_renderbuffer *)(x))
|
||||||
|
|
||||||
|
struct gl_framebuffer *
|
||||||
|
nouveau_framebuffer_dri_new(const GLvisual *visual);
|
||||||
|
|
||||||
|
struct gl_renderbuffer *
|
||||||
|
nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_fbo_functions_init(struct dd_function_table *functions);
|
||||||
|
|
||||||
|
#endif
|
||||||
263
src/mesa/drivers/dri/nouveau/nouveau_gldefs.h
Normal file
263
src/mesa/drivers/dri/nouveau/nouveau_gldefs.h
Normal file
|
|
@ -0,0 +1,263 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2010 The Nouveau Project.
|
||||||
|
* 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_GLDEFS_H__
|
||||||
|
#define __NOUVEAU_GLDEFS_H__
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
nvgl_blend_func(unsigned func)
|
||||||
|
{
|
||||||
|
switch (func) {
|
||||||
|
case GL_ZERO:
|
||||||
|
return 0x0000;
|
||||||
|
case GL_ONE:
|
||||||
|
return 0x0001;
|
||||||
|
case GL_SRC_COLOR:
|
||||||
|
return 0x0300;
|
||||||
|
case GL_ONE_MINUS_SRC_COLOR:
|
||||||
|
return 0x0301;
|
||||||
|
case GL_SRC_ALPHA:
|
||||||
|
return 0x0302;
|
||||||
|
case GL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
return 0x0303;
|
||||||
|
case GL_DST_ALPHA:
|
||||||
|
return 0x0304;
|
||||||
|
case GL_ONE_MINUS_DST_ALPHA:
|
||||||
|
return 0x0305;
|
||||||
|
case GL_DST_COLOR:
|
||||||
|
return 0x0306;
|
||||||
|
case GL_ONE_MINUS_DST_COLOR:
|
||||||
|
return 0x0307;
|
||||||
|
case GL_SRC_ALPHA_SATURATE:
|
||||||
|
return 0x0308;
|
||||||
|
case GL_CONSTANT_COLOR:
|
||||||
|
return 0x8001;
|
||||||
|
case GL_ONE_MINUS_CONSTANT_COLOR:
|
||||||
|
return 0x8002;
|
||||||
|
case GL_CONSTANT_ALPHA:
|
||||||
|
return 0x8003;
|
||||||
|
case GL_ONE_MINUS_CONSTANT_ALPHA:
|
||||||
|
return 0x8004;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
nvgl_blend_eqn(unsigned eqn)
|
||||||
|
{
|
||||||
|
switch (eqn) {
|
||||||
|
case GL_FUNC_ADD:
|
||||||
|
return 0x8006;
|
||||||
|
case GL_MIN:
|
||||||
|
return 0x8007;
|
||||||
|
case GL_MAX:
|
||||||
|
return 0x8008;
|
||||||
|
case GL_FUNC_SUBTRACT:
|
||||||
|
return 0x800a;
|
||||||
|
case GL_FUNC_REVERSE_SUBTRACT:
|
||||||
|
return 0x800b;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
nvgl_logicop_func(unsigned func)
|
||||||
|
{
|
||||||
|
switch (func) {
|
||||||
|
case GL_CLEAR:
|
||||||
|
return 0x1500;
|
||||||
|
case GL_NOR:
|
||||||
|
return 0x1508;
|
||||||
|
case GL_AND_INVERTED:
|
||||||
|
return 0x1504;
|
||||||
|
case GL_COPY_INVERTED:
|
||||||
|
return 0x150c;
|
||||||
|
case GL_AND_REVERSE:
|
||||||
|
return 0x1502;
|
||||||
|
case GL_INVERT:
|
||||||
|
return 0x150a;
|
||||||
|
case GL_XOR:
|
||||||
|
return 0x1506;
|
||||||
|
case GL_NAND:
|
||||||
|
return 0x150e;
|
||||||
|
case GL_AND:
|
||||||
|
return 0x1501;
|
||||||
|
case GL_EQUIV:
|
||||||
|
return 0x1509;
|
||||||
|
case GL_NOOP:
|
||||||
|
return 0x1505;
|
||||||
|
case GL_OR_INVERTED:
|
||||||
|
return 0x150d;
|
||||||
|
case GL_COPY:
|
||||||
|
return 0x1503;
|
||||||
|
case GL_OR_REVERSE:
|
||||||
|
return 0x150b;
|
||||||
|
case GL_OR:
|
||||||
|
return 0x1507;
|
||||||
|
case GL_SET:
|
||||||
|
return 0x150f;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
nvgl_comparison_op(unsigned op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case GL_NEVER:
|
||||||
|
return 0x0200;
|
||||||
|
case GL_LESS:
|
||||||
|
return 0x0201;
|
||||||
|
case GL_EQUAL:
|
||||||
|
return 0x0202;
|
||||||
|
case GL_LEQUAL:
|
||||||
|
return 0x0203;
|
||||||
|
case GL_GREATER:
|
||||||
|
return 0x0204;
|
||||||
|
case GL_NOTEQUAL:
|
||||||
|
return 0x0205;
|
||||||
|
case GL_GEQUAL:
|
||||||
|
return 0x0206;
|
||||||
|
case GL_ALWAYS:
|
||||||
|
return 0x0207;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
nvgl_polygon_mode(unsigned mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case GL_POINT:
|
||||||
|
return 0x1b00;
|
||||||
|
case GL_LINE:
|
||||||
|
return 0x1b01;
|
||||||
|
case GL_FILL:
|
||||||
|
return 0x1b02;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
nvgl_stencil_op(unsigned op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case GL_ZERO:
|
||||||
|
return 0x0000;
|
||||||
|
case GL_INVERT:
|
||||||
|
return 0x150a;
|
||||||
|
case GL_KEEP:
|
||||||
|
return 0x1e00;
|
||||||
|
case GL_REPLACE:
|
||||||
|
return 0x1e01;
|
||||||
|
case GL_INCR:
|
||||||
|
return 0x1e02;
|
||||||
|
case GL_DECR:
|
||||||
|
return 0x1e03;
|
||||||
|
case GL_INCR_WRAP_EXT:
|
||||||
|
return 0x8507;
|
||||||
|
case GL_DECR_WRAP_EXT:
|
||||||
|
return 0x8508;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
nvgl_primitive(unsigned prim)
|
||||||
|
{
|
||||||
|
switch (prim) {
|
||||||
|
case GL_POINTS:
|
||||||
|
return 0x0001;
|
||||||
|
case GL_LINES:
|
||||||
|
return 0x0002;
|
||||||
|
case GL_LINE_LOOP:
|
||||||
|
return 0x0003;
|
||||||
|
case GL_LINE_STRIP:
|
||||||
|
return 0x0004;
|
||||||
|
case GL_TRIANGLES:
|
||||||
|
return 0x0005;
|
||||||
|
case GL_TRIANGLE_STRIP:
|
||||||
|
return 0x0006;
|
||||||
|
case GL_TRIANGLE_FAN:
|
||||||
|
return 0x0007;
|
||||||
|
case GL_QUADS:
|
||||||
|
return 0x0008;
|
||||||
|
case GL_QUAD_STRIP:
|
||||||
|
return 0x0009;
|
||||||
|
case GL_POLYGON:
|
||||||
|
return 0x000a;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
nvgl_wrap_mode(unsigned wrap)
|
||||||
|
{
|
||||||
|
switch (wrap) {
|
||||||
|
case GL_REPEAT:
|
||||||
|
return 0x1;
|
||||||
|
case GL_MIRRORED_REPEAT:
|
||||||
|
return 0x2;
|
||||||
|
case GL_CLAMP_TO_EDGE:
|
||||||
|
return 0x3;
|
||||||
|
case GL_CLAMP_TO_BORDER:
|
||||||
|
return 0x4;
|
||||||
|
case GL_CLAMP:
|
||||||
|
return 0x5;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
nvgl_filter_mode(unsigned filter)
|
||||||
|
{
|
||||||
|
switch (filter) {
|
||||||
|
case GL_NEAREST:
|
||||||
|
return 0x1;
|
||||||
|
case GL_LINEAR:
|
||||||
|
return 0x2;
|
||||||
|
case GL_NEAREST_MIPMAP_NEAREST:
|
||||||
|
return 0x3;
|
||||||
|
case GL_LINEAR_MIPMAP_NEAREST:
|
||||||
|
return 0x4;
|
||||||
|
case GL_NEAREST_MIPMAP_LINEAR:
|
||||||
|
return 0x5;
|
||||||
|
case GL_LINEAR_MIPMAP_LINEAR:
|
||||||
|
return 0x6;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
98
src/mesa/drivers/dri/nouveau/nouveau_render.h
Normal file
98
src/mesa/drivers/dri/nouveau/nouveau_render.h
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* 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_RENDER_H__
|
||||||
|
#define __NOUVEAU_RENDER_H__
|
||||||
|
|
||||||
|
#include "vbo/vbo_context.h"
|
||||||
|
|
||||||
|
struct nouveau_array_state;
|
||||||
|
|
||||||
|
typedef void (*dispatch_t)(GLcontext *, unsigned int, int, unsigned int);
|
||||||
|
typedef unsigned (*extract_u_t)(struct nouveau_array_state *a, int i, int j);
|
||||||
|
typedef float (*extract_f_t)(struct nouveau_array_state *a, int i, int j);
|
||||||
|
|
||||||
|
struct nouveau_attr_info {
|
||||||
|
int vbo_index;
|
||||||
|
int imm_method;
|
||||||
|
int imm_fields;
|
||||||
|
|
||||||
|
void (*emit)(GLcontext *, 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RENDER_SCRATCH_COUNT 32
|
||||||
|
#define RENDER_SCRATCH_SIZE 64*1024
|
||||||
|
|
||||||
|
struct nouveau_scratch_state {
|
||||||
|
struct nouveau_bo *bo[RENDER_SCRATCH_COUNT];
|
||||||
|
|
||||||
|
int index;
|
||||||
|
int offset;
|
||||||
|
void *buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nouveau_swtnl_state {
|
||||||
|
struct nouveau_bo *vbo;
|
||||||
|
void *buf;
|
||||||
|
unsigned vertex_count;
|
||||||
|
GLenum primitive;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nouveau_render_state {
|
||||||
|
enum {
|
||||||
|
VBO,
|
||||||
|
IMM
|
||||||
|
} mode;
|
||||||
|
|
||||||
|
struct nouveau_array_state ib;
|
||||||
|
struct nouveau_array_state 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). */
|
||||||
|
int map[VERT_ATTRIB_MAX];
|
||||||
|
|
||||||
|
int attr_count;
|
||||||
|
int vertex_size;
|
||||||
|
|
||||||
|
struct nouveau_scratch_state scratch;
|
||||||
|
struct nouveau_swtnl_state swtnl;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define to_render_state(ctx) (&to_nouveau_context(ctx)->render)
|
||||||
|
|
||||||
|
#endif
|
||||||
361
src/mesa/drivers/dri/nouveau/nouveau_render_t.c
Normal file
361
src/mesa/drivers/dri/nouveau/nouveau_render_t.c
Normal file
|
|
@ -0,0 +1,361 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vertex submission helper definitions shared among the software and
|
||||||
|
* hardware TnL paths.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nouveau_gldefs.h"
|
||||||
|
|
||||||
|
#include "main/light.h"
|
||||||
|
#include "vbo/vbo.h"
|
||||||
|
#include "tnl/tnl.h"
|
||||||
|
|
||||||
|
#define OUT_INDICES_L(r, i, d, n) \
|
||||||
|
BATCH_OUT_L(i + d, n); \
|
||||||
|
(void)r
|
||||||
|
#define OUT_INDICES_I16(r, i, d, n) \
|
||||||
|
BATCH_OUT_I16(r->ib.extract_u(&r->ib, 0, i) + d, \
|
||||||
|
r->ib.extract_u(&r->ib, 0, i + 1) + d)
|
||||||
|
#define OUT_INDICES_I32(r, i, d, n) \
|
||||||
|
BATCH_OUT_I32(r->ib.extract_u(&r->ib, 0, i) + d)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit <n> vertices using BATCH_OUT_<out>, MAX_OUT_<out> at a time,
|
||||||
|
* grouping them in packets of length MAX_PACKET.
|
||||||
|
*
|
||||||
|
* out: hardware index data type.
|
||||||
|
* ctx: GL context.
|
||||||
|
* start: element within the index buffer to begin with.
|
||||||
|
* delta: integer correction that will be added to each index found in
|
||||||
|
* the index buffer.
|
||||||
|
*/
|
||||||
|
#define EMIT_VBO(out, ctx, start, delta, n) do { \
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx); \
|
||||||
|
int npush = n; \
|
||||||
|
\
|
||||||
|
while (npush) { \
|
||||||
|
int npack = MIN2(npush, MAX_PACKET * MAX_OUT_##out); \
|
||||||
|
npush -= npack; \
|
||||||
|
\
|
||||||
|
BATCH_PACKET_##out((npack + MAX_OUT_##out - 1) \
|
||||||
|
/ MAX_OUT_##out); \
|
||||||
|
while (npack) { \
|
||||||
|
int nout = MIN2(npack, MAX_OUT_##out); \
|
||||||
|
npack -= nout; \
|
||||||
|
\
|
||||||
|
OUT_INDICES_##out(render, start, delta, \
|
||||||
|
nout); \
|
||||||
|
start += nout; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit the <n>-th element of the array <a>, using IMM_OUT.
|
||||||
|
*/
|
||||||
|
#define EMIT_IMM(ctx, a, n) do { \
|
||||||
|
struct nouveau_attr_info *info = \
|
||||||
|
&TAG(vertex_attrs)[(a)->attr]; \
|
||||||
|
int m; \
|
||||||
|
\
|
||||||
|
if (!info->emit) { \
|
||||||
|
IMM_PACKET(info->imm_method, info->imm_fields); \
|
||||||
|
\
|
||||||
|
for (m = 0; m < (a)->fields; m++) \
|
||||||
|
IMM_OUT((a)->extract_f(a, n, m)); \
|
||||||
|
\
|
||||||
|
for (m = (a)->fields; m < info->imm_fields; m++) \
|
||||||
|
IMM_OUT(((float []){0, 0, 0, 1})[m]); \
|
||||||
|
\
|
||||||
|
} else { \
|
||||||
|
info->emit(ctx, a, (a)->buf + n * (a)->stride); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select an appropriate dispatch function for the given index buffer.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
get_array_dispatch(struct nouveau_array_state *a, dispatch_t *dispatch)
|
||||||
|
{
|
||||||
|
if (!a->fields) {
|
||||||
|
auto void f(GLcontext *, unsigned int, int, unsigned int);
|
||||||
|
|
||||||
|
void f(GLcontext *ctx, unsigned int start, int delta,
|
||||||
|
unsigned int n) {
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
RENDER_LOCALS(ctx);
|
||||||
|
|
||||||
|
EMIT_VBO(L, ctx, start, delta, n);
|
||||||
|
};
|
||||||
|
|
||||||
|
*dispatch = f;
|
||||||
|
|
||||||
|
} else if (a->type == GL_UNSIGNED_INT) {
|
||||||
|
auto void f(GLcontext *, unsigned int, int, unsigned int);
|
||||||
|
|
||||||
|
void f(GLcontext *ctx, unsigned int start, int delta,
|
||||||
|
unsigned int n) {
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
RENDER_LOCALS(ctx);
|
||||||
|
|
||||||
|
EMIT_VBO(I32, ctx, start, delta, n);
|
||||||
|
};
|
||||||
|
|
||||||
|
*dispatch = f;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
auto void f(GLcontext *, unsigned int, int, unsigned int);
|
||||||
|
|
||||||
|
void f(GLcontext *ctx, unsigned int start, int delta,
|
||||||
|
unsigned int n) {
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
RENDER_LOCALS(ctx);
|
||||||
|
|
||||||
|
EMIT_VBO(I32, ctx, start, delta, n & 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a pointer to a chunk of <size> bytes long GART memory. <bo>
|
||||||
|
* will be updated with the buffer object the memory is located in.
|
||||||
|
*
|
||||||
|
* If <offset> is provided, it will be updated with the offset within
|
||||||
|
* <bo> of the allocated memory. Otherwise the returned memory will
|
||||||
|
* always be located right at the beginning of <bo>.
|
||||||
|
*/
|
||||||
|
static inline void *
|
||||||
|
get_scratch_vbo(GLcontext *ctx, unsigned size, struct nouveau_bo **bo,
|
||||||
|
unsigned *offset)
|
||||||
|
{
|
||||||
|
struct nouveau_scratch_state *scratch = &to_render_state(ctx)->scratch;
|
||||||
|
void *buf;
|
||||||
|
|
||||||
|
if (scratch->buf && offset &&
|
||||||
|
size <= RENDER_SCRATCH_SIZE - scratch->offset) {
|
||||||
|
nouveau_bo_ref(scratch->bo[scratch->index], bo);
|
||||||
|
|
||||||
|
buf = scratch->buf + scratch->offset;
|
||||||
|
*offset = scratch->offset;
|
||||||
|
scratch->offset += size;
|
||||||
|
|
||||||
|
} else if (size <= RENDER_SCRATCH_SIZE) {
|
||||||
|
scratch->index = (scratch->index + 1) % RENDER_SCRATCH_COUNT;
|
||||||
|
nouveau_bo_ref(scratch->bo[scratch->index], bo);
|
||||||
|
|
||||||
|
nouveau_bo_map(*bo, NOUVEAU_BO_WR);
|
||||||
|
buf = scratch->buf = (*bo)->map;
|
||||||
|
nouveau_bo_unmap(*bo);
|
||||||
|
|
||||||
|
if (offset)
|
||||||
|
*offset = 0;
|
||||||
|
scratch->offset = size;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nouveau_bo_new(context_dev(ctx),
|
||||||
|
NOUVEAU_BO_MAP | NOUVEAU_BO_GART, 0, size, bo);
|
||||||
|
|
||||||
|
nouveau_bo_map(*bo, NOUVEAU_BO_WR);
|
||||||
|
buf = (*bo)->map;
|
||||||
|
nouveau_bo_unmap(*bo);
|
||||||
|
|
||||||
|
if (offset)
|
||||||
|
*offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns how many vertices you can draw using <n> pushbuf dwords.
|
||||||
|
*/
|
||||||
|
static inline unsigned
|
||||||
|
get_max_vertices(GLcontext *ctx, const struct _mesa_index_buffer *ib,
|
||||||
|
unsigned n)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
|
||||||
|
if (render->mode == IMM) {
|
||||||
|
return MAX2(0, n - 4) / (render->vertex_size / 4 +
|
||||||
|
render->attr_count);
|
||||||
|
} else {
|
||||||
|
unsigned max_out;
|
||||||
|
|
||||||
|
if (ib) {
|
||||||
|
switch (ib->type) {
|
||||||
|
case GL_UNSIGNED_INT:
|
||||||
|
max_out = MAX_OUT_I32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_UNSIGNED_SHORT:
|
||||||
|
max_out = MAX_OUT_I16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_UNSIGNED_BYTE:
|
||||||
|
max_out = MAX_OUT_I16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
max_out = MAX_OUT_L;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MAX2(0, n - 7) * max_out * MAX_PACKET / (1 + MAX_PACKET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "nouveau_vbo_t.c"
|
||||||
|
#include "nouveau_swtnl_t.c"
|
||||||
|
|
||||||
|
static void
|
||||||
|
TAG(emit_material)(GLcontext *ctx, struct nouveau_array_state *a,
|
||||||
|
const void *v)
|
||||||
|
{
|
||||||
|
const int attr = a->attr - VERT_ATTRIB_GENERIC0;
|
||||||
|
const int state = ((int []) {
|
||||||
|
NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT,
|
||||||
|
NOUVEAU_STATE_MATERIAL_BACK_AMBIENT,
|
||||||
|
NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE,
|
||||||
|
NOUVEAU_STATE_MATERIAL_BACK_DIFFUSE,
|
||||||
|
NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR,
|
||||||
|
NOUVEAU_STATE_MATERIAL_BACK_SPECULAR,
|
||||||
|
NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT,
|
||||||
|
NOUVEAU_STATE_MATERIAL_BACK_AMBIENT,
|
||||||
|
NOUVEAU_STATE_MATERIAL_FRONT_SHININESS,
|
||||||
|
NOUVEAU_STATE_MATERIAL_BACK_SHININESS
|
||||||
|
}) [attr];
|
||||||
|
|
||||||
|
COPY_4V(ctx->Light.Material.Attrib[attr], (float *)v);
|
||||||
|
_mesa_update_material(ctx, 1 << attr);
|
||||||
|
|
||||||
|
context_drv(ctx)->emit[state](ctx, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
TAG(render_prims)(GLcontext *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,
|
||||||
|
GLuint min_index, GLuint max_index)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||||
|
|
||||||
|
nouveau_validate_framebuffer(ctx);
|
||||||
|
|
||||||
|
if (nctx->fallback == HWTNL)
|
||||||
|
TAG(vbo_render_prims)(ctx, arrays, prims, nr_prims, ib,
|
||||||
|
index_bounds_valid, min_index, max_index);
|
||||||
|
|
||||||
|
if (nctx->fallback == SWTNL)
|
||||||
|
_tnl_vbo_draw_prims(ctx, arrays, prims, nr_prims, ib,
|
||||||
|
index_bounds_valid, min_index, max_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TAG(render_init)(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
struct nouveau_scratch_state *scratch = &render->scratch;
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
for (i = 0; i < RENDER_SCRATCH_COUNT; i++) {
|
||||||
|
ret = nouveau_bo_new(context_dev(ctx),
|
||||||
|
NOUVEAU_BO_MAP | NOUVEAU_BO_GART,
|
||||||
|
0, RENDER_SCRATCH_SIZE, &scratch->bo[i]);
|
||||||
|
assert(!ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < VERT_ATTRIB_MAX; i++)
|
||||||
|
render->map[i] = -1;
|
||||||
|
|
||||||
|
TAG(swtnl_init)(ctx);
|
||||||
|
vbo_set_draw_func(ctx, TAG(render_prims));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TAG(render_destroy)(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
TAG(swtnl_destroy)(ctx);
|
||||||
|
}
|
||||||
269
src/mesa/drivers/dri/nouveau/nouveau_screen.c
Normal file
269
src/mesa/drivers/dri/nouveau/nouveau_screen.c
Normal file
|
|
@ -0,0 +1,269 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_fbo.h"
|
||||||
|
#include "nouveau_drmif.h"
|
||||||
|
#include "nv04_driver.h"
|
||||||
|
#include "nv10_driver.h"
|
||||||
|
#include "nv20_driver.h"
|
||||||
|
|
||||||
|
#include "main/framebuffer.h"
|
||||||
|
#include "main/renderbuffer.h"
|
||||||
|
|
||||||
|
static const __DRIextension *nouveau_screen_extensions[];
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_destroy_screen(__DRIscreen *dri_screen);
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_channel_flush_notify(struct nouveau_channel *chan)
|
||||||
|
{
|
||||||
|
struct nouveau_screen *screen = chan->user_private;
|
||||||
|
struct nouveau_context *nctx = screen->context;
|
||||||
|
|
||||||
|
if (nctx && nctx->fallback < SWRAST)
|
||||||
|
nouveau_state_emit(&nctx->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const __DRIconfig **
|
||||||
|
nouveau_get_configs(void)
|
||||||
|
{
|
||||||
|
__DRIconfig **configs = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
const uint8_t depth_bits[] = { 0, 16, 24, 24 };
|
||||||
|
const uint8_t stencil_bits[] = { 0, 0, 0, 8 };
|
||||||
|
const uint8_t msaa_samples[] = { 0 };
|
||||||
|
|
||||||
|
const struct {
|
||||||
|
GLenum format;
|
||||||
|
GLenum type;
|
||||||
|
} fb_formats[] = {
|
||||||
|
{ GL_RGB , GL_UNSIGNED_SHORT_5_6_5 },
|
||||||
|
{ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV },
|
||||||
|
{ GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV },
|
||||||
|
};
|
||||||
|
|
||||||
|
const GLenum back_buffer_modes[] = {
|
||||||
|
GLX_NONE, GLX_SWAP_UNDEFINED_OML
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < Elements(fb_formats); i++) {
|
||||||
|
__DRIconfig **config;
|
||||||
|
|
||||||
|
config = driCreateConfigs(fb_formats[i].format,
|
||||||
|
fb_formats[i].type,
|
||||||
|
depth_bits, stencil_bits,
|
||||||
|
Elements(depth_bits),
|
||||||
|
back_buffer_modes,
|
||||||
|
Elements(back_buffer_modes),
|
||||||
|
msaa_samples,
|
||||||
|
Elements(msaa_samples));
|
||||||
|
assert(config);
|
||||||
|
|
||||||
|
configs = configs ? driConcatConfigs(configs, config)
|
||||||
|
: config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (const __DRIconfig **)configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const __DRIconfig **
|
||||||
|
nouveau_init_screen2(__DRIscreen *dri_screen)
|
||||||
|
{
|
||||||
|
const __DRIconfig **configs;
|
||||||
|
struct nouveau_screen *screen;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Allocate the screen. */
|
||||||
|
screen = CALLOC_STRUCT(nouveau_screen);
|
||||||
|
if (!screen)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dri_screen->private = screen;
|
||||||
|
dri_screen->extensions = nouveau_screen_extensions;
|
||||||
|
screen->dri_screen = dri_screen;
|
||||||
|
|
||||||
|
/* Open the DRM device. */
|
||||||
|
ret = nouveau_device_open_existing(&screen->device, 0, dri_screen->fd,
|
||||||
|
0);
|
||||||
|
if (ret) {
|
||||||
|
nouveau_error("Error opening the DRM device.\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = nouveau_channel_alloc(screen->device, 0xbeef0201, 0xbeef0202,
|
||||||
|
&screen->chan);
|
||||||
|
if (ret) {
|
||||||
|
nouveau_error("Error initializing the FIFO.\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
screen->chan->flush_notify = nouveau_channel_flush_notify;
|
||||||
|
screen->chan->user_private = screen;
|
||||||
|
|
||||||
|
/* Do the card specific initialization */
|
||||||
|
switch (screen->device->chipset & 0xf0) {
|
||||||
|
case 0x00:
|
||||||
|
ret = nv04_screen_init(screen);
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
ret = nv10_screen_init(screen);
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
ret = nv20_screen_init(screen);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
if (!ret) {
|
||||||
|
nouveau_error("Error initializing the hardware.\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
configs = nouveau_get_configs();
|
||||||
|
if (!configs) {
|
||||||
|
nouveau_error("Error creating the framebuffer configs.\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return configs;
|
||||||
|
fail:
|
||||||
|
nouveau_destroy_screen(dri_screen);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_destroy_screen(__DRIscreen *dri_screen)
|
||||||
|
{
|
||||||
|
struct nouveau_screen *screen = dri_screen->private;
|
||||||
|
|
||||||
|
if (!screen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
screen->driver->screen_destroy(screen);
|
||||||
|
|
||||||
|
if (screen->chan) {
|
||||||
|
screen->chan->flush_notify = NULL;
|
||||||
|
nouveau_channel_free(&screen->chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (screen->device)
|
||||||
|
nouveau_device_close(&screen->device);
|
||||||
|
|
||||||
|
FREE(screen);
|
||||||
|
dri_screen->private = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
nouveau_create_buffer(__DRIscreen *dri_screen,
|
||||||
|
__DRIdrawable *drawable,
|
||||||
|
const __GLcontextModes *visual,
|
||||||
|
GLboolean is_pixmap)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *rb;
|
||||||
|
struct gl_framebuffer *fb;
|
||||||
|
GLenum color_format;
|
||||||
|
|
||||||
|
if (is_pixmap)
|
||||||
|
return GL_FALSE; /* not implemented */
|
||||||
|
|
||||||
|
if (visual->redBits == 5)
|
||||||
|
color_format = GL_RGB5;
|
||||||
|
else if (visual->alphaBits == 0)
|
||||||
|
color_format = GL_RGB8;
|
||||||
|
else
|
||||||
|
color_format = GL_RGBA8;
|
||||||
|
|
||||||
|
fb = nouveau_framebuffer_dri_new(visual);
|
||||||
|
if (!fb)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
/* Front buffer. */
|
||||||
|
rb = nouveau_renderbuffer_dri_new(color_format, drawable);
|
||||||
|
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, rb);
|
||||||
|
|
||||||
|
/* Back buffer */
|
||||||
|
if (visual->doubleBufferMode) {
|
||||||
|
rb = nouveau_renderbuffer_dri_new(color_format, drawable);
|
||||||
|
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Depth/stencil buffer. */
|
||||||
|
if (visual->depthBits == 24 && visual->stencilBits == 8) {
|
||||||
|
rb = nouveau_renderbuffer_dri_new(GL_DEPTH24_STENCIL8_EXT, drawable);
|
||||||
|
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
|
||||||
|
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
|
||||||
|
|
||||||
|
} else if (visual->depthBits == 24) {
|
||||||
|
rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT24, drawable);
|
||||||
|
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
|
||||||
|
|
||||||
|
} else if (visual->depthBits == 16) {
|
||||||
|
rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT16, drawable);
|
||||||
|
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Software renderbuffers. */
|
||||||
|
_mesa_add_soft_renderbuffers(fb, GL_FALSE, GL_FALSE, GL_FALSE,
|
||||||
|
visual->accumRedBits > 0,
|
||||||
|
GL_FALSE, GL_FALSE);
|
||||||
|
|
||||||
|
drawable->driverPrivate = fb;
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_destroy_buffer(__DRIdrawable *drawable)
|
||||||
|
{
|
||||||
|
_mesa_reference_framebuffer(
|
||||||
|
(struct gl_framebuffer **)&drawable->driverPrivate, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const __DRIextension *nouveau_screen_extensions[] = {
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct __DriverAPIRec driDriverAPI = {
|
||||||
|
.InitScreen2 = nouveau_init_screen2,
|
||||||
|
.DestroyScreen = nouveau_destroy_screen,
|
||||||
|
.CreateBuffer = nouveau_create_buffer,
|
||||||
|
.DestroyBuffer = nouveau_destroy_buffer,
|
||||||
|
.CreateContext = nouveau_context_create,
|
||||||
|
.DestroyContext = nouveau_context_destroy,
|
||||||
|
.MakeCurrent = nouveau_context_make_current,
|
||||||
|
.UnbindContext = nouveau_context_unbind,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is the table of extensions that the loader will dlsym() for. */
|
||||||
|
PUBLIC const __DRIextension *__driDriverExtensions[] = {
|
||||||
|
&driCoreExtension.base,
|
||||||
|
&driDRI2Extension.base,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
54
src/mesa/drivers/dri/nouveau/nouveau_screen.h
Normal file
54
src/mesa/drivers/dri/nouveau/nouveau_screen.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_SCREEN_H__
|
||||||
|
#define __NOUVEAU_SCREEN_H__
|
||||||
|
|
||||||
|
struct nouveau_context;
|
||||||
|
|
||||||
|
struct nouveau_screen {
|
||||||
|
__DRIscreen *dri_screen;
|
||||||
|
|
||||||
|
struct nouveau_device *device;
|
||||||
|
struct nouveau_channel *chan;
|
||||||
|
|
||||||
|
struct nouveau_notifier *ntfy;
|
||||||
|
struct nouveau_grobj *eng3d;
|
||||||
|
struct nouveau_grobj *eng3dm;
|
||||||
|
struct nouveau_grobj *surf3d;
|
||||||
|
struct nouveau_grobj *m2mf;
|
||||||
|
struct nouveau_grobj *surf2d;
|
||||||
|
struct nouveau_grobj *rop;
|
||||||
|
struct nouveau_grobj *patt;
|
||||||
|
struct nouveau_grobj *rect;
|
||||||
|
struct nouveau_grobj *swzsurf;
|
||||||
|
struct nouveau_grobj *sifm;
|
||||||
|
|
||||||
|
const struct nouveau_driver *driver;
|
||||||
|
struct nouveau_context *context;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
174
src/mesa/drivers/dri/nouveau/nouveau_span.c
Normal file
174
src/mesa/drivers/dri/nouveau/nouveau_span.c
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_fbo.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_bo.h"
|
||||||
|
|
||||||
|
#include "swrast/swrast.h"
|
||||||
|
|
||||||
|
#define LOCAL_VARS \
|
||||||
|
struct gl_framebuffer *fb = ctx->DrawBuffer; \
|
||||||
|
struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; \
|
||||||
|
GLuint p; \
|
||||||
|
(void)p;
|
||||||
|
|
||||||
|
#define LOCAL_DEPTH_VARS LOCAL_VARS
|
||||||
|
|
||||||
|
#define HW_LOCK()
|
||||||
|
#define HW_UNLOCK()
|
||||||
|
|
||||||
|
#define HW_CLIPLOOP() { \
|
||||||
|
int minx = 0; \
|
||||||
|
int miny = 0; \
|
||||||
|
int maxx = fb->Width; \
|
||||||
|
int maxy = fb->Height;
|
||||||
|
|
||||||
|
#define HW_ENDCLIPLOOP() }
|
||||||
|
|
||||||
|
#define Y_FLIP(y) (fb->Name ? (y) : rb->Height - 1 - (y))
|
||||||
|
|
||||||
|
/* RGB565 span functions */
|
||||||
|
#define SPANTMP_PIXEL_FMT GL_RGB
|
||||||
|
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
|
||||||
|
#define TAG(x) nouveau_##x##_rgb565
|
||||||
|
#define TAG2(x, y) nouveau_##x##_rgb565##y
|
||||||
|
#define GET_PTR(x, y) (s->bo->map + (y)*s->pitch + (x)*s->cpp)
|
||||||
|
|
||||||
|
#include "spantmp2.h"
|
||||||
|
|
||||||
|
/* ARGB8888 span functions */
|
||||||
|
#define SPANTMP_PIXEL_FMT GL_BGRA
|
||||||
|
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
|
||||||
|
#define TAG(x) nouveau_##x##_argb8888
|
||||||
|
#define TAG2(x, y) nouveau_##x##_argb8888##y
|
||||||
|
#define GET_PTR(x, y) (s->bo->map + (y)*s->pitch + (x)*s->cpp)
|
||||||
|
|
||||||
|
#include "spantmp2.h"
|
||||||
|
|
||||||
|
/* Z16 span functions */
|
||||||
|
#define VALUE_TYPE uint16_t
|
||||||
|
#define READ_DEPTH(v, x, y) \
|
||||||
|
v = *(uint16_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp);
|
||||||
|
#define WRITE_DEPTH(x, y, v) \
|
||||||
|
*(uint16_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp) = v
|
||||||
|
#define TAG(x) nouveau_##x##_z16
|
||||||
|
|
||||||
|
#include "depthtmp.h"
|
||||||
|
|
||||||
|
/* Z24S8 span functions */
|
||||||
|
#define VALUE_TYPE uint32_t
|
||||||
|
#define READ_DEPTH(v, x, y) \
|
||||||
|
v = *(uint32_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp);
|
||||||
|
#define WRITE_DEPTH(x, y, v) \
|
||||||
|
*(uint32_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp) = v
|
||||||
|
#define TAG(x) nouveau_##x##_z24s8
|
||||||
|
|
||||||
|
#include "depthtmp.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
renderbuffer_map_unmap(struct gl_renderbuffer *rb, GLboolean map)
|
||||||
|
{
|
||||||
|
struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
|
||||||
|
|
||||||
|
if (map) {
|
||||||
|
switch (rb->Format) {
|
||||||
|
case MESA_FORMAT_RGB565:
|
||||||
|
nouveau_InitPointers_rgb565(rb);
|
||||||
|
break;
|
||||||
|
case MESA_FORMAT_XRGB8888:
|
||||||
|
case MESA_FORMAT_ARGB8888:
|
||||||
|
nouveau_InitPointers_argb8888(rb);
|
||||||
|
break;
|
||||||
|
case MESA_FORMAT_Z16:
|
||||||
|
nouveau_InitDepthPointers_z16(rb);
|
||||||
|
break;
|
||||||
|
case MESA_FORMAT_Z24_S8:
|
||||||
|
nouveau_InitDepthPointers_z24s8(rb);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR);
|
||||||
|
} else {
|
||||||
|
nouveau_bo_unmap(s->bo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
texture_unit_map_unmap(GLcontext *ctx, struct gl_texture_unit *u, GLboolean map)
|
||||||
|
{
|
||||||
|
if (!u->_ReallyEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (map)
|
||||||
|
ctx->Driver.MapTexture(ctx, u->_Current);
|
||||||
|
else
|
||||||
|
ctx->Driver.UnmapTexture(ctx, u->_Current);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
span_map_unmap(GLcontext *ctx, GLboolean map)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++)
|
||||||
|
renderbuffer_map_unmap(ctx->DrawBuffer->_ColorDrawBuffers[i], map);
|
||||||
|
|
||||||
|
renderbuffer_map_unmap(ctx->DrawBuffer->_ColorReadBuffer, map);
|
||||||
|
|
||||||
|
if (ctx->DrawBuffer->_DepthBuffer)
|
||||||
|
renderbuffer_map_unmap(ctx->DrawBuffer->_DepthBuffer->Wrapped, map);
|
||||||
|
|
||||||
|
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
|
||||||
|
texture_unit_map_unmap(ctx, &ctx->Texture.Unit[i], map);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_span_start(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
nouveau_fallback(ctx, SWRAST);
|
||||||
|
span_map_unmap(ctx, GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_span_finish(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
span_map_unmap(ctx, GL_FALSE);
|
||||||
|
nouveau_fallback(ctx, HWTNL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_span_functions_init(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct swrast_device_driver *swdd =
|
||||||
|
_swrast_GetDeviceDriverReference(ctx);
|
||||||
|
|
||||||
|
swdd->SpanRenderStart = nouveau_span_start;
|
||||||
|
swdd->SpanRenderFinish = nouveau_span_finish;
|
||||||
|
}
|
||||||
532
src/mesa/drivers/dri/nouveau/nouveau_state.c
Normal file
532
src/mesa/drivers/dri/nouveau/nouveau_state.c
Normal file
|
|
@ -0,0 +1,532 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_texture.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
|
||||||
|
#include "swrast/swrast.h"
|
||||||
|
#include "tnl/tnl.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_alpha_func(GLcontext *ctx, GLenum func, GLfloat ref)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, ALPHA_FUNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_blend_color(GLcontext *ctx, const GLfloat color[4])
|
||||||
|
{
|
||||||
|
context_dirty(ctx, BLEND_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_blend_equation_separate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, BLEND_EQUATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_blend_func_separate(GLcontext *ctx, GLenum sfactorRGB,
|
||||||
|
GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, BLEND_FUNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_clip_plane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
|
||||||
|
{
|
||||||
|
context_dirty_i(ctx, CLIP_PLANE, plane - GL_CLIP_PLANE0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_color_mask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
|
||||||
|
GLboolean bmask, GLboolean amask)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, COLOR_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_color_material(GLcontext *ctx, GLenum face, GLenum mode)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, COLOR_MATERIAL);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_SPECULAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_cull_face(GLcontext *ctx, GLenum mode)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, CULL_FACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_front_face(GLcontext *ctx, GLenum mode)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, FRONT_FACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_depth_func(GLcontext *ctx, GLenum func)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, DEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_depth_mask(GLcontext *ctx, GLboolean flag)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, DEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_depth_range(GLcontext *ctx, GLclampd nearval, GLclampd farval)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, VIEWPORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_draw_buffer(GLcontext *ctx, GLenum buffer)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, FRAMEBUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_draw_buffers(GLcontext *ctx, GLsizei n, const GLenum *buffers)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, FRAMEBUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_enable(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch (cap) {
|
||||||
|
case GL_ALPHA_TEST:
|
||||||
|
context_dirty(ctx, ALPHA_FUNC);
|
||||||
|
break;
|
||||||
|
case GL_BLEND:
|
||||||
|
context_dirty(ctx, BLEND_EQUATION);
|
||||||
|
break;
|
||||||
|
case GL_COLOR_LOGIC_OP:
|
||||||
|
context_dirty(ctx, LOGIC_OPCODE);
|
||||||
|
break;
|
||||||
|
case GL_COLOR_MATERIAL:
|
||||||
|
context_dirty(ctx, COLOR_MATERIAL);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_SPECULAR);
|
||||||
|
break;
|
||||||
|
case GL_COLOR_SUM_EXT:
|
||||||
|
context_dirty(ctx, FRAG);
|
||||||
|
break;
|
||||||
|
case GL_CULL_FACE:
|
||||||
|
context_dirty(ctx, CULL_FACE);
|
||||||
|
break;
|
||||||
|
case GL_DEPTH_TEST:
|
||||||
|
context_dirty(ctx, DEPTH);
|
||||||
|
break;
|
||||||
|
case GL_DITHER:
|
||||||
|
context_dirty(ctx, DITHER);
|
||||||
|
break;
|
||||||
|
case GL_FOG:
|
||||||
|
context_dirty(ctx, FOG);
|
||||||
|
context_dirty(ctx, FRAG);
|
||||||
|
context_dirty(ctx, MODELVIEW);
|
||||||
|
break;
|
||||||
|
case GL_LIGHT0:
|
||||||
|
case GL_LIGHT1:
|
||||||
|
case GL_LIGHT2:
|
||||||
|
case GL_LIGHT3:
|
||||||
|
case GL_LIGHT4:
|
||||||
|
case GL_LIGHT5:
|
||||||
|
case GL_LIGHT6:
|
||||||
|
case GL_LIGHT7:
|
||||||
|
context_dirty(ctx, MODELVIEW);
|
||||||
|
context_dirty(ctx, LIGHT_ENABLE);
|
||||||
|
context_dirty_i(ctx, LIGHT_SOURCE, cap - GL_LIGHT0);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_SPECULAR);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_SHININESS);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_SHININESS);
|
||||||
|
break;
|
||||||
|
case GL_LIGHTING:
|
||||||
|
context_dirty(ctx, FRAG);
|
||||||
|
context_dirty(ctx, MODELVIEW);
|
||||||
|
context_dirty(ctx, LIGHT_ENABLE);
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_LIGHTS; i++) {
|
||||||
|
if (ctx->Light.Light[i].Enabled)
|
||||||
|
context_dirty_i(ctx, LIGHT_SOURCE, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_SPECULAR);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_SHININESS);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_SHININESS);
|
||||||
|
break;
|
||||||
|
case GL_LINE_SMOOTH:
|
||||||
|
context_dirty(ctx, LINE_MODE);
|
||||||
|
break;
|
||||||
|
case GL_NORMALIZE:
|
||||||
|
context_dirty(ctx, LIGHT_ENABLE);
|
||||||
|
break;
|
||||||
|
case GL_POINT_SMOOTH:
|
||||||
|
context_dirty(ctx, POINT_MODE);
|
||||||
|
break;
|
||||||
|
case GL_POLYGON_OFFSET_POINT:
|
||||||
|
case GL_POLYGON_OFFSET_LINE:
|
||||||
|
case GL_POLYGON_OFFSET_FILL:
|
||||||
|
context_dirty(ctx, POLYGON_OFFSET);
|
||||||
|
break;
|
||||||
|
case GL_POLYGON_SMOOTH:
|
||||||
|
context_dirty(ctx, POLYGON_MODE);
|
||||||
|
break;
|
||||||
|
case GL_SCISSOR_TEST:
|
||||||
|
context_dirty(ctx, SCISSOR);
|
||||||
|
break;
|
||||||
|
case GL_STENCIL_TEST:
|
||||||
|
context_dirty(ctx, STENCIL_FUNC);
|
||||||
|
break;
|
||||||
|
case GL_TEXTURE_1D:
|
||||||
|
case GL_TEXTURE_2D:
|
||||||
|
case GL_TEXTURE_3D:
|
||||||
|
context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_fog(GLcontext *ctx, GLenum pname, const GLfloat *params)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, FOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_index_mask(GLcontext *ctx, GLuint mask)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, INDEX_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_light(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params)
|
||||||
|
{
|
||||||
|
switch (pname) {
|
||||||
|
case GL_AMBIENT:
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_AMBIENT);
|
||||||
|
break;
|
||||||
|
case GL_DIFFUSE:
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
|
||||||
|
break;
|
||||||
|
case GL_SPECULAR:
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_SPECULAR);
|
||||||
|
break;
|
||||||
|
case GL_SPOT_CUTOFF:
|
||||||
|
case GL_POSITION:
|
||||||
|
context_dirty(ctx, MODELVIEW);
|
||||||
|
context_dirty(ctx, LIGHT_ENABLE);
|
||||||
|
context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_light_model(GLcontext *ctx, GLenum pname, const GLfloat *params)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, LIGHT_MODEL);
|
||||||
|
context_dirty(ctx, MODELVIEW);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_line_stipple(GLcontext *ctx, GLint factor, GLushort pattern )
|
||||||
|
{
|
||||||
|
context_dirty(ctx, LINE_STIPPLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_line_width(GLcontext *ctx, GLfloat width)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, LINE_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_logic_opcode(GLcontext *ctx, GLenum opcode)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, LOGIC_OPCODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_point_parameter(GLcontext *ctx, GLenum pname, const GLfloat *params)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, POINT_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_point_size(GLcontext *ctx, GLfloat size)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, POINT_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_polygon_mode(GLcontext *ctx, GLenum face, GLenum mode)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, POLYGON_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_polygon_offset(GLcontext *ctx, GLfloat factor, GLfloat units)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, POLYGON_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_polygon_stipple(GLcontext *ctx, const GLubyte *mask)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, POLYGON_STIPPLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_render_mode(GLcontext *ctx, GLenum mode)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, RENDER_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, SCISSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_shade_model(GLcontext *ctx, GLenum mode)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, SHADE_MODEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_stencil_func_separate(GLcontext *ctx, GLenum face, GLenum func,
|
||||||
|
GLint ref, GLuint mask)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, STENCIL_FUNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_stencil_mask_separate(GLcontext *ctx, GLenum face, GLuint mask)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, STENCIL_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_stencil_op_separate(GLcontext *ctx, GLenum face, GLenum fail,
|
||||||
|
GLenum zfail, GLenum zpass)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, STENCIL_OP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_tex_gen(GLcontext *ctx, GLenum coord, GLenum pname,
|
||||||
|
const GLfloat *params)
|
||||||
|
{
|
||||||
|
context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_tex_env(GLcontext *ctx, GLenum target, GLenum pname,
|
||||||
|
const GLfloat *param)
|
||||||
|
{
|
||||||
|
switch (target) {
|
||||||
|
case GL_TEXTURE_FILTER_CONTROL_EXT:
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_tex_parameter(GLcontext *ctx, GLenum target,
|
||||||
|
struct gl_texture_object *t, GLenum pname,
|
||||||
|
const GLfloat *params)
|
||||||
|
{
|
||||||
|
switch (pname) {
|
||||||
|
case GL_TEXTURE_MIN_FILTER:
|
||||||
|
case GL_TEXTURE_MAG_FILTER:
|
||||||
|
case GL_TEXTURE_WRAP_S:
|
||||||
|
case GL_TEXTURE_WRAP_T:
|
||||||
|
case GL_TEXTURE_WRAP_R:
|
||||||
|
case GL_TEXTURE_MIN_LOD:
|
||||||
|
case GL_TEXTURE_MAX_LOD:
|
||||||
|
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
||||||
|
case GL_TEXTURE_LOD_BIAS:
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_TEXTURE_BASE_LEVEL:
|
||||||
|
case GL_TEXTURE_MAX_LEVEL:
|
||||||
|
texture_dirty(t);
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, VIEWPORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_emit_nothing(GLcontext *ctx, int emit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nouveau_next_dirty_state(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||||
|
int i = BITSET_FFS(nctx->dirty) - 1;
|
||||||
|
|
||||||
|
if (i < 0 || i >= context_drv(ctx)->num_emit)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_state_emit(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||||
|
const struct nouveau_driver *drv = context_drv(ctx);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while ((i = nouveau_next_dirty_state(ctx)) >= 0) {
|
||||||
|
BITSET_CLEAR(nctx->dirty, i);
|
||||||
|
drv->emit[i](ctx, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
BITSET_ZERO(nctx->dirty);
|
||||||
|
|
||||||
|
nouveau_bo_state_emit(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_update_state(GLcontext *ctx, GLbitfield new_state)
|
||||||
|
{
|
||||||
|
if (new_state & (_NEW_PROJECTION | _NEW_MODELVIEW))
|
||||||
|
context_dirty(ctx, PROJECTION);
|
||||||
|
|
||||||
|
if (new_state & _NEW_MODELVIEW)
|
||||||
|
context_dirty(ctx, MODELVIEW);
|
||||||
|
|
||||||
|
if (new_state & _NEW_CURRENT_ATTRIB &&
|
||||||
|
new_state & _NEW_LIGHT) {
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_AMBIENT);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_DIFFUSE);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_SPECULAR);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_SPECULAR);
|
||||||
|
context_dirty(ctx, MATERIAL_FRONT_SHININESS);
|
||||||
|
context_dirty(ctx, MATERIAL_BACK_SHININESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
_swrast_InvalidateState(ctx, new_state);
|
||||||
|
_tnl_InvalidateState(ctx, new_state);
|
||||||
|
|
||||||
|
nouveau_state_emit(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_state_init(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||||
|
|
||||||
|
ctx->Driver.AlphaFunc = nouveau_alpha_func;
|
||||||
|
ctx->Driver.BlendColor = nouveau_blend_color;
|
||||||
|
ctx->Driver.BlendEquationSeparate = nouveau_blend_equation_separate;
|
||||||
|
ctx->Driver.BlendFuncSeparate = nouveau_blend_func_separate;
|
||||||
|
ctx->Driver.ClipPlane = nouveau_clip_plane;
|
||||||
|
ctx->Driver.ColorMask = nouveau_color_mask;
|
||||||
|
ctx->Driver.ColorMaterial = nouveau_color_material;
|
||||||
|
ctx->Driver.CullFace = nouveau_cull_face;
|
||||||
|
ctx->Driver.FrontFace = nouveau_front_face;
|
||||||
|
ctx->Driver.DepthFunc = nouveau_depth_func;
|
||||||
|
ctx->Driver.DepthMask = nouveau_depth_mask;
|
||||||
|
ctx->Driver.DepthRange = nouveau_depth_range;
|
||||||
|
ctx->Driver.DrawBuffer = nouveau_draw_buffer;
|
||||||
|
ctx->Driver.DrawBuffers = nouveau_draw_buffers;
|
||||||
|
ctx->Driver.Enable = nouveau_enable;
|
||||||
|
ctx->Driver.Fogfv = nouveau_fog;
|
||||||
|
ctx->Driver.IndexMask = nouveau_index_mask;
|
||||||
|
ctx->Driver.Lightfv = nouveau_light;
|
||||||
|
ctx->Driver.LightModelfv = nouveau_light_model;
|
||||||
|
ctx->Driver.LineStipple = nouveau_line_stipple;
|
||||||
|
ctx->Driver.LineWidth = nouveau_line_width;
|
||||||
|
ctx->Driver.LogicOpcode = nouveau_logic_opcode;
|
||||||
|
ctx->Driver.PointParameterfv = nouveau_point_parameter;
|
||||||
|
ctx->Driver.PointSize = nouveau_point_size;
|
||||||
|
ctx->Driver.PolygonMode = nouveau_polygon_mode;
|
||||||
|
ctx->Driver.PolygonOffset = nouveau_polygon_offset;
|
||||||
|
ctx->Driver.PolygonStipple = nouveau_polygon_stipple;
|
||||||
|
ctx->Driver.RenderMode = nouveau_render_mode;
|
||||||
|
ctx->Driver.Scissor = nouveau_scissor;
|
||||||
|
ctx->Driver.ShadeModel = nouveau_shade_model;
|
||||||
|
ctx->Driver.StencilFuncSeparate = nouveau_stencil_func_separate;
|
||||||
|
ctx->Driver.StencilMaskSeparate = nouveau_stencil_mask_separate;
|
||||||
|
ctx->Driver.StencilOpSeparate = nouveau_stencil_op_separate;
|
||||||
|
ctx->Driver.TexGen = nouveau_tex_gen;
|
||||||
|
ctx->Driver.TexEnv = nouveau_tex_env;
|
||||||
|
ctx->Driver.TexParameter = nouveau_tex_parameter;
|
||||||
|
ctx->Driver.Viewport = nouveau_viewport;
|
||||||
|
|
||||||
|
ctx->Driver.UpdateState = nouveau_update_state;
|
||||||
|
|
||||||
|
BITSET_ONES(nctx->dirty);
|
||||||
|
}
|
||||||
119
src/mesa/drivers/dri/nouveau/nouveau_state.h
Normal file
119
src/mesa/drivers/dri/nouveau/nouveau_state.h
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_STATE_H__
|
||||||
|
#define __NOUVEAU_STATE_H__
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NOUVEAU_STATE_ALPHA_FUNC,
|
||||||
|
NOUVEAU_STATE_BLEND_COLOR,
|
||||||
|
NOUVEAU_STATE_BLEND_EQUATION,
|
||||||
|
NOUVEAU_STATE_BLEND_FUNC,
|
||||||
|
NOUVEAU_STATE_CLIP_PLANE0,
|
||||||
|
NOUVEAU_STATE_CLIP_PLANE1,
|
||||||
|
NOUVEAU_STATE_CLIP_PLANE2,
|
||||||
|
NOUVEAU_STATE_CLIP_PLANE3,
|
||||||
|
NOUVEAU_STATE_CLIP_PLANE4,
|
||||||
|
NOUVEAU_STATE_CLIP_PLANE5,
|
||||||
|
NOUVEAU_STATE_COLOR_MASK,
|
||||||
|
NOUVEAU_STATE_COLOR_MATERIAL,
|
||||||
|
NOUVEAU_STATE_CULL_FACE,
|
||||||
|
NOUVEAU_STATE_FRONT_FACE,
|
||||||
|
NOUVEAU_STATE_DEPTH,
|
||||||
|
NOUVEAU_STATE_DITHER,
|
||||||
|
NOUVEAU_STATE_FRAG,
|
||||||
|
NOUVEAU_STATE_FRAMEBUFFER,
|
||||||
|
NOUVEAU_STATE_FOG,
|
||||||
|
NOUVEAU_STATE_INDEX_MASK,
|
||||||
|
NOUVEAU_STATE_LIGHT_ENABLE,
|
||||||
|
NOUVEAU_STATE_LIGHT_MODEL,
|
||||||
|
NOUVEAU_STATE_LIGHT_SOURCE0,
|
||||||
|
NOUVEAU_STATE_LIGHT_SOURCE1,
|
||||||
|
NOUVEAU_STATE_LIGHT_SOURCE2,
|
||||||
|
NOUVEAU_STATE_LIGHT_SOURCE3,
|
||||||
|
NOUVEAU_STATE_LIGHT_SOURCE4,
|
||||||
|
NOUVEAU_STATE_LIGHT_SOURCE5,
|
||||||
|
NOUVEAU_STATE_LIGHT_SOURCE6,
|
||||||
|
NOUVEAU_STATE_LIGHT_SOURCE7,
|
||||||
|
NOUVEAU_STATE_LINE_STIPPLE,
|
||||||
|
NOUVEAU_STATE_LINE_MODE,
|
||||||
|
NOUVEAU_STATE_LOGIC_OPCODE,
|
||||||
|
NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT,
|
||||||
|
NOUVEAU_STATE_MATERIAL_BACK_AMBIENT,
|
||||||
|
NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE,
|
||||||
|
NOUVEAU_STATE_MATERIAL_BACK_DIFFUSE,
|
||||||
|
NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR,
|
||||||
|
NOUVEAU_STATE_MATERIAL_BACK_SPECULAR,
|
||||||
|
NOUVEAU_STATE_MATERIAL_FRONT_SHININESS,
|
||||||
|
NOUVEAU_STATE_MATERIAL_BACK_SHININESS,
|
||||||
|
NOUVEAU_STATE_MODELVIEW,
|
||||||
|
NOUVEAU_STATE_POINT_MODE,
|
||||||
|
NOUVEAU_STATE_POINT_PARAMETER,
|
||||||
|
NOUVEAU_STATE_POLYGON_MODE,
|
||||||
|
NOUVEAU_STATE_POLYGON_OFFSET,
|
||||||
|
NOUVEAU_STATE_POLYGON_STIPPLE,
|
||||||
|
NOUVEAU_STATE_PROJECTION,
|
||||||
|
NOUVEAU_STATE_RENDER_MODE,
|
||||||
|
NOUVEAU_STATE_SCISSOR,
|
||||||
|
NOUVEAU_STATE_SHADE_MODEL,
|
||||||
|
NOUVEAU_STATE_STENCIL_FUNC,
|
||||||
|
NOUVEAU_STATE_STENCIL_MASK,
|
||||||
|
NOUVEAU_STATE_STENCIL_OP,
|
||||||
|
NOUVEAU_STATE_TEX_ENV0,
|
||||||
|
NOUVEAU_STATE_TEX_ENV1,
|
||||||
|
NOUVEAU_STATE_TEX_ENV2,
|
||||||
|
NOUVEAU_STATE_TEX_ENV3,
|
||||||
|
NOUVEAU_STATE_TEX_GEN0,
|
||||||
|
NOUVEAU_STATE_TEX_GEN1,
|
||||||
|
NOUVEAU_STATE_TEX_GEN2,
|
||||||
|
NOUVEAU_STATE_TEX_GEN3,
|
||||||
|
NOUVEAU_STATE_TEX_OBJ0,
|
||||||
|
NOUVEAU_STATE_TEX_OBJ1,
|
||||||
|
NOUVEAU_STATE_TEX_OBJ2,
|
||||||
|
NOUVEAU_STATE_TEX_OBJ3,
|
||||||
|
NOUVEAU_STATE_VIEWPORT,
|
||||||
|
NUM_NOUVEAU_STATE,
|
||||||
|
|
||||||
|
/* Room for card-specific states. */
|
||||||
|
|
||||||
|
MAX_NOUVEAU_STATE = NUM_NOUVEAU_STATE + 16,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*nouveau_state_func)(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_state_init(GLcontext *ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_emit_nothing(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
int
|
||||||
|
nouveau_next_dirty_state(GLcontext *ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_state_emit(GLcontext *ctx);
|
||||||
|
|
||||||
|
#endif
|
||||||
81
src/mesa/drivers/dri/nouveau/nouveau_surface.c
Normal file
81
src/mesa/drivers/dri/nouveau/nouveau_surface.c
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_surface_alloc(GLcontext *ctx, struct nouveau_surface *s,
|
||||||
|
enum nouveau_surface_layout layout,
|
||||||
|
unsigned flags, unsigned format,
|
||||||
|
unsigned width, unsigned height)
|
||||||
|
{
|
||||||
|
unsigned tile_mode, cpp = _mesa_get_format_bytes(format);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
nouveau_bo_ref(NULL, &s->bo);
|
||||||
|
|
||||||
|
*s = (struct nouveau_surface) {
|
||||||
|
.layout = layout,
|
||||||
|
.format = format,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.cpp = cpp,
|
||||||
|
.pitch = width * cpp,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (layout == TILED) {
|
||||||
|
s->pitch = align(s->pitch, 256);
|
||||||
|
tile_mode = s->pitch;
|
||||||
|
} else {
|
||||||
|
s->pitch = align(s->pitch, 64);
|
||||||
|
tile_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = nouveau_bo_new_tile(context_dev(ctx), flags, 0, s->pitch * height,
|
||||||
|
tile_mode, 0, &s->bo);
|
||||||
|
assert(!ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_surface_ref(struct nouveau_surface *src,
|
||||||
|
struct nouveau_surface *dst)
|
||||||
|
{
|
||||||
|
if (src) {
|
||||||
|
dst->offset = src->offset;
|
||||||
|
dst->layout = src->layout;
|
||||||
|
dst->format = src->format;
|
||||||
|
dst->width = src->width;
|
||||||
|
dst->height = src->height;
|
||||||
|
dst->cpp = src->cpp;
|
||||||
|
dst->pitch = src->pitch;
|
||||||
|
nouveau_bo_ref(src->bo, &dst->bo);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nouveau_bo_ref(NULL, &dst->bo);
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/mesa/drivers/dri/nouveau/nouveau_surface.h
Normal file
58
src/mesa/drivers/dri/nouveau/nouveau_surface.h
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_SURFACE_H__
|
||||||
|
#define __NOUVEAU_SURFACE_H__
|
||||||
|
|
||||||
|
enum nouveau_surface_layout {
|
||||||
|
LINEAR = 0,
|
||||||
|
TILED,
|
||||||
|
SWIZZLED,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nouveau_surface {
|
||||||
|
struct nouveau_bo *bo;
|
||||||
|
unsigned offset;
|
||||||
|
|
||||||
|
enum nouveau_surface_layout layout;
|
||||||
|
|
||||||
|
gl_format format;
|
||||||
|
unsigned cpp, pitch;
|
||||||
|
|
||||||
|
unsigned width, height;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_surface_alloc(GLcontext *ctx, struct nouveau_surface *s,
|
||||||
|
enum nouveau_surface_layout layout,
|
||||||
|
unsigned flags, unsigned format,
|
||||||
|
unsigned width, unsigned height);
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_surface_ref(struct nouveau_surface *src,
|
||||||
|
struct nouveau_surface *dst);
|
||||||
|
|
||||||
|
#endif
|
||||||
354
src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c
Normal file
354
src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c
Normal file
|
|
@ -0,0 +1,354 @@
|
||||||
|
/*
|
||||||
|
* 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 "tnl/t_context.h"
|
||||||
|
#include "tnl/t_pipeline.h"
|
||||||
|
#include "tnl/t_vertex.h"
|
||||||
|
|
||||||
|
static enum tnl_attr_format
|
||||||
|
swtnl_get_format(int type, int fields) {
|
||||||
|
switch (type) {
|
||||||
|
case GL_FLOAT:
|
||||||
|
switch (fields){
|
||||||
|
case 1:
|
||||||
|
return EMIT_1F;
|
||||||
|
case 2:
|
||||||
|
return EMIT_2F;
|
||||||
|
case 3:
|
||||||
|
return EMIT_3F;
|
||||||
|
case 4:
|
||||||
|
return EMIT_4F;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
case GL_UNSIGNED_BYTE:
|
||||||
|
switch (fields) {
|
||||||
|
case 4:
|
||||||
|
return EMIT_4UB_4F_RGBA;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct swtnl_attr_info {
|
||||||
|
int type;
|
||||||
|
int fields;
|
||||||
|
} swtnl_attrs[VERT_ATTRIB_MAX] = {
|
||||||
|
[VERT_ATTRIB_POS] = {
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.fields = 4,
|
||||||
|
},
|
||||||
|
[VERT_ATTRIB_NORMAL] = {
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.fields = -1,
|
||||||
|
},
|
||||||
|
[VERT_ATTRIB_COLOR0] = {
|
||||||
|
.type = GL_UNSIGNED_BYTE,
|
||||||
|
.fields = 4,
|
||||||
|
},
|
||||||
|
[VERT_ATTRIB_COLOR1] = {
|
||||||
|
.type = GL_UNSIGNED_BYTE,
|
||||||
|
.fields = 4,
|
||||||
|
},
|
||||||
|
[VERT_ATTRIB_FOG] = {
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.fields = 1,
|
||||||
|
},
|
||||||
|
[VERT_ATTRIB_TEX0] = {
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.fields = -1,
|
||||||
|
},
|
||||||
|
[VERT_ATTRIB_TEX1] = {
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.fields = -1,
|
||||||
|
},
|
||||||
|
[VERT_ATTRIB_TEX2] = {
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.fields = -1,
|
||||||
|
},
|
||||||
|
[VERT_ATTRIB_TEX3] = {
|
||||||
|
.type = GL_FLOAT,
|
||||||
|
.fields = -1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_choose_attrs(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
|
struct tnl_clipspace *vtx = &tnl->clipspace;
|
||||||
|
static struct tnl_attr_map map[NUM_VERTEX_ATTRS];
|
||||||
|
int fields, i, n = 0;
|
||||||
|
|
||||||
|
render->mode = VBO;
|
||||||
|
render->attr_count = NUM_VERTEX_ATTRS;
|
||||||
|
|
||||||
|
/* We always want non Ndc coords format */
|
||||||
|
tnl->vb.AttribPtr[VERT_ATTRIB_POS] = tnl->vb.ClipPtr;
|
||||||
|
|
||||||
|
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];
|
||||||
|
|
||||||
|
if (!sa->fields)
|
||||||
|
continue; /* Unsupported attribute. */
|
||||||
|
|
||||||
|
if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, i)) {
|
||||||
|
if (sa->fields > 0)
|
||||||
|
fields = sa->fields;
|
||||||
|
else
|
||||||
|
fields = tnl->vb.AttribPtr[i]->size;
|
||||||
|
|
||||||
|
map[n++] = (struct tnl_attr_map) {
|
||||||
|
.attrib = i,
|
||||||
|
.format = swtnl_get_format(sa->type, fields),
|
||||||
|
};
|
||||||
|
|
||||||
|
render->map[ha->vbo_index] = i;
|
||||||
|
a->attr = i;
|
||||||
|
a->fields = fields;
|
||||||
|
a->type = sa->type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_tnl_install_attrs(ctx, map, n, NULL, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < vtx->attr_count; i++) {
|
||||||
|
struct tnl_clipspace_attr *ta = &vtx->attr[i];
|
||||||
|
struct nouveau_array_state *a = &render->attrs[ta->attrib];
|
||||||
|
|
||||||
|
a->stride = vtx->vertex_size;
|
||||||
|
a->offset = ta->vertoffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAG(render_set_format)(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_alloc_vertices(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl;
|
||||||
|
|
||||||
|
nouveau_bo_ref(NULL, &swtnl->vbo);
|
||||||
|
swtnl->buf = get_scratch_vbo(ctx, RENDER_SCRATCH_SIZE,
|
||||||
|
&swtnl->vbo, NULL);
|
||||||
|
swtnl->vertex_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_bind_vertices(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
struct nouveau_swtnl_state *swtnl = &render->swtnl;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < render->attr_count; i++) {
|
||||||
|
int attr = render->map[i];
|
||||||
|
|
||||||
|
if (attr >= 0)
|
||||||
|
nouveau_bo_ref(swtnl->vbo,
|
||||||
|
&render->attrs[attr].bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
TAG(render_bind_vertices)(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_unbind_vertices(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < render->attr_count; i++) {
|
||||||
|
int *attr = &render->map[i];
|
||||||
|
|
||||||
|
if (*attr >= 0) {
|
||||||
|
nouveau_bo_ref(NULL, &render->attrs[*attr].bo);
|
||||||
|
*attr = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render->attr_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_flush_vertices(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl;
|
||||||
|
unsigned push, start = 0, count = swtnl->vertex_count;
|
||||||
|
RENDER_LOCALS(ctx);
|
||||||
|
|
||||||
|
swtnl_bind_vertices(ctx);
|
||||||
|
|
||||||
|
while (count) {
|
||||||
|
push = get_max_vertices(ctx, NULL, chan->pushbuf->remaining);
|
||||||
|
push = MIN2(push / 12 * 12, count);
|
||||||
|
count -= push;
|
||||||
|
|
||||||
|
if (!push) {
|
||||||
|
FIRE_RING(chan);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BATCH_BEGIN(nvgl_primitive(swtnl->primitive));
|
||||||
|
EMIT_VBO(L, ctx, start, 0, push);
|
||||||
|
BATCH_END();
|
||||||
|
|
||||||
|
FIRE_RING(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
swtnl_alloc_vertices(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TnL renderer entry points */
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_start(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
swtnl_choose_attrs(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_finish(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
swtnl_flush_vertices(ctx);
|
||||||
|
swtnl_unbind_vertices(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_primitive(GLcontext *ctx, GLenum mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_reset_stipple(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primitive rendering */
|
||||||
|
|
||||||
|
#define BEGIN_PRIMITIVE(p, n) \
|
||||||
|
struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; \
|
||||||
|
int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size; \
|
||||||
|
\
|
||||||
|
if (swtnl->vertex_count + (n) > swtnl->vbo->size/vertex_len \
|
||||||
|
|| (swtnl->vertex_count && swtnl->primitive != p)) \
|
||||||
|
swtnl_flush_vertices(ctx); \
|
||||||
|
\
|
||||||
|
swtnl->primitive = p;
|
||||||
|
|
||||||
|
#define OUT_VERTEX(i) do { \
|
||||||
|
memcpy(swtnl->buf + swtnl->vertex_count * vertex_len, \
|
||||||
|
_tnl_get_vertex(ctx, (i)), vertex_len); \
|
||||||
|
swtnl->vertex_count++; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_points(GLcontext *ctx, GLuint first, GLuint last)
|
||||||
|
{
|
||||||
|
int i, count;
|
||||||
|
|
||||||
|
while (first < last) {
|
||||||
|
BEGIN_PRIMITIVE(GL_POINTS, last - first);
|
||||||
|
|
||||||
|
count = MIN2(swtnl->vbo->size / vertex_len, last - first);
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
OUT_VERTEX(first + i);
|
||||||
|
|
||||||
|
first += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_line(GLcontext *ctx, GLuint v1, GLuint v2)
|
||||||
|
{
|
||||||
|
BEGIN_PRIMITIVE(GL_LINES, 2);
|
||||||
|
OUT_VERTEX(v1);
|
||||||
|
OUT_VERTEX(v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_triangle(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3)
|
||||||
|
{
|
||||||
|
BEGIN_PRIMITIVE(GL_TRIANGLES, 3);
|
||||||
|
OUT_VERTEX(v1);
|
||||||
|
OUT_VERTEX(v2);
|
||||||
|
OUT_VERTEX(v3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_quad(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4)
|
||||||
|
{
|
||||||
|
BEGIN_PRIMITIVE(GL_QUADS, 4);
|
||||||
|
OUT_VERTEX(v1);
|
||||||
|
OUT_VERTEX(v2);
|
||||||
|
OUT_VERTEX(v3);
|
||||||
|
OUT_VERTEX(v4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TnL initialization. */
|
||||||
|
static void
|
||||||
|
TAG(swtnl_init)(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
|
|
||||||
|
tnl->Driver.RunPipeline = _tnl_run_pipeline;
|
||||||
|
tnl->Driver.Render.Interp = _tnl_interp;
|
||||||
|
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
|
||||||
|
tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
|
||||||
|
tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine;
|
||||||
|
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
|
||||||
|
|
||||||
|
tnl->Driver.Render.Start = swtnl_start;
|
||||||
|
tnl->Driver.Render.Finish = swtnl_finish;
|
||||||
|
tnl->Driver.Render.PrimitiveNotify = swtnl_primitive;
|
||||||
|
tnl->Driver.Render.ResetLineStipple = swtnl_reset_stipple;
|
||||||
|
|
||||||
|
tnl->Driver.Render.Points = swtnl_points;
|
||||||
|
tnl->Driver.Render.Line = swtnl_line;
|
||||||
|
tnl->Driver.Render.Triangle = swtnl_triangle;
|
||||||
|
tnl->Driver.Render.Quad = swtnl_quad;
|
||||||
|
|
||||||
|
_tnl_init_vertices(ctx, tnl->vb.Size,
|
||||||
|
NUM_VERTEX_ATTRS * 4 * sizeof(GLfloat));
|
||||||
|
_tnl_need_projected_coords(ctx, GL_FALSE);
|
||||||
|
_tnl_allow_vertex_fog(ctx, GL_FALSE);
|
||||||
|
_tnl_wakeup(ctx);
|
||||||
|
|
||||||
|
swtnl_alloc_vertices(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
TAG(swtnl_destroy)(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
nouveau_bo_ref(NULL, &to_render_state(ctx)->swtnl.vbo);
|
||||||
|
}
|
||||||
456
src/mesa/drivers/dri/nouveau/nouveau_texture.c
Normal file
456
src/mesa/drivers/dri/nouveau/nouveau_texture.c
Normal file
|
|
@ -0,0 +1,456 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_texture.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
|
||||||
|
#include "main/texobj.h"
|
||||||
|
#include "main/texstore.h"
|
||||||
|
#include "main/texformat.h"
|
||||||
|
#include "main/texcompress.h"
|
||||||
|
#include "main/texgetimage.h"
|
||||||
|
#include "main/mipmap.h"
|
||||||
|
#include "main/texfetch.h"
|
||||||
|
|
||||||
|
static struct gl_texture_object *
|
||||||
|
nouveau_texture_new(GLcontext *ctx, GLuint name, GLenum target)
|
||||||
|
{
|
||||||
|
struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture);
|
||||||
|
|
||||||
|
_mesa_initialize_texture_object(&nt->base, name, target);
|
||||||
|
|
||||||
|
return &nt->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_texture_free(GLcontext *ctx, struct gl_texture_object *t)
|
||||||
|
{
|
||||||
|
struct nouveau_texture *nt = to_nouveau_texture(t);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
|
||||||
|
nouveau_surface_ref(NULL, &nt->surfaces[i]);
|
||||||
|
|
||||||
|
_mesa_delete_texture_object(ctx, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct gl_texture_image *
|
||||||
|
nouveau_teximage_new(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage);
|
||||||
|
|
||||||
|
return &nti->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_teximage_free(GLcontext *ctx, struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
struct nouveau_teximage *nti = to_nouveau_teximage(ti);
|
||||||
|
|
||||||
|
nouveau_surface_ref(NULL, &nti->surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_teximage_map(GLcontext *ctx, struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR);
|
||||||
|
assert(!ret);
|
||||||
|
|
||||||
|
ti->Data = s->bo->map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_teximage_unmap(GLcontext *ctx, struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
|
||||||
|
|
||||||
|
nouveau_bo_unmap(s->bo);
|
||||||
|
ti->Data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gl_format
|
||||||
|
nouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat,
|
||||||
|
GLenum srcFormat, GLenum srcType)
|
||||||
|
{
|
||||||
|
switch (internalFormat) {
|
||||||
|
case 4:
|
||||||
|
case GL_RGBA:
|
||||||
|
case GL_RGB10_A2:
|
||||||
|
case GL_RGBA12:
|
||||||
|
case GL_RGBA16:
|
||||||
|
case GL_RGBA8:
|
||||||
|
case GL_RGB:
|
||||||
|
case GL_RGB8:
|
||||||
|
case GL_RGB10:
|
||||||
|
case GL_RGB12:
|
||||||
|
case GL_RGB16:
|
||||||
|
return MESA_FORMAT_ARGB8888;
|
||||||
|
case GL_RGB5_A1:
|
||||||
|
return MESA_FORMAT_ARGB1555;
|
||||||
|
case GL_RGBA2:
|
||||||
|
case GL_RGBA4:
|
||||||
|
return MESA_FORMAT_ARGB4444;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
case GL_R3_G3_B2:
|
||||||
|
case GL_RGB4:
|
||||||
|
case GL_RGB5:
|
||||||
|
return MESA_FORMAT_RGB565;
|
||||||
|
|
||||||
|
case GL_ALPHA:
|
||||||
|
case GL_ALPHA4:
|
||||||
|
case GL_ALPHA12:
|
||||||
|
case GL_ALPHA16:
|
||||||
|
case GL_ALPHA8:
|
||||||
|
return MESA_FORMAT_A8;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case GL_LUMINANCE:
|
||||||
|
case GL_LUMINANCE4:
|
||||||
|
case GL_LUMINANCE12:
|
||||||
|
case GL_LUMINANCE16:
|
||||||
|
case GL_LUMINANCE8:
|
||||||
|
return MESA_FORMAT_L8;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
case GL_LUMINANCE_ALPHA:
|
||||||
|
case GL_LUMINANCE4_ALPHA4:
|
||||||
|
case GL_LUMINANCE6_ALPHA2:
|
||||||
|
case GL_LUMINANCE12_ALPHA4:
|
||||||
|
case GL_LUMINANCE12_ALPHA12:
|
||||||
|
case GL_LUMINANCE16_ALPHA16:
|
||||||
|
case GL_LUMINANCE8_ALPHA8:
|
||||||
|
return MESA_FORMAT_ARGB8888;
|
||||||
|
|
||||||
|
case GL_INTENSITY:
|
||||||
|
case GL_INTENSITY4:
|
||||||
|
case GL_INTENSITY12:
|
||||||
|
case GL_INTENSITY16:
|
||||||
|
case GL_INTENSITY8:
|
||||||
|
return MESA_FORMAT_ARGB8888;
|
||||||
|
|
||||||
|
case GL_COLOR_INDEX:
|
||||||
|
case GL_COLOR_INDEX1_EXT:
|
||||||
|
case GL_COLOR_INDEX2_EXT:
|
||||||
|
case GL_COLOR_INDEX4_EXT:
|
||||||
|
case GL_COLOR_INDEX12_EXT:
|
||||||
|
case GL_COLOR_INDEX16_EXT:
|
||||||
|
case GL_COLOR_INDEX8_EXT:
|
||||||
|
return MESA_FORMAT_CI8;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_teximage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint height, GLint depth, GLint border,
|
||||||
|
GLenum format, GLenum type, const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *t,
|
||||||
|
struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
|
||||||
|
unsigned bo_flags = NOUVEAU_BO_GART | NOUVEAU_BO_RDWR | NOUVEAU_BO_MAP;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Allocate a new bo for the image. */
|
||||||
|
nouveau_surface_alloc(ctx, s, LINEAR, bo_flags, ti->TexFormat,
|
||||||
|
width, height);
|
||||||
|
ti->RowStride = s->pitch / s->cpp;
|
||||||
|
|
||||||
|
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
|
||||||
|
format, type, pixels, packing,
|
||||||
|
"glTexImage");
|
||||||
|
if (!pixels)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Store the pixel data. */
|
||||||
|
nouveau_teximage_map(ctx, ti);
|
||||||
|
|
||||||
|
ret = _mesa_texstore(ctx, dims, ti->_BaseFormat,
|
||||||
|
ti->TexFormat, ti->Data,
|
||||||
|
0, 0, 0, s->pitch,
|
||||||
|
ti->ImageOffsets,
|
||||||
|
width, height, depth,
|
||||||
|
format, type, pixels, packing);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
nouveau_teximage_unmap(ctx, ti);
|
||||||
|
_mesa_unmap_teximage_pbo(ctx, packing);
|
||||||
|
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||||
|
context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
|
||||||
|
texture_dirty(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_teximage_1d(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint border,
|
||||||
|
GLenum format, GLenum type, const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *t,
|
||||||
|
struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
nouveau_teximage(ctx, 1, target, level, internalFormat,
|
||||||
|
width, 1, 1, border, format, type, pixels,
|
||||||
|
packing, t, ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_teximage_2d(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint height, GLint border,
|
||||||
|
GLenum format, GLenum type, const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *t,
|
||||||
|
struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
nouveau_teximage(ctx, 2, target, level, internalFormat,
|
||||||
|
width, height, 1, border, format, type, pixels,
|
||||||
|
packing, t, ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_teximage_3d(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint height, GLint depth, GLint border,
|
||||||
|
GLenum format, GLenum type, const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *t,
|
||||||
|
struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
nouveau_teximage(ctx, 3, target, level, internalFormat,
|
||||||
|
width, height, depth, border, format, type, pixels,
|
||||||
|
packing, t, ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_texsubimage_3d(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||||
|
GLint width, GLint height, GLint depth,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *t,
|
||||||
|
struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
nouveau_teximage_map(ctx, ti);
|
||||||
|
_mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
|
||||||
|
width, height, depth, format, type, pixels,
|
||||||
|
packing, t, ti);
|
||||||
|
nouveau_teximage_unmap(ctx, ti);
|
||||||
|
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||||
|
texture_dirty(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_texsubimage_2d(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint xoffset, GLint yoffset,
|
||||||
|
GLint width, GLint height,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *t,
|
||||||
|
struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
nouveau_teximage_map(ctx, ti);
|
||||||
|
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset,
|
||||||
|
width, height, format, type, pixels,
|
||||||
|
packing, t, ti);
|
||||||
|
nouveau_teximage_unmap(ctx, ti);
|
||||||
|
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||||
|
texture_dirty(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_texsubimage_1d(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint xoffset, GLint width,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *t,
|
||||||
|
struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
nouveau_teximage_map(ctx, ti);
|
||||||
|
_mesa_store_texsubimage1d(ctx, target, level, xoffset,
|
||||||
|
width, format, type, pixels,
|
||||||
|
packing, t, ti);
|
||||||
|
nouveau_teximage_unmap(ctx, ti);
|
||||||
|
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||||
|
texture_dirty(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_get_teximage(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLenum format, GLenum type, GLvoid *pixels,
|
||||||
|
struct gl_texture_object *t,
|
||||||
|
struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
nouveau_teximage_map(ctx, ti);
|
||||||
|
_mesa_get_teximage(ctx, target, level, format, type, pixels,
|
||||||
|
t, ti);
|
||||||
|
nouveau_teximage_unmap(ctx, ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_bind_texture(GLcontext *ctx, GLenum target,
|
||||||
|
struct gl_texture_object *t)
|
||||||
|
{
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit);
|
||||||
|
context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_texture_map(GLcontext *ctx, struct gl_texture_object *t)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
|
||||||
|
if (t->Image[0][i])
|
||||||
|
nouveau_teximage_map(ctx, t->Image[0][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nouveau_texture_unmap(GLcontext *ctx, struct gl_texture_object *t)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = t->BaseLevel; i < t->_MaxLevel; i++) {
|
||||||
|
if (t->Image[0][i])
|
||||||
|
nouveau_teximage_unmap(ctx, t->Image[0][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
relayout_miptree(GLcontext *ctx, struct gl_texture_object *t)
|
||||||
|
{
|
||||||
|
struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces;
|
||||||
|
unsigned last_level, offset = 0;
|
||||||
|
unsigned size;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
if (t->MinFilter == GL_NEAREST ||
|
||||||
|
t->MinFilter == GL_LINEAR)
|
||||||
|
last_level = t->BaseLevel;
|
||||||
|
else
|
||||||
|
last_level = t->_MaxLevel;
|
||||||
|
|
||||||
|
/* Deallocate the old storage. */
|
||||||
|
for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
|
||||||
|
nouveau_bo_ref(NULL, &ss[i].bo);
|
||||||
|
|
||||||
|
/* Relayout the mipmap tree. */
|
||||||
|
for (i = t->BaseLevel; i <= last_level; i++) {
|
||||||
|
struct nouveau_surface *s =
|
||||||
|
&to_nouveau_teximage(t->Image[0][i])->surface;
|
||||||
|
|
||||||
|
size = s->width * s->height * s->cpp;
|
||||||
|
|
||||||
|
/* Images larger than 16B have to be aligned. */
|
||||||
|
if (size > 16)
|
||||||
|
offset = align(offset, 64);
|
||||||
|
|
||||||
|
ss[i] = (struct nouveau_surface) {
|
||||||
|
.offset = offset,
|
||||||
|
.layout = SWIZZLED,
|
||||||
|
.format = s->format,
|
||||||
|
.width = s->width,
|
||||||
|
.height = s->height,
|
||||||
|
.cpp = s->cpp,
|
||||||
|
.pitch = s->width * s->cpp,
|
||||||
|
};
|
||||||
|
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get new storage. */
|
||||||
|
size = align(offset, 64);
|
||||||
|
|
||||||
|
ret = nouveau_bo_new(context_dev(ctx),
|
||||||
|
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM,
|
||||||
|
0, size, &ss[last_level].bo);
|
||||||
|
assert(!ret);
|
||||||
|
|
||||||
|
for (i = t->BaseLevel; i < last_level; i++)
|
||||||
|
nouveau_bo_ref(ss[last_level].bo, &ss[i].bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t)
|
||||||
|
{
|
||||||
|
struct nouveau_texture *nt = to_nouveau_texture(t);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!nt->dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nt->dirty = GL_FALSE;
|
||||||
|
|
||||||
|
relayout_miptree(ctx, t);
|
||||||
|
|
||||||
|
/* Copy the teximages to the actual swizzled miptree. */
|
||||||
|
for (i = t->BaseLevel; i < MAX_TEXTURE_LEVELS; i++) {
|
||||||
|
struct gl_texture_image *ti = t->Image[0][i];
|
||||||
|
struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface;
|
||||||
|
|
||||||
|
if (!nt->surfaces[i].bo)
|
||||||
|
break;
|
||||||
|
|
||||||
|
context_drv(ctx)->surface_copy(ctx, &nt->surfaces[i], s,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
s->width, s->height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_texture_functions_init(struct dd_function_table *functions)
|
||||||
|
{
|
||||||
|
functions->NewTextureObject = nouveau_texture_new;
|
||||||
|
functions->DeleteTexture = nouveau_texture_free;
|
||||||
|
functions->NewTextureImage = nouveau_teximage_new;
|
||||||
|
functions->FreeTexImageData = nouveau_teximage_free;
|
||||||
|
functions->ChooseTextureFormat = nouveau_choose_tex_format;
|
||||||
|
functions->TexImage1D = nouveau_teximage_1d;
|
||||||
|
functions->TexImage2D = nouveau_teximage_2d;
|
||||||
|
functions->TexImage3D = nouveau_teximage_3d;
|
||||||
|
functions->TexSubImage1D = nouveau_texsubimage_1d;
|
||||||
|
functions->TexSubImage2D = nouveau_texsubimage_2d;
|
||||||
|
functions->TexSubImage3D = nouveau_texsubimage_3d;
|
||||||
|
functions->GetTexImage = nouveau_get_teximage;
|
||||||
|
functions->BindTexture = nouveau_bind_texture;
|
||||||
|
functions->MapTexture = nouveau_texture_map;
|
||||||
|
functions->UnmapTexture = nouveau_texture_unmap;
|
||||||
|
}
|
||||||
49
src/mesa/drivers/dri/nouveau/nouveau_texture.h
Normal file
49
src/mesa/drivers/dri/nouveau/nouveau_texture.h
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_TEXTURE_H__
|
||||||
|
#define __NOUVEAU_TEXTURE_H__
|
||||||
|
|
||||||
|
struct nouveau_teximage {
|
||||||
|
struct gl_texture_image base;
|
||||||
|
struct nouveau_surface surface;
|
||||||
|
};
|
||||||
|
#define to_nouveau_teximage(x) ((struct nouveau_teximage *)(x))
|
||||||
|
|
||||||
|
struct nouveau_texture {
|
||||||
|
struct gl_texture_object base;
|
||||||
|
struct nouveau_surface surfaces[MAX_TEXTURE_LEVELS];
|
||||||
|
GLboolean dirty;
|
||||||
|
};
|
||||||
|
#define to_nouveau_texture(x) ((struct nouveau_texture *)(x))
|
||||||
|
|
||||||
|
#define texture_dirty(t) \
|
||||||
|
to_nouveau_texture(t)->dirty = GL_TRUE;
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t);
|
||||||
|
|
||||||
|
#endif
|
||||||
176
src/mesa/drivers/dri/nouveau/nouveau_util.h
Normal file
176
src/mesa/drivers/dri/nouveau/nouveau_util.h
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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_UTIL_H__
|
||||||
|
#define __NOUVEAU_UTIL_H__
|
||||||
|
|
||||||
|
#include "main/formats.h"
|
||||||
|
#include "main/colormac.h"
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
pack_rgba_i(gl_format f, uint8_t c[])
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case MESA_FORMAT_ARGB8888:
|
||||||
|
return PACK_COLOR_8888(c[ACOMP], c[RCOMP], c[GCOMP], c[BCOMP]);
|
||||||
|
case MESA_FORMAT_ARGB8888_REV:
|
||||||
|
return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], c[ACOMP]);
|
||||||
|
case MESA_FORMAT_XRGB8888:
|
||||||
|
return PACK_COLOR_8888(0, c[RCOMP], c[GCOMP], c[BCOMP]);
|
||||||
|
case MESA_FORMAT_XRGB8888_REV:
|
||||||
|
return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], 0);
|
||||||
|
case MESA_FORMAT_RGBA8888:
|
||||||
|
return PACK_COLOR_8888(c[RCOMP], c[GCOMP], c[BCOMP], c[ACOMP]);
|
||||||
|
case MESA_FORMAT_RGBA8888_REV:
|
||||||
|
return PACK_COLOR_8888(c[ACOMP], c[BCOMP], c[GCOMP], c[RCOMP]);
|
||||||
|
case MESA_FORMAT_RGB565:
|
||||||
|
return PACK_COLOR_565(c[RCOMP], c[GCOMP], c[BCOMP]);
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
pack_zs_i(gl_format f, uint32_t z, uint8_t s)
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case MESA_FORMAT_Z24_S8:
|
||||||
|
return (z & 0xffffff00) | (s & 0xff);
|
||||||
|
case MESA_FORMAT_Z24_X8:
|
||||||
|
return (z & 0xffffff00);
|
||||||
|
case MESA_FORMAT_Z16:
|
||||||
|
return (z & 0xffff0000) >> 16;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
pack_rgba_f(gl_format f, float c[])
|
||||||
|
{
|
||||||
|
return pack_rgba_i(f, (uint8_t []) {
|
||||||
|
FLOAT_TO_UBYTE(c[RCOMP]),
|
||||||
|
FLOAT_TO_UBYTE(c[GCOMP]),
|
||||||
|
FLOAT_TO_UBYTE(c[BCOMP]),
|
||||||
|
FLOAT_TO_UBYTE(c[ACOMP]) });
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
pack_zs_f(gl_format f, float z, uint8_t s)
|
||||||
|
{
|
||||||
|
return pack_zs_i(f, FLOAT_TO_UINT(z), s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Integer base-2 logarithm, rounded towards zero. */
|
||||||
|
static inline unsigned
|
||||||
|
log2i(unsigned i)
|
||||||
|
{
|
||||||
|
unsigned r = 0;
|
||||||
|
|
||||||
|
if (i & 0xffff0000) {
|
||||||
|
i >>= 16;
|
||||||
|
r += 16;
|
||||||
|
}
|
||||||
|
if (i & 0x0000ff00) {
|
||||||
|
i >>= 8;
|
||||||
|
r += 8;
|
||||||
|
}
|
||||||
|
if (i & 0x000000f0) {
|
||||||
|
i >>= 4;
|
||||||
|
r += 4;
|
||||||
|
}
|
||||||
|
if (i & 0x0000000c) {
|
||||||
|
i >>= 2;
|
||||||
|
r += 2;
|
||||||
|
}
|
||||||
|
if (i & 0x00000002) {
|
||||||
|
r += 1;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
align(unsigned x, unsigned m)
|
||||||
|
{
|
||||||
|
return (x + m - 1) & ~(m - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
get_scissors(struct gl_framebuffer *fb, int *x, int *y, int *w, int *h)
|
||||||
|
{
|
||||||
|
*w = fb->_Xmax - fb->_Xmin;
|
||||||
|
*h = fb->_Ymax - fb->_Ymin;
|
||||||
|
*x = fb->_Xmin;
|
||||||
|
*y = (fb->Name ? fb->_Ymin :
|
||||||
|
/* Window system FBO: Flip the Y coordinate. */
|
||||||
|
fb->Height - fb->_Ymax);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
get_viewport_scale(GLcontext *ctx, float a[16])
|
||||||
|
{
|
||||||
|
struct gl_viewport_attrib *vp = &ctx->Viewport;
|
||||||
|
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||||
|
|
||||||
|
a[MAT_SX] = (float)vp->Width / 2;
|
||||||
|
|
||||||
|
if (fb->Name)
|
||||||
|
a[MAT_SY] = (float)vp->Height / 2;
|
||||||
|
else
|
||||||
|
/* Window system FBO: Flip the Y coordinate. */
|
||||||
|
a[MAT_SY] = - (float)vp->Height / 2;
|
||||||
|
|
||||||
|
a[MAT_SZ] = fb->_DepthMaxF * (vp->Far - vp->Near) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
get_viewport_translate(GLcontext *ctx, float a[4])
|
||||||
|
{
|
||||||
|
struct gl_viewport_attrib *vp = &ctx->Viewport;
|
||||||
|
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||||
|
|
||||||
|
a[0] = (float)vp->Width / 2 + vp->X;
|
||||||
|
|
||||||
|
if (fb->Name)
|
||||||
|
a[1] = (float)vp->Height / 2 + vp->Y;
|
||||||
|
else
|
||||||
|
/* Window system FBO: Flip the Y coordinate. */
|
||||||
|
a[1] = fb->Height - (float)vp->Height / 2 - vp->Y;
|
||||||
|
|
||||||
|
a[2] = fb->_DepthMaxF * (vp->Far + vp->Near) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
OUT_RINGm(struct nouveau_channel *chan, float m[16])
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
OUT_RINGf(chan, m[4*j + i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
409
src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
Normal file
409
src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c
Normal file
|
|
@ -0,0 +1,409 @@
|
||||||
|
/*
|
||||||
|
* 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_bufferobj.h"
|
||||||
|
|
||||||
|
/* Arbitrary pushbuf length we can assume we can get with a single
|
||||||
|
* WAIT_RING. */
|
||||||
|
#define PUSHBUF_DWORDS 2048
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
a->buf = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbo_init_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib,
|
||||||
|
const struct gl_client_array **arrays)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (ib)
|
||||||
|
vbo_init_array(&render->ib, 0, 0, ib->count, ib->type,
|
||||||
|
ib->obj, ib->ptr, GL_TRUE);
|
||||||
|
|
||||||
|
for (i = 0; i < render->attr_count; i++) {
|
||||||
|
int attr = render->map[i];
|
||||||
|
|
||||||
|
if (attr >= 0) {
|
||||||
|
const struct gl_client_array *array = arrays[attr];
|
||||||
|
|
||||||
|
vbo_init_array(&render->attrs[attr], attr,
|
||||||
|
array->StrideB, array->Size,
|
||||||
|
array->Type, array->BufferObj,
|
||||||
|
array->Ptr, render->mode == IMM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbo_deinit_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib,
|
||||||
|
const struct gl_client_array **arrays)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (ib)
|
||||||
|
vbo_deinit_array(&render->ib);
|
||||||
|
|
||||||
|
for (i = 0; i < render->attr_count; i++) {
|
||||||
|
int *attr = &render->map[i];
|
||||||
|
|
||||||
|
if (*attr >= 0) {
|
||||||
|
vbo_deinit_array(&render->attrs[*attr]);
|
||||||
|
*attr = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render->attr_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make some rendering decisions from the GL context. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbo_choose_render_mode(GLcontext *ctx, const struct gl_client_array **arrays)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
render->mode = VBO;
|
||||||
|
|
||||||
|
if (ctx->Light.Enabled) {
|
||||||
|
for (i = 0; i < MAT_ATTRIB_MAX; i++) {
|
||||||
|
if (arrays[VERT_ATTRIB_GENERIC0 + i]->StrideB) {
|
||||||
|
render->mode = IMM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (render->mode == VBO)
|
||||||
|
render->attr_count = NUM_VERTEX_ATTRS;
|
||||||
|
else
|
||||||
|
render->attr_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbo_emit_attr(GLcontext *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];
|
||||||
|
RENDER_LOCALS(ctx);
|
||||||
|
|
||||||
|
if (!array->StrideB) {
|
||||||
|
if (attr >= VERT_ATTRIB_GENERIC0)
|
||||||
|
/* nouveau_update_state takes care of materials. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Constant attribute. */
|
||||||
|
vbo_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);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Varying attribute. */
|
||||||
|
struct nouveau_attr_info *info = &TAG(vertex_attrs)[attr];
|
||||||
|
|
||||||
|
if (render->mode == VBO) {
|
||||||
|
render->map[info->vbo_index] = attr;
|
||||||
|
render->vertex_size += array->_ElementSize;
|
||||||
|
} else {
|
||||||
|
render->map[render->attr_count++] = attr;
|
||||||
|
render->vertex_size += 4 * info->imm_fields;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAT(a) (VERT_ATTRIB_GENERIC0 + MAT_ATTRIB_##a)
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbo_choose_attrs(GLcontext *ctx, const struct gl_client_array **arrays)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Reset the vertex size. */
|
||||||
|
render->vertex_size = 0;
|
||||||
|
|
||||||
|
vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR0);
|
||||||
|
if (ctx->Fog.ColorSumEnabled && !ctx->Light.Enabled)
|
||||||
|
vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR1);
|
||||||
|
|
||||||
|
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
|
||||||
|
if (ctx->Texture._EnabledCoordUnits & (1 << i))
|
||||||
|
vbo_emit_attr(ctx, arrays, VERT_ATTRIB_TEX0 + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->Fog.Enabled && ctx->Fog.FogCoordinateSource == GL_FOG_COORD)
|
||||||
|
vbo_emit_attr(ctx, arrays, VERT_ATTRIB_FOG);
|
||||||
|
|
||||||
|
if (ctx->Light.Enabled) {
|
||||||
|
vbo_emit_attr(ctx, arrays, VERT_ATTRIB_NORMAL);
|
||||||
|
|
||||||
|
vbo_emit_attr(ctx, arrays, MAT(FRONT_AMBIENT));
|
||||||
|
vbo_emit_attr(ctx, arrays, MAT(FRONT_DIFFUSE));
|
||||||
|
vbo_emit_attr(ctx, arrays, MAT(FRONT_SPECULAR));
|
||||||
|
vbo_emit_attr(ctx, arrays, MAT(FRONT_SHININESS));
|
||||||
|
|
||||||
|
if (ctx->Light.Model.TwoSide) {
|
||||||
|
vbo_emit_attr(ctx, arrays, MAT(BACK_AMBIENT));
|
||||||
|
vbo_emit_attr(ctx, arrays, MAT(BACK_DIFFUSE));
|
||||||
|
vbo_emit_attr(ctx, arrays, MAT(BACK_SPECULAR));
|
||||||
|
vbo_emit_attr(ctx, arrays, MAT(BACK_SHININESS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vbo_emit_attr(ctx, arrays, VERT_ATTRIB_POS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
TAG(vbo_render_prims)(GLcontext *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,
|
||||||
|
GLuint min_index, GLuint max_index);
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
vbo_maybe_split(GLcontext *ctx, const struct gl_client_array **arrays,
|
||||||
|
const struct _mesa_prim *prims, GLuint nr_prims,
|
||||||
|
const struct _mesa_index_buffer *ib,
|
||||||
|
GLuint min_index, GLuint max_index)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx = to_nouveau_context(ctx);
|
||||||
|
unsigned pushbuf_avail = PUSHBUF_DWORDS - 2 * nctx->bo.count,
|
||||||
|
vert_avail = get_max_vertices(ctx, NULL, pushbuf_avail),
|
||||||
|
idx_avail = get_max_vertices(ctx, ib, pushbuf_avail);
|
||||||
|
|
||||||
|
if ((ib && ib->count > idx_avail) ||
|
||||||
|
(!ib && max_index - min_index > vert_avail)) {
|
||||||
|
struct split_limits limits = {
|
||||||
|
.max_verts = vert_avail,
|
||||||
|
.max_indices = idx_avail,
|
||||||
|
.max_vb_size = ~0,
|
||||||
|
};
|
||||||
|
|
||||||
|
vbo_split_prims(ctx, arrays, prims, nr_prims, ib, min_index,
|
||||||
|
max_index, TAG(vbo_render_prims), &limits);
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VBO rendering path. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbo_bind_vertices(GLcontext *ctx, const struct gl_client_array **arrays,
|
||||||
|
GLint basevertex, GLuint min_index, GLuint max_index)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_VERTEX_ATTRS; i++) {
|
||||||
|
int attr = render->map[i];
|
||||||
|
|
||||||
|
if (attr >= 0) {
|
||||||
|
const struct gl_client_array *array = arrays[attr];
|
||||||
|
struct nouveau_array_state *a = &render->attrs[attr];
|
||||||
|
unsigned delta = (basevertex + min_index) * a->stride,
|
||||||
|
size = (max_index - min_index + 1) * a->stride;
|
||||||
|
|
||||||
|
if (a->bo) {
|
||||||
|
a->offset = (intptr_t)array->Ptr + delta;
|
||||||
|
} else {
|
||||||
|
void *scratch = get_scratch_vbo(ctx, size,
|
||||||
|
&a->bo,
|
||||||
|
&a->offset);
|
||||||
|
|
||||||
|
memcpy(scratch, a->buf + delta, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TAG(render_bind_vertices)(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbo_draw_vbo(GLcontext *ctx, const struct gl_client_array **arrays,
|
||||||
|
const struct _mesa_prim *prims, GLuint nr_prims,
|
||||||
|
const struct _mesa_index_buffer *ib, GLuint min_index,
|
||||||
|
GLuint max_index)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
dispatch_t dispatch;
|
||||||
|
int delta = -min_index, basevertex = 0, i;
|
||||||
|
RENDER_LOCALS(ctx);
|
||||||
|
|
||||||
|
get_array_dispatch(&to_render_state(ctx)->ib, &dispatch);
|
||||||
|
|
||||||
|
TAG(render_set_format)(ctx);
|
||||||
|
|
||||||
|
for (i = 0; i < nr_prims; i++) {
|
||||||
|
unsigned start = prims[i].start,
|
||||||
|
count = prims[i].count;
|
||||||
|
|
||||||
|
if (i == 0 || basevertex != prims[i].basevertex) {
|
||||||
|
basevertex = prims[i].basevertex;
|
||||||
|
vbo_bind_vertices(ctx, arrays, basevertex,
|
||||||
|
min_index, max_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > get_max_vertices(ctx, ib, chan->pushbuf->remaining))
|
||||||
|
WAIT_RING(chan, PUSHBUF_DWORDS);
|
||||||
|
|
||||||
|
BATCH_BEGIN(nvgl_primitive(prims[i].mode));
|
||||||
|
dispatch(ctx, start, delta, count);
|
||||||
|
BATCH_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
FIRE_RING(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Immediate rendering path. */
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
extract_id(struct nouveau_array_state *a, int i, int j)
|
||||||
|
{
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbo_draw_imm(GLcontext *ctx, const struct gl_client_array **arrays,
|
||||||
|
const struct _mesa_prim *prims, GLuint nr_prims,
|
||||||
|
const struct _mesa_index_buffer *ib, GLuint min_index,
|
||||||
|
GLuint max_index)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
extract_u_t extract = ib ? render->ib.extract_u : extract_id;
|
||||||
|
int i, j, k;
|
||||||
|
RENDER_LOCALS(ctx);
|
||||||
|
|
||||||
|
for (i = 0; i < nr_prims; i++) {
|
||||||
|
unsigned start = prims[i].start,
|
||||||
|
end = start + prims[i].count;
|
||||||
|
|
||||||
|
if (prims[i].count > get_max_vertices(ctx, ib,
|
||||||
|
chan->pushbuf->remaining))
|
||||||
|
WAIT_RING(chan, PUSHBUF_DWORDS);
|
||||||
|
|
||||||
|
BATCH_BEGIN(nvgl_primitive(prims[i].mode));
|
||||||
|
|
||||||
|
for (; start < end; start++) {
|
||||||
|
j = prims[i].basevertex +
|
||||||
|
extract(&render->ib, 0, start);
|
||||||
|
|
||||||
|
for (k = 0; k < render->attr_count; k++)
|
||||||
|
EMIT_IMM(ctx, &render->attrs[render->map[k]],
|
||||||
|
j);
|
||||||
|
}
|
||||||
|
|
||||||
|
BATCH_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
FIRE_RING(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw_prims entry point when we're doing hw-tnl. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
TAG(vbo_render_prims)(GLcontext *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,
|
||||||
|
GLuint min_index, GLuint max_index)
|
||||||
|
{
|
||||||
|
struct nouveau_render_state *render = to_render_state(ctx);
|
||||||
|
|
||||||
|
if (!index_bounds_valid)
|
||||||
|
vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
|
||||||
|
|
||||||
|
vbo_choose_render_mode(ctx, arrays);
|
||||||
|
vbo_choose_attrs(ctx, arrays);
|
||||||
|
|
||||||
|
if (vbo_maybe_split(ctx, arrays, prims, nr_prims, ib, min_index,
|
||||||
|
max_index))
|
||||||
|
return;
|
||||||
|
|
||||||
|
vbo_init_arrays(ctx, ib, arrays);
|
||||||
|
|
||||||
|
if (render->mode == VBO)
|
||||||
|
vbo_draw_vbo(ctx, arrays, prims, nr_prims, ib, min_index,
|
||||||
|
max_index);
|
||||||
|
else
|
||||||
|
vbo_draw_imm(ctx, arrays, prims, nr_prims, ib, min_index,
|
||||||
|
max_index);
|
||||||
|
|
||||||
|
vbo_deinit_arrays(ctx, ib, arrays);
|
||||||
|
}
|
||||||
118
src/mesa/drivers/dri/nouveau/nv04_context.c
Normal file
118
src/mesa/drivers/dri/nouveau/nv04_context.c
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_fbo.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
#include "nouveau_class.h"
|
||||||
|
#include "nv04_driver.h"
|
||||||
|
|
||||||
|
struct nouveau_grobj *
|
||||||
|
nv04_context_engine(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nv04_context *nctx = to_nv04_context(ctx);
|
||||||
|
struct nouveau_screen *screen = nctx->base.screen;
|
||||||
|
struct nouveau_grobj *fahrenheit;
|
||||||
|
|
||||||
|
if (ctx->Texture.Unit[0].EnvMode == GL_COMBINE ||
|
||||||
|
ctx->Texture.Unit[0].EnvMode == GL_BLEND ||
|
||||||
|
ctx->Texture.Unit[1]._ReallyEnabled ||
|
||||||
|
ctx->Stencil.Enabled)
|
||||||
|
fahrenheit = screen->eng3dm;
|
||||||
|
else
|
||||||
|
fahrenheit = screen->eng3d;
|
||||||
|
|
||||||
|
if (fahrenheit != nctx->eng3d) {
|
||||||
|
nctx->eng3d = fahrenheit;
|
||||||
|
|
||||||
|
if (nv04_mtex_engine(fahrenheit)) {
|
||||||
|
context_dirty_i(ctx, TEX_ENV, 0);
|
||||||
|
context_dirty_i(ctx, TEX_ENV, 1);
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, 0);
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, 1);
|
||||||
|
context_dirty(ctx, CONTROL);
|
||||||
|
context_dirty(ctx, BLEND);
|
||||||
|
} else {
|
||||||
|
context_bctx_i(ctx, TEXTURE, 1);
|
||||||
|
context_dirty_i(ctx, TEX_ENV, 0);
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, 0);
|
||||||
|
context_dirty(ctx, CONTROL);
|
||||||
|
context_dirty(ctx, BLEND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fahrenheit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_dummy_texture(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_surface *s = &to_nv04_context(ctx)->dummy_texture;
|
||||||
|
|
||||||
|
nouveau_surface_alloc(ctx, s, SWIZZLED,
|
||||||
|
NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM,
|
||||||
|
MESA_FORMAT_ARGB8888, 1, 1);
|
||||||
|
|
||||||
|
nouveau_bo_map(s->bo, NOUVEAU_BO_WR);
|
||||||
|
*(uint32_t *)s->bo->map = 0xffffffff;
|
||||||
|
nouveau_bo_unmap(s->bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLcontext *
|
||||||
|
nv04_context_create(struct nouveau_screen *screen, const GLvisual *visual,
|
||||||
|
GLcontext *share_ctx)
|
||||||
|
{
|
||||||
|
struct nv04_context *nctx;
|
||||||
|
GLcontext *ctx;
|
||||||
|
|
||||||
|
nctx = CALLOC_STRUCT(nv04_context);
|
||||||
|
if (!nctx)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctx = &nctx->base.base;
|
||||||
|
nouveau_context_init(ctx, screen, visual, share_ctx);
|
||||||
|
|
||||||
|
ctx->Const.MaxTextureCoordUnits = NV04_TEXTURE_UNITS;
|
||||||
|
ctx->Const.MaxTextureImageUnits = NV04_TEXTURE_UNITS;
|
||||||
|
ctx->Const.MaxTextureUnits = NV04_TEXTURE_UNITS;
|
||||||
|
ctx->Const.MaxTextureMaxAnisotropy = 2;
|
||||||
|
ctx->Const.MaxTextureLodBias = 15;
|
||||||
|
|
||||||
|
init_dummy_texture(ctx);
|
||||||
|
nv04_render_init(ctx);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_context_destroy(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
nv04_render_destroy(ctx);
|
||||||
|
nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture);
|
||||||
|
|
||||||
|
FREE(ctx);
|
||||||
|
}
|
||||||
52
src/mesa/drivers/dri/nouveau/nv04_context.h
Normal file
52
src/mesa/drivers/dri/nouveau/nv04_context.h
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 __NV04_CONTEXT_H__
|
||||||
|
#define __NV04_CONTEXT_H__
|
||||||
|
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
|
||||||
|
struct nv04_context {
|
||||||
|
struct nouveau_context base;
|
||||||
|
struct nouveau_grobj *eng3d;
|
||||||
|
struct nouveau_surface dummy_texture;
|
||||||
|
float viewport[16];
|
||||||
|
};
|
||||||
|
#define to_nv04_context(ctx) ((struct nv04_context *)(ctx))
|
||||||
|
|
||||||
|
#define nv04_mtex_engine(obj) ((obj)->grclass == NV04_MULTITEX_TRIANGLE)
|
||||||
|
|
||||||
|
struct nouveau_grobj *
|
||||||
|
nv04_context_engine(GLcontext *ctx);
|
||||||
|
|
||||||
|
GLcontext *
|
||||||
|
nv04_context_create(struct nouveau_screen *screen, const GLvisual *visual,
|
||||||
|
GLcontext *share_ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_context_destroy(GLcontext *ctx);
|
||||||
|
|
||||||
|
#endif
|
||||||
97
src/mesa/drivers/dri/nouveau/nv04_driver.h
Normal file
97
src/mesa/drivers/dri/nouveau/nv04_driver.h
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 __NV04_DRIVER_H__
|
||||||
|
#define __NV04_DRIVER_H__
|
||||||
|
|
||||||
|
#include "nv04_context.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NOUVEAU_STATE_BLEND = NUM_NOUVEAU_STATE,
|
||||||
|
NOUVEAU_STATE_CONTROL,
|
||||||
|
NUM_NV04_STATE
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NV04_TEXTURE_UNITS 2
|
||||||
|
|
||||||
|
/* nv04_screen.c */
|
||||||
|
GLboolean
|
||||||
|
nv04_screen_init(struct nouveau_screen *screen);
|
||||||
|
|
||||||
|
/* nv04_render.c */
|
||||||
|
void
|
||||||
|
nv04_render_init(GLcontext *ctx);
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_render_destroy(GLcontext *ctx);
|
||||||
|
|
||||||
|
/* nv04_surface.c */
|
||||||
|
GLboolean
|
||||||
|
nv04_surface_init(struct nouveau_screen *screen);
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_surface_takedown(struct nouveau_screen *screen);
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_surface_copy(GLcontext *ctx,
|
||||||
|
struct nouveau_surface *dst, struct nouveau_surface *src,
|
||||||
|
int dx, int dy, int sx, int sy, int w, int h);
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_surface_fill(GLcontext *ctx,
|
||||||
|
struct nouveau_surface *dst,
|
||||||
|
unsigned mask, unsigned value,
|
||||||
|
int dx, int dy, int w, int h);
|
||||||
|
|
||||||
|
/* nv04_state_fb.c */
|
||||||
|
void
|
||||||
|
nv04_emit_framebuffer(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_emit_scissor(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
/* nv04_state_raster.c */
|
||||||
|
void
|
||||||
|
nv04_defer_control(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_emit_control(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_defer_blend(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_emit_blend(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
/* nv04_state_frag.c */
|
||||||
|
void
|
||||||
|
nv04_emit_tex_env(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
/* nv04_state_tex.c */
|
||||||
|
void
|
||||||
|
nv04_emit_tex_obj(GLcontext *ctx, int emit);
|
||||||
|
|
||||||
|
#endif
|
||||||
212
src/mesa/drivers/dri/nouveau/nv04_render.c
Normal file
212
src/mesa/drivers/dri/nouveau/nv04_render.c
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
#include "nouveau_class.h"
|
||||||
|
#include "nv04_driver.h"
|
||||||
|
|
||||||
|
#include "tnl/tnl.h"
|
||||||
|
#include "tnl/t_pipeline.h"
|
||||||
|
#include "tnl/t_vertex.h"
|
||||||
|
|
||||||
|
#define NUM_VERTEX_ATTRS 6
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_update_viewport(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
float *viewport = to_nv04_context(ctx)->viewport;
|
||||||
|
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||||
|
|
||||||
|
get_viewport_scale(ctx, viewport);
|
||||||
|
get_viewport_translate(ctx, &viewport[MAT_TX]);
|
||||||
|
|
||||||
|
/* It wants normalized Z coordinates. */
|
||||||
|
viewport[MAT_SZ] /= fb->_DepthMaxF;
|
||||||
|
viewport[MAT_TZ] /= fb->_DepthMaxF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_emit_attr(GLcontext *ctx, struct tnl_attr_map *m, int attr, int emit)
|
||||||
|
{
|
||||||
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
|
|
||||||
|
if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, attr))
|
||||||
|
*m = (struct tnl_attr_map) {
|
||||||
|
.attrib = attr,
|
||||||
|
.format = emit,
|
||||||
|
};
|
||||||
|
else
|
||||||
|
*m = (struct tnl_attr_map) {
|
||||||
|
.format = EMIT_PAD,
|
||||||
|
.offset = _tnl_format_info[emit].attrsize,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_choose_attrs(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
|
struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx);
|
||||||
|
struct nv04_context *nctx = to_nv04_context(ctx);
|
||||||
|
static struct tnl_attr_map map[NUM_VERTEX_ATTRS];
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
tnl->vb.AttribPtr[VERT_ATTRIB_POS] = tnl->vb.NdcPtr;
|
||||||
|
|
||||||
|
swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT);
|
||||||
|
swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA);
|
||||||
|
swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR);
|
||||||
|
swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_FOG, EMIT_1UB_1F);
|
||||||
|
swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_TEX0, EMIT_2F);
|
||||||
|
if (nv04_mtex_engine(fahrenheit))
|
||||||
|
swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_TEX1, EMIT_2F);
|
||||||
|
|
||||||
|
swtnl_update_viewport(ctx);
|
||||||
|
|
||||||
|
_tnl_install_attrs(ctx, map, n, nctx->viewport, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TnL renderer entry points */
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_start(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
swtnl_choose_attrs(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_finish(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
FIRE_RING(context_chan(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_primitive(GLcontext *ctx, GLenum mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_reset_stipple(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primitive rendering */
|
||||||
|
|
||||||
|
#define BEGIN_PRIMITIVE(n) \
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx); \
|
||||||
|
struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); \
|
||||||
|
int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size / 4; \
|
||||||
|
\
|
||||||
|
if (nv04_mtex_engine(fahrenheit)) \
|
||||||
|
BEGIN_RING(chan, fahrenheit, \
|
||||||
|
NV04_MULTITEX_TRIANGLE_TLMTVERTEX_SX(0), \
|
||||||
|
n * vertex_len); \
|
||||||
|
else \
|
||||||
|
BEGIN_RING(chan, fahrenheit, \
|
||||||
|
NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0), \
|
||||||
|
n * vertex_len); \
|
||||||
|
|
||||||
|
#define OUT_VERTEX(i) \
|
||||||
|
OUT_RINGp(chan, _tnl_get_vertex(ctx, i), vertex_len);
|
||||||
|
|
||||||
|
#define END_PRIMITIVE(draw) \
|
||||||
|
if (nv04_mtex_engine(fahrenheit)) { \
|
||||||
|
BEGIN_RING(chan, fahrenheit, \
|
||||||
|
NV04_MULTITEX_TRIANGLE_DRAWPRIMITIVE(0), 1); \
|
||||||
|
OUT_RING(chan, draw); \
|
||||||
|
} else { \
|
||||||
|
BEGIN_RING(chan, fahrenheit, \
|
||||||
|
NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), 1); \
|
||||||
|
OUT_RING(chan, draw); \
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_points(GLcontext *ctx, GLuint first, GLuint last)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_line(GLcontext *ctx, GLuint v1, GLuint v2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_triangle(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3)
|
||||||
|
{
|
||||||
|
BEGIN_PRIMITIVE(3);
|
||||||
|
OUT_VERTEX(v1);
|
||||||
|
OUT_VERTEX(v2);
|
||||||
|
OUT_VERTEX(v3);
|
||||||
|
END_PRIMITIVE(0x210);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
swtnl_quad(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4)
|
||||||
|
{
|
||||||
|
BEGIN_PRIMITIVE(4);
|
||||||
|
OUT_VERTEX(v1);
|
||||||
|
OUT_VERTEX(v2);
|
||||||
|
OUT_VERTEX(v3);
|
||||||
|
OUT_VERTEX(v4);
|
||||||
|
END_PRIMITIVE(0x320210);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TnL initialization. */
|
||||||
|
void
|
||||||
|
nv04_render_init(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
|
|
||||||
|
tnl->Driver.RunPipeline = _tnl_run_pipeline;
|
||||||
|
tnl->Driver.Render.Interp = _tnl_interp;
|
||||||
|
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
|
||||||
|
tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
|
||||||
|
tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine;
|
||||||
|
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
|
||||||
|
|
||||||
|
tnl->Driver.Render.Start = swtnl_start;
|
||||||
|
tnl->Driver.Render.Finish = swtnl_finish;
|
||||||
|
tnl->Driver.Render.PrimitiveNotify = swtnl_primitive;
|
||||||
|
tnl->Driver.Render.ResetLineStipple = swtnl_reset_stipple;
|
||||||
|
|
||||||
|
tnl->Driver.Render.Points = swtnl_points;
|
||||||
|
tnl->Driver.Render.Line = swtnl_line;
|
||||||
|
tnl->Driver.Render.Triangle = swtnl_triangle;
|
||||||
|
tnl->Driver.Render.Quad = swtnl_quad;
|
||||||
|
|
||||||
|
_tnl_need_projected_coords(ctx, GL_TRUE);
|
||||||
|
_tnl_init_vertices(ctx, tnl->vb.Size,
|
||||||
|
NUM_VERTEX_ATTRS * 4 * sizeof(GLfloat));
|
||||||
|
_tnl_allow_pixel_fog(ctx, GL_FALSE);
|
||||||
|
_tnl_wakeup(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_render_destroy(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
211
src/mesa/drivers/dri/nouveau/nv04_screen.c
Normal file
211
src/mesa/drivers/dri/nouveau/nv04_screen.c
Normal file
|
|
@ -0,0 +1,211 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_screen.h"
|
||||||
|
#include "nouveau_class.h"
|
||||||
|
#include "nv04_driver.h"
|
||||||
|
|
||||||
|
static const struct nouveau_driver nv04_driver;
|
||||||
|
|
||||||
|
static void
|
||||||
|
nv04_hwctx_init(struct nouveau_screen *screen)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = screen->chan;
|
||||||
|
struct nouveau_grobj *surf3d = screen->surf3d;
|
||||||
|
struct nouveau_grobj *eng3d = screen->eng3d;
|
||||||
|
struct nouveau_grobj *eng3dm = screen->eng3dm;
|
||||||
|
|
||||||
|
BIND_RING(chan, surf3d, 7);
|
||||||
|
BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3);
|
||||||
|
OUT_RING(chan, screen->ntfy->handle);
|
||||||
|
OUT_RING(chan, chan->vram->handle);
|
||||||
|
OUT_RING(chan, chan->vram->handle);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, eng3d, NV04_TEXTURED_TRIANGLE_DMA_NOTIFY, 4);
|
||||||
|
OUT_RING(chan, screen->ntfy->handle);
|
||||||
|
OUT_RING(chan, chan->vram->handle);
|
||||||
|
OUT_RING(chan, chan->gart->handle);
|
||||||
|
OUT_RING(chan, surf3d->handle);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, eng3dm, NV04_MULTITEX_TRIANGLE_DMA_NOTIFY, 4);
|
||||||
|
OUT_RING(chan, screen->ntfy->handle);
|
||||||
|
OUT_RING(chan, chan->vram->handle);
|
||||||
|
OUT_RING(chan, chan->gart->handle);
|
||||||
|
OUT_RING(chan, surf3d->handle);
|
||||||
|
|
||||||
|
FIRE_RING(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nv04_channel_flush_notify(struct nouveau_channel *chan)
|
||||||
|
{
|
||||||
|
struct nouveau_screen *screen = chan->user_private;
|
||||||
|
struct nouveau_context *nctx = screen->context;
|
||||||
|
|
||||||
|
if (nctx && nctx->fallback < SWRAST) {
|
||||||
|
GLcontext *ctx = &nctx->base;
|
||||||
|
|
||||||
|
/* Flushing seems to clobber the engine context. */
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, 0);
|
||||||
|
context_dirty_i(ctx, TEX_OBJ, 1);
|
||||||
|
context_dirty_i(ctx, TEX_ENV, 0);
|
||||||
|
context_dirty_i(ctx, TEX_ENV, 1);
|
||||||
|
context_dirty(ctx, CONTROL);
|
||||||
|
context_dirty(ctx, BLEND);
|
||||||
|
|
||||||
|
nouveau_state_emit(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nv04_screen_init(struct nouveau_screen *screen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
screen->driver = &nv04_driver;
|
||||||
|
screen->chan->flush_notify = nv04_channel_flush_notify;
|
||||||
|
|
||||||
|
/* 2D engine. */
|
||||||
|
ret = nv04_surface_init(screen);
|
||||||
|
if (!ret)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
/* 3D engine. */
|
||||||
|
ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001,
|
||||||
|
NV04_TEXTURED_TRIANGLE, &screen->eng3d);
|
||||||
|
if (ret)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
ret = nouveau_grobj_alloc(screen->chan, 0xbeef0002,
|
||||||
|
NV04_MULTITEX_TRIANGLE, &screen->eng3dm);
|
||||||
|
if (ret)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
ret = nouveau_grobj_alloc(screen->chan, 0xbeef0003,
|
||||||
|
NV04_CONTEXT_SURFACES_3D, &screen->surf3d);
|
||||||
|
if (ret)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
nv04_hwctx_init(screen);
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nv04_screen_destroy(struct nouveau_screen *screen)
|
||||||
|
{
|
||||||
|
if (screen->eng3d)
|
||||||
|
nouveau_grobj_free(&screen->eng3d);
|
||||||
|
|
||||||
|
if (screen->eng3dm)
|
||||||
|
nouveau_grobj_free(&screen->eng3dm);
|
||||||
|
|
||||||
|
if (screen->surf3d)
|
||||||
|
nouveau_grobj_free(&screen->surf3d);
|
||||||
|
|
||||||
|
nv04_surface_takedown(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct nouveau_driver nv04_driver = {
|
||||||
|
.screen_destroy = nv04_screen_destroy,
|
||||||
|
.context_create = nv04_context_create,
|
||||||
|
.context_destroy = nv04_context_destroy,
|
||||||
|
.surface_copy = nv04_surface_copy,
|
||||||
|
.surface_fill = nv04_surface_fill,
|
||||||
|
.emit = (nouveau_state_func[]) {
|
||||||
|
nv04_defer_control,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nv04_defer_blend,
|
||||||
|
nv04_defer_blend,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nv04_defer_control,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nv04_defer_control,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nv04_defer_control,
|
||||||
|
nv04_defer_control,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nv04_emit_framebuffer,
|
||||||
|
nv04_defer_blend,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nv04_emit_scissor,
|
||||||
|
nv04_defer_blend,
|
||||||
|
nv04_defer_control,
|
||||||
|
nv04_defer_control,
|
||||||
|
nv04_defer_control,
|
||||||
|
nv04_emit_tex_env,
|
||||||
|
nv04_emit_tex_env,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nv04_emit_tex_obj,
|
||||||
|
nv04_emit_tex_obj,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nouveau_emit_nothing,
|
||||||
|
nv04_emit_blend,
|
||||||
|
nv04_emit_control,
|
||||||
|
},
|
||||||
|
.num_emit = NUM_NV04_STATE,
|
||||||
|
};
|
||||||
116
src/mesa/drivers/dri/nouveau/nv04_state_fb.c
Normal file
116
src/mesa/drivers/dri/nouveau/nv04_state_fb.c
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_fbo.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
#include "nouveau_class.h"
|
||||||
|
#include "nv04_driver.h"
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
get_rt_format(gl_format format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case MESA_FORMAT_XRGB8888:
|
||||||
|
return 0x05;
|
||||||
|
case MESA_FORMAT_ARGB8888:
|
||||||
|
return 0x08;
|
||||||
|
case MESA_FORMAT_RGB565:
|
||||||
|
return 0x03;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_emit_framebuffer(GLcontext *ctx, int emit)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_screen *screen = to_nouveau_context(ctx)->screen;
|
||||||
|
struct nouveau_grobj *surf3d = screen->surf3d;
|
||||||
|
struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER);
|
||||||
|
struct gl_framebuffer *fb = ctx->DrawBuffer;
|
||||||
|
struct nouveau_surface *s;
|
||||||
|
uint32_t rt_format = NV04_CONTEXT_SURFACES_3D_FORMAT_TYPE_PITCH;
|
||||||
|
uint32_t rt_pitch = 0, zeta_pitch = 0;
|
||||||
|
unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
|
||||||
|
|
||||||
|
if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Render target */
|
||||||
|
if (fb->_NumColorDrawBuffers) {
|
||||||
|
s = &to_nouveau_renderbuffer(
|
||||||
|
fb->_ColorDrawBuffers[0])->surface;
|
||||||
|
|
||||||
|
rt_format |= get_rt_format(s->format);
|
||||||
|
zeta_pitch = rt_pitch = s->pitch;
|
||||||
|
|
||||||
|
nouveau_bo_markl(bctx, surf3d,
|
||||||
|
NV04_CONTEXT_SURFACES_3D_OFFSET_COLOR,
|
||||||
|
s->bo, 0, bo_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* depth/stencil */
|
||||||
|
if (fb->_DepthBuffer) {
|
||||||
|
s = &to_nouveau_renderbuffer(
|
||||||
|
fb->_DepthBuffer->Wrapped)->surface;
|
||||||
|
|
||||||
|
zeta_pitch = s->pitch;
|
||||||
|
|
||||||
|
nouveau_bo_markl(bctx, surf3d,
|
||||||
|
NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA,
|
||||||
|
s->bo, 0, bo_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
|
||||||
|
OUT_RING(chan, rt_format);
|
||||||
|
BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_PITCH, 1);
|
||||||
|
OUT_RING(chan, zeta_pitch << 16 | rt_pitch);
|
||||||
|
|
||||||
|
/* Recompute the scissor state. */
|
||||||
|
context_dirty(ctx, SCISSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_emit_scissor(GLcontext *ctx, int emit)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_screen *screen = to_nouveau_context(ctx)->screen;
|
||||||
|
struct nouveau_grobj *surf3d = screen->surf3d;
|
||||||
|
int x, y, w, h;
|
||||||
|
|
||||||
|
get_scissors(ctx->DrawBuffer, &x, &y, &w, &h);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2);
|
||||||
|
OUT_RING(chan, w << 16 | x);
|
||||||
|
OUT_RING(chan, h << 16 | y);
|
||||||
|
|
||||||
|
/* Messing with surf3d invalidates some engine state. */
|
||||||
|
context_dirty(ctx, CONTROL);
|
||||||
|
context_dirty(ctx, BLEND);
|
||||||
|
}
|
||||||
261
src/mesa/drivers/dri/nouveau/nv04_state_frag.c
Normal file
261
src/mesa/drivers/dri/nouveau/nv04_state_frag.c
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
#include "nouveau_class.h"
|
||||||
|
#include "nv04_driver.h"
|
||||||
|
|
||||||
|
#define COMBINER_SHIFT(in) \
|
||||||
|
(NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT##in##_SHIFT \
|
||||||
|
- NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_SHIFT)
|
||||||
|
#define COMBINER_SOURCE(reg) \
|
||||||
|
NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_##reg
|
||||||
|
#define COMBINER_INVERT \
|
||||||
|
NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_INVERSE0
|
||||||
|
#define COMBINER_ALPHA \
|
||||||
|
NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ALPHA0
|
||||||
|
|
||||||
|
struct combiner_state {
|
||||||
|
int unit;
|
||||||
|
GLboolean alpha;
|
||||||
|
|
||||||
|
/* GL state */
|
||||||
|
GLenum mode;
|
||||||
|
GLenum *source;
|
||||||
|
GLenum *operand;
|
||||||
|
GLuint logscale;
|
||||||
|
|
||||||
|
/* Derived HW state */
|
||||||
|
uint32_t hw;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define __INIT_COMBINER_ALPHA_A GL_TRUE
|
||||||
|
#define __INIT_COMBINER_ALPHA_RGB GL_FALSE
|
||||||
|
|
||||||
|
/* Initialize a combiner_state struct from the texture unit
|
||||||
|
* context. */
|
||||||
|
#define INIT_COMBINER(chan, rc, i) do { \
|
||||||
|
struct gl_tex_env_combine_state *c = \
|
||||||
|
ctx->Texture.Unit[i]._CurrentCombine; \
|
||||||
|
(rc)->alpha = __INIT_COMBINER_ALPHA_##chan; \
|
||||||
|
(rc)->unit = i; \
|
||||||
|
(rc)->mode = c->Mode##chan; \
|
||||||
|
(rc)->source = c->Source##chan; \
|
||||||
|
(rc)->operand = c->Operand##chan; \
|
||||||
|
(rc)->logscale = c->ScaleShift##chan; \
|
||||||
|
(rc)->hw = 0; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Get the combiner source for the specified EXT_texture_env_combine
|
||||||
|
* argument. */
|
||||||
|
static uint32_t
|
||||||
|
get_arg_source(struct combiner_state *rc, int arg)
|
||||||
|
{
|
||||||
|
switch (rc->source[arg]) {
|
||||||
|
case GL_TEXTURE:
|
||||||
|
return rc->unit ? COMBINER_SOURCE(TEXTURE1) :
|
||||||
|
COMBINER_SOURCE(TEXTURE0);
|
||||||
|
|
||||||
|
case GL_TEXTURE0:
|
||||||
|
return COMBINER_SOURCE(TEXTURE0);
|
||||||
|
|
||||||
|
case GL_TEXTURE1:
|
||||||
|
return COMBINER_SOURCE(TEXTURE1);
|
||||||
|
|
||||||
|
case GL_CONSTANT:
|
||||||
|
return COMBINER_SOURCE(CONSTANT);
|
||||||
|
|
||||||
|
case GL_PRIMARY_COLOR:
|
||||||
|
return COMBINER_SOURCE(PRIMARY_COLOR);
|
||||||
|
|
||||||
|
case GL_PREVIOUS:
|
||||||
|
return rc->unit ? COMBINER_SOURCE(PREVIOUS) :
|
||||||
|
COMBINER_SOURCE(PRIMARY_COLOR);
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the (possibly inverted) combiner input mapping for the
|
||||||
|
* specified argument. */
|
||||||
|
#define INVERT 0x1
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
get_arg_mapping(struct combiner_state *rc, int arg, int flags)
|
||||||
|
{
|
||||||
|
int map = 0;
|
||||||
|
|
||||||
|
switch (rc->operand[arg]) {
|
||||||
|
case GL_SRC_COLOR:
|
||||||
|
case GL_ONE_MINUS_SRC_COLOR:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_SRC_ALPHA:
|
||||||
|
case GL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
map |= rc->alpha ? 0 : COMBINER_ALPHA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rc->operand[arg]) {
|
||||||
|
case GL_SRC_COLOR:
|
||||||
|
case GL_SRC_ALPHA:
|
||||||
|
map |= flags & INVERT ? COMBINER_INVERT : 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_ONE_MINUS_SRC_COLOR:
|
||||||
|
case GL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
map |= flags & INVERT ? 0 : COMBINER_INVERT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bind the combiner input <in> to the combiner source <src>,
|
||||||
|
* possibly inverted. */
|
||||||
|
#define INPUT_SRC(rc, in, src, flags) \
|
||||||
|
(rc)->hw |= ((flags & INVERT ? COMBINER_INVERT : 0) | \
|
||||||
|
COMBINER_SOURCE(src)) << COMBINER_SHIFT(in)
|
||||||
|
|
||||||
|
/* Bind the combiner input <in> to the EXT_texture_env_combine
|
||||||
|
* argument <arg>, possibly inverted. */
|
||||||
|
#define INPUT_ARG(rc, in, arg, flags) \
|
||||||
|
(rc)->hw |= (get_arg_source(rc, arg) | \
|
||||||
|
get_arg_mapping(rc, arg, flags)) << COMBINER_SHIFT(in)
|
||||||
|
|
||||||
|
#define UNSIGNED_OP(rc) \
|
||||||
|
(rc)->hw |= ((rc)->logscale ? \
|
||||||
|
NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_SCALE2 : \
|
||||||
|
NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_IDENTITY)
|
||||||
|
#define SIGNED_OP(rc) \
|
||||||
|
(rc)->hw |= ((rc)->logscale ? \
|
||||||
|
NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS_SCALE2 : \
|
||||||
|
NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS)
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_combiner(struct combiner_state *rc)
|
||||||
|
{
|
||||||
|
switch (rc->mode) {
|
||||||
|
case GL_REPLACE:
|
||||||
|
INPUT_ARG(rc, 0, 0, 0);
|
||||||
|
INPUT_SRC(rc, 1, ZERO, INVERT);
|
||||||
|
INPUT_SRC(rc, 2, ZERO, 0);
|
||||||
|
INPUT_SRC(rc, 3, ZERO, 0);
|
||||||
|
UNSIGNED_OP(rc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_MODULATE:
|
||||||
|
INPUT_ARG(rc, 0, 0, 0);
|
||||||
|
INPUT_ARG(rc, 1, 1, 0);
|
||||||
|
INPUT_SRC(rc, 2, ZERO, 0);
|
||||||
|
INPUT_SRC(rc, 3, ZERO, 0);
|
||||||
|
UNSIGNED_OP(rc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_ADD:
|
||||||
|
INPUT_ARG(rc, 0, 0, 0);
|
||||||
|
INPUT_SRC(rc, 1, ZERO, INVERT);
|
||||||
|
INPUT_ARG(rc, 2, 1, 0);
|
||||||
|
INPUT_SRC(rc, 3, ZERO, INVERT);
|
||||||
|
UNSIGNED_OP(rc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_INTERPOLATE:
|
||||||
|
INPUT_ARG(rc, 0, 0, 0);
|
||||||
|
INPUT_ARG(rc, 1, 2, 0);
|
||||||
|
INPUT_ARG(rc, 2, 1, 0);
|
||||||
|
INPUT_ARG(rc, 3, 2, INVERT);
|
||||||
|
UNSIGNED_OP(rc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_ADD_SIGNED:
|
||||||
|
INPUT_ARG(rc, 0, 0, 0);
|
||||||
|
INPUT_SRC(rc, 1, ZERO, INVERT);
|
||||||
|
INPUT_ARG(rc, 2, 1, 0);
|
||||||
|
INPUT_SRC(rc, 3, ZERO, INVERT);
|
||||||
|
SIGNED_OP(rc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_emit_tex_env(GLcontext *ctx, int emit)
|
||||||
|
{
|
||||||
|
const int i = emit - NOUVEAU_STATE_TEX_ENV0;
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx);
|
||||||
|
struct combiner_state rc_a = {}, rc_c = {};
|
||||||
|
|
||||||
|
if (!nv04_mtex_engine(fahrenheit)) {
|
||||||
|
context_dirty(ctx, BLEND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the new combiner state. */
|
||||||
|
if (ctx->Texture.Unit[i]._ReallyEnabled) {
|
||||||
|
INIT_COMBINER(A, &rc_a, i);
|
||||||
|
setup_combiner(&rc_a);
|
||||||
|
|
||||||
|
INIT_COMBINER(RGB, &rc_c, i);
|
||||||
|
setup_combiner(&rc_c);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (i == 0) {
|
||||||
|
INPUT_SRC(&rc_a, 0, PRIMARY_COLOR, 0);
|
||||||
|
INPUT_SRC(&rc_c, 0, PRIMARY_COLOR, 0);
|
||||||
|
} else {
|
||||||
|
INPUT_SRC(&rc_a, 0, PREVIOUS, 0);
|
||||||
|
INPUT_SRC(&rc_c, 0, PREVIOUS, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
INPUT_SRC(&rc_a, 1, ZERO, INVERT);
|
||||||
|
INPUT_SRC(&rc_c, 1, ZERO, INVERT);
|
||||||
|
INPUT_SRC(&rc_a, 2, ZERO, 0);
|
||||||
|
INPUT_SRC(&rc_c, 2, ZERO, 0);
|
||||||
|
INPUT_SRC(&rc_a, 3, ZERO, 0);
|
||||||
|
INPUT_SRC(&rc_c, 3, ZERO, 0);
|
||||||
|
|
||||||
|
UNSIGNED_OP(&rc_a);
|
||||||
|
UNSIGNED_OP(&rc_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the register combiner state out to the hardware. */
|
||||||
|
BEGIN_RING(chan, fahrenheit,
|
||||||
|
NV04_MULTITEX_TRIANGLE_COMBINE_ALPHA(i), 2);
|
||||||
|
OUT_RING(chan, rc_a.hw);
|
||||||
|
OUT_RING(chan, rc_c.hw);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit,
|
||||||
|
NV04_MULTITEX_TRIANGLE_COMBINE_FACTOR, 1);
|
||||||
|
OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888,
|
||||||
|
ctx->Texture.Unit[0].EnvColor));
|
||||||
|
}
|
||||||
314
src/mesa/drivers/dri/nouveau/nv04_state_raster.c
Normal file
314
src/mesa/drivers/dri/nouveau/nv04_state_raster.c
Normal file
|
|
@ -0,0 +1,314 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
#include "nouveau_class.h"
|
||||||
|
#include "nv04_driver.h"
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
get_comparison_op(unsigned op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case GL_NEVER:
|
||||||
|
return 0x1;
|
||||||
|
case GL_LESS:
|
||||||
|
return 0x2;
|
||||||
|
case GL_EQUAL:
|
||||||
|
return 0x3;
|
||||||
|
case GL_LEQUAL:
|
||||||
|
return 0x4;
|
||||||
|
case GL_GREATER:
|
||||||
|
return 0x5;
|
||||||
|
case GL_NOTEQUAL:
|
||||||
|
return 0x6;
|
||||||
|
case GL_GEQUAL:
|
||||||
|
return 0x7;
|
||||||
|
case GL_ALWAYS:
|
||||||
|
return 0x8;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
get_stencil_op(unsigned op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case GL_KEEP:
|
||||||
|
return 0x1;
|
||||||
|
case GL_INCR:
|
||||||
|
return 0x4;
|
||||||
|
case GL_DECR:
|
||||||
|
return 0x5;
|
||||||
|
case GL_INVERT:
|
||||||
|
return 0x6;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
get_texenv_mode(unsigned mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case GL_REPLACE:
|
||||||
|
return 0x1;
|
||||||
|
case GL_ADD:
|
||||||
|
return 0x2;
|
||||||
|
case GL_DECAL:
|
||||||
|
return 0x3;
|
||||||
|
case GL_MODULATE:
|
||||||
|
return 0x4;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
get_blend_func(unsigned func)
|
||||||
|
{
|
||||||
|
switch (func) {
|
||||||
|
case GL_ZERO:
|
||||||
|
return 0x1;
|
||||||
|
case GL_ONE:
|
||||||
|
return 0x2;
|
||||||
|
case GL_SRC_COLOR:
|
||||||
|
return 0x3;
|
||||||
|
case GL_ONE_MINUS_SRC_COLOR:
|
||||||
|
return 0x4;
|
||||||
|
case GL_SRC_ALPHA:
|
||||||
|
return 0x5;
|
||||||
|
case GL_ONE_MINUS_SRC_ALPHA:
|
||||||
|
return 0x6;
|
||||||
|
case GL_DST_ALPHA:
|
||||||
|
return 0x7;
|
||||||
|
case GL_ONE_MINUS_DST_ALPHA:
|
||||||
|
return 0x8;
|
||||||
|
case GL_DST_COLOR:
|
||||||
|
return 0x9;
|
||||||
|
case GL_ONE_MINUS_DST_COLOR:
|
||||||
|
return 0xa;
|
||||||
|
case GL_SRC_ALPHA_SATURATE:
|
||||||
|
return 0xb;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_defer_control(GLcontext *ctx, int emit)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_emit_control(GLcontext *ctx, int emit)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx);
|
||||||
|
|
||||||
|
if (nv04_mtex_engine(fahrenheit)) {
|
||||||
|
int cull_mode = ctx->Polygon.CullFaceMode;
|
||||||
|
int front_face = ctx->Polygon.FrontFace;
|
||||||
|
uint32_t ctrl0 = 1 << 30 |
|
||||||
|
NV04_MULTITEX_TRIANGLE_CONTROL0_ORIGIN;
|
||||||
|
uint32_t ctrl1 = 0, ctrl2 = 0;
|
||||||
|
|
||||||
|
/* Color mask. */
|
||||||
|
if (ctx->Color.ColorMask[0][RCOMP])
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE;
|
||||||
|
if (ctx->Color.ColorMask[0][GCOMP])
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE;
|
||||||
|
if (ctx->Color.ColorMask[0][BCOMP])
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE;
|
||||||
|
if (ctx->Color.ColorMask[0][ACOMP])
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE;
|
||||||
|
|
||||||
|
/* Dithering. */
|
||||||
|
if (ctx->Color.DitherFlag)
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_DITHER_ENABLE;
|
||||||
|
|
||||||
|
/* Cull mode. */
|
||||||
|
if (!ctx->Polygon.CullFlag)
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_NONE;
|
||||||
|
else if (cull_mode == GL_FRONT_AND_BACK)
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_BOTH;
|
||||||
|
else
|
||||||
|
ctrl0 |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ?
|
||||||
|
NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CW :
|
||||||
|
NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CCW;
|
||||||
|
|
||||||
|
/* Depth test. */
|
||||||
|
if (ctx->Depth.Test)
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_ENABLE;
|
||||||
|
|
||||||
|
if (ctx->Depth.Mask)
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_WRITE;
|
||||||
|
|
||||||
|
ctrl0 |= get_comparison_op(ctx->Depth.Func) << 16;
|
||||||
|
|
||||||
|
/* Alpha test. */
|
||||||
|
if (ctx->Color.AlphaEnabled)
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_ENABLE;
|
||||||
|
|
||||||
|
ctrl0 |= get_comparison_op(ctx->Color.AlphaFunc) << 8 |
|
||||||
|
FLOAT_TO_UBYTE(ctx->Color.AlphaRef);
|
||||||
|
|
||||||
|
/* Stencil test. */
|
||||||
|
if (ctx->Stencil.WriteMask[0])
|
||||||
|
ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE;
|
||||||
|
|
||||||
|
if (ctx->Stencil.Enabled)
|
||||||
|
ctrl1 |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE;
|
||||||
|
|
||||||
|
ctrl1 |= get_comparison_op(ctx->Stencil.Function[0]) << 4 |
|
||||||
|
ctx->Stencil.Ref[0] << 8 |
|
||||||
|
ctx->Stencil.ValueMask[0] << 16 |
|
||||||
|
ctx->Stencil.WriteMask[0] << 24;
|
||||||
|
|
||||||
|
ctrl2 |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 |
|
||||||
|
get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 |
|
||||||
|
get_stencil_op(ctx->Stencil.FailFunc[0]);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_CONTROL0, 3);
|
||||||
|
OUT_RING(chan, ctrl0);
|
||||||
|
OUT_RING(chan, ctrl1);
|
||||||
|
OUT_RING(chan, ctrl2);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
int cull_mode = ctx->Polygon.CullFaceMode;
|
||||||
|
int front_face = ctx->Polygon.FrontFace;
|
||||||
|
uint32_t ctrl = 1 << 30 |
|
||||||
|
NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN;
|
||||||
|
|
||||||
|
/* Dithering. */
|
||||||
|
if (ctx->Color.DitherFlag)
|
||||||
|
ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE;
|
||||||
|
|
||||||
|
/* Cull mode. */
|
||||||
|
if (!ctx->Polygon.CullFlag)
|
||||||
|
ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE;
|
||||||
|
else if (cull_mode == GL_FRONT_AND_BACK)
|
||||||
|
ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH;
|
||||||
|
else
|
||||||
|
ctrl |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ?
|
||||||
|
NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW :
|
||||||
|
NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW;
|
||||||
|
|
||||||
|
/* Depth test. */
|
||||||
|
if (ctx->Depth.Test)
|
||||||
|
ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE;
|
||||||
|
if (ctx->Depth.Mask)
|
||||||
|
ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE;
|
||||||
|
|
||||||
|
ctrl |= get_comparison_op(ctx->Depth.Func) << 16;
|
||||||
|
|
||||||
|
/* Alpha test. */
|
||||||
|
if (ctx->Color.AlphaEnabled)
|
||||||
|
ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE;
|
||||||
|
|
||||||
|
ctrl |= get_comparison_op(ctx->Color.AlphaFunc) << 8 |
|
||||||
|
FLOAT_TO_UBYTE(ctx->Color.AlphaRef);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1);
|
||||||
|
OUT_RING(chan, ctrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_defer_blend(GLcontext *ctx, int emit)
|
||||||
|
{
|
||||||
|
context_dirty(ctx, BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_emit_blend(GLcontext *ctx, int emit)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx);
|
||||||
|
|
||||||
|
if (nv04_mtex_engine(fahrenheit)) {
|
||||||
|
uint32_t blend = 0x2 << 4 |
|
||||||
|
NV04_MULTITEX_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE;
|
||||||
|
|
||||||
|
/* Alpha blending. */
|
||||||
|
blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 |
|
||||||
|
get_blend_func(ctx->Color.BlendSrcRGB) << 24;
|
||||||
|
|
||||||
|
if (ctx->Color.BlendEnabled)
|
||||||
|
blend |= NV04_MULTITEX_TRIANGLE_BLEND_BLEND_ENABLE;
|
||||||
|
|
||||||
|
/* Shade model. */
|
||||||
|
if (ctx->Light.ShadeModel == GL_SMOOTH)
|
||||||
|
blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_GOURAUD;
|
||||||
|
else
|
||||||
|
blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_FLAT;
|
||||||
|
|
||||||
|
/* Fog. */
|
||||||
|
if (ctx->Fog.Enabled)
|
||||||
|
blend |= NV04_MULTITEX_TRIANGLE_BLEND_FOG_ENABLE;
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_BLEND, 1);
|
||||||
|
OUT_RING(chan, blend);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FOGCOLOR, 1);
|
||||||
|
OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888,
|
||||||
|
ctx->Fog.Color));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
uint32_t blend = 0x2 << 4 |
|
||||||
|
NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE;
|
||||||
|
|
||||||
|
/* Alpha blending. */
|
||||||
|
blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 |
|
||||||
|
get_blend_func(ctx->Color.BlendSrcRGB) << 24;
|
||||||
|
|
||||||
|
if (ctx->Color.BlendEnabled)
|
||||||
|
blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE;
|
||||||
|
|
||||||
|
/* Shade model. */
|
||||||
|
if (ctx->Light.ShadeModel == GL_SMOOTH)
|
||||||
|
blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD;
|
||||||
|
else
|
||||||
|
blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT;
|
||||||
|
|
||||||
|
/* Texture environment. */
|
||||||
|
blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode);
|
||||||
|
|
||||||
|
/* Fog. */
|
||||||
|
if (ctx->Fog.Enabled)
|
||||||
|
blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE;
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1);
|
||||||
|
OUT_RING(chan, blend);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FOGCOLOR, 1);
|
||||||
|
OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888,
|
||||||
|
ctx->Fog.Color));
|
||||||
|
}
|
||||||
|
}
|
||||||
162
src/mesa/drivers/dri/nouveau/nv04_state_tex.c
Normal file
162
src/mesa/drivers/dri/nouveau/nv04_state_tex.c
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_texture.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
#include "nouveau_gldefs.h"
|
||||||
|
#include "nouveau_class.h"
|
||||||
|
#include "nv04_driver.h"
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
get_tex_format(struct gl_texture_image *ti)
|
||||||
|
{
|
||||||
|
switch (ti->TexFormat) {
|
||||||
|
case MESA_FORMAT_A8:
|
||||||
|
case MESA_FORMAT_L8:
|
||||||
|
return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_Y8;
|
||||||
|
case MESA_FORMAT_ARGB1555:
|
||||||
|
return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A1R5G5B5;
|
||||||
|
case MESA_FORMAT_ARGB4444:
|
||||||
|
return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A4R4G4B4;
|
||||||
|
case MESA_FORMAT_RGB565:
|
||||||
|
return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_R5G6B5;
|
||||||
|
case MESA_FORMAT_ARGB8888:
|
||||||
|
return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
get_wrap_mode(unsigned wrap)
|
||||||
|
{
|
||||||
|
switch (wrap) {
|
||||||
|
case GL_REPEAT:
|
||||||
|
return 0x1;
|
||||||
|
case GL_MIRRORED_REPEAT:
|
||||||
|
return 0x2;
|
||||||
|
case GL_CLAMP:
|
||||||
|
case GL_CLAMP_TO_EDGE:
|
||||||
|
return 0x3;
|
||||||
|
case GL_CLAMP_TO_BORDER:
|
||||||
|
return 0x4;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_emit_tex_obj(GLcontext *ctx, int emit)
|
||||||
|
{
|
||||||
|
const int i = emit - NOUVEAU_STATE_TEX_OBJ0;
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx);
|
||||||
|
struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i);
|
||||||
|
const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM;
|
||||||
|
struct nouveau_surface *s;
|
||||||
|
uint32_t format = 0xa0, filter = 0x1010;
|
||||||
|
|
||||||
|
if (i && !nv04_mtex_engine(fahrenheit))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ctx->Texture.Unit[i]._ReallyEnabled) {
|
||||||
|
struct gl_texture_object *t = ctx->Texture.Unit[i]._Current;
|
||||||
|
struct gl_texture_image *ti = t->Image[0][t->BaseLevel];
|
||||||
|
int lod_max = 1, lod_bias = 0;
|
||||||
|
|
||||||
|
nouveau_texture_validate(ctx, t);
|
||||||
|
s = &to_nouveau_texture(t)->surfaces[t->BaseLevel];
|
||||||
|
|
||||||
|
if (t->MinFilter != GL_NEAREST &&
|
||||||
|
t->MinFilter != GL_LINEAR) {
|
||||||
|
lod_max = CLAMP(MIN2(t->MaxLod, t->_MaxLambda),
|
||||||
|
0, 15) + 1;
|
||||||
|
|
||||||
|
lod_bias = CLAMP(ctx->Texture.Unit[i].LodBias +
|
||||||
|
t->LodBias, 0, 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
format |= get_wrap_mode(t->WrapT) << 28 |
|
||||||
|
get_wrap_mode(t->WrapS) << 24 |
|
||||||
|
ti->HeightLog2 << 20 |
|
||||||
|
ti->WidthLog2 << 16 |
|
||||||
|
lod_max << 12 |
|
||||||
|
get_tex_format(ti);
|
||||||
|
|
||||||
|
filter |= log2i(t->MaxAnisotropy) << 31 |
|
||||||
|
nvgl_filter_mode(t->MagFilter) << 28 |
|
||||||
|
log2i(t->MaxAnisotropy) << 27 |
|
||||||
|
nvgl_filter_mode(t->MinFilter) << 24 |
|
||||||
|
lod_bias << 16;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
s = &to_nv04_context(ctx)->dummy_texture;
|
||||||
|
|
||||||
|
format |= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT |
|
||||||
|
NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_REPEAT |
|
||||||
|
1 << 12 |
|
||||||
|
NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8;
|
||||||
|
|
||||||
|
filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST |
|
||||||
|
NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nv04_mtex_engine(fahrenheit)) {
|
||||||
|
nouveau_bo_markl(bctx, fahrenheit,
|
||||||
|
NV04_MULTITEX_TRIANGLE_OFFSET(i),
|
||||||
|
s->bo, 0, bo_flags);
|
||||||
|
|
||||||
|
nouveau_bo_mark(bctx, fahrenheit,
|
||||||
|
NV04_MULTITEX_TRIANGLE_FORMAT(i),
|
||||||
|
s->bo, format, 0,
|
||||||
|
NV04_MULTITEX_TRIANGLE_FORMAT_DMA_A,
|
||||||
|
NV04_MULTITEX_TRIANGLE_FORMAT_DMA_B,
|
||||||
|
bo_flags | NOUVEAU_BO_OR);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FILTER(i), 1);
|
||||||
|
OUT_RING(chan, filter);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nouveau_bo_markl(bctx, fahrenheit,
|
||||||
|
NV04_TEXTURED_TRIANGLE_OFFSET,
|
||||||
|
s->bo, 0, bo_flags);
|
||||||
|
|
||||||
|
nouveau_bo_mark(bctx, fahrenheit,
|
||||||
|
NV04_TEXTURED_TRIANGLE_FORMAT,
|
||||||
|
s->bo, format, 0,
|
||||||
|
NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A,
|
||||||
|
NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B,
|
||||||
|
bo_flags | NOUVEAU_BO_OR);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1);
|
||||||
|
OUT_RING(chan, 0);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1);
|
||||||
|
OUT_RING(chan, filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
547
src/mesa/drivers/dri/nouveau/nv04_surface.c
Normal file
547
src/mesa/drivers/dri/nouveau/nv04_surface.c
Normal file
|
|
@ -0,0 +1,547 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2010 The Nouveau Project.
|
||||||
|
* 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_class.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
#include "nv04_driver.h"
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
swzsurf_format(gl_format format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case MESA_FORMAT_A8:
|
||||||
|
case MESA_FORMAT_L8:
|
||||||
|
case MESA_FORMAT_I8:
|
||||||
|
case MESA_FORMAT_RGB332:
|
||||||
|
case MESA_FORMAT_CI8:
|
||||||
|
return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y8;
|
||||||
|
|
||||||
|
case MESA_FORMAT_RGB565:
|
||||||
|
case MESA_FORMAT_RGB565_REV:
|
||||||
|
case MESA_FORMAT_ARGB4444:
|
||||||
|
case MESA_FORMAT_ARGB4444_REV:
|
||||||
|
case MESA_FORMAT_ARGB1555:
|
||||||
|
case MESA_FORMAT_RGBA5551:
|
||||||
|
case MESA_FORMAT_ARGB1555_REV:
|
||||||
|
case MESA_FORMAT_AL88:
|
||||||
|
case MESA_FORMAT_AL88_REV:
|
||||||
|
case MESA_FORMAT_YCBCR:
|
||||||
|
case MESA_FORMAT_YCBCR_REV:
|
||||||
|
case MESA_FORMAT_Z16:
|
||||||
|
return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_R5G6B5;
|
||||||
|
|
||||||
|
case MESA_FORMAT_RGBA8888:
|
||||||
|
case MESA_FORMAT_RGBA8888_REV:
|
||||||
|
case MESA_FORMAT_XRGB8888:
|
||||||
|
case MESA_FORMAT_ARGB8888:
|
||||||
|
case MESA_FORMAT_ARGB8888_REV:
|
||||||
|
case MESA_FORMAT_S8_Z24:
|
||||||
|
case MESA_FORMAT_Z24_S8:
|
||||||
|
case MESA_FORMAT_Z32:
|
||||||
|
return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
surf2d_format(gl_format format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case MESA_FORMAT_A8:
|
||||||
|
case MESA_FORMAT_L8:
|
||||||
|
case MESA_FORMAT_I8:
|
||||||
|
case MESA_FORMAT_RGB332:
|
||||||
|
case MESA_FORMAT_CI8:
|
||||||
|
return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
|
||||||
|
|
||||||
|
case MESA_FORMAT_RGB565:
|
||||||
|
case MESA_FORMAT_RGB565_REV:
|
||||||
|
case MESA_FORMAT_ARGB4444:
|
||||||
|
case MESA_FORMAT_ARGB4444_REV:
|
||||||
|
case MESA_FORMAT_ARGB1555:
|
||||||
|
case MESA_FORMAT_RGBA5551:
|
||||||
|
case MESA_FORMAT_ARGB1555_REV:
|
||||||
|
case MESA_FORMAT_AL88:
|
||||||
|
case MESA_FORMAT_AL88_REV:
|
||||||
|
case MESA_FORMAT_YCBCR:
|
||||||
|
case MESA_FORMAT_YCBCR_REV:
|
||||||
|
case MESA_FORMAT_Z16:
|
||||||
|
return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
|
||||||
|
|
||||||
|
case MESA_FORMAT_RGBA8888:
|
||||||
|
case MESA_FORMAT_RGBA8888_REV:
|
||||||
|
case MESA_FORMAT_XRGB8888:
|
||||||
|
case MESA_FORMAT_ARGB8888:
|
||||||
|
case MESA_FORMAT_ARGB8888_REV:
|
||||||
|
case MESA_FORMAT_S8_Z24:
|
||||||
|
case MESA_FORMAT_Z24_S8:
|
||||||
|
case MESA_FORMAT_Z32:
|
||||||
|
return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
rect_format(gl_format format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case MESA_FORMAT_A8:
|
||||||
|
case MESA_FORMAT_L8:
|
||||||
|
case MESA_FORMAT_I8:
|
||||||
|
case MESA_FORMAT_RGB332:
|
||||||
|
case MESA_FORMAT_CI8:
|
||||||
|
return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
|
||||||
|
|
||||||
|
case MESA_FORMAT_RGB565:
|
||||||
|
case MESA_FORMAT_RGB565_REV:
|
||||||
|
case MESA_FORMAT_ARGB4444:
|
||||||
|
case MESA_FORMAT_ARGB4444_REV:
|
||||||
|
case MESA_FORMAT_ARGB1555:
|
||||||
|
case MESA_FORMAT_RGBA5551:
|
||||||
|
case MESA_FORMAT_ARGB1555_REV:
|
||||||
|
case MESA_FORMAT_AL88:
|
||||||
|
case MESA_FORMAT_AL88_REV:
|
||||||
|
case MESA_FORMAT_YCBCR:
|
||||||
|
case MESA_FORMAT_YCBCR_REV:
|
||||||
|
case MESA_FORMAT_Z16:
|
||||||
|
return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5;
|
||||||
|
|
||||||
|
case MESA_FORMAT_RGBA8888:
|
||||||
|
case MESA_FORMAT_RGBA8888_REV:
|
||||||
|
case MESA_FORMAT_XRGB8888:
|
||||||
|
case MESA_FORMAT_ARGB8888:
|
||||||
|
case MESA_FORMAT_ARGB8888_REV:
|
||||||
|
case MESA_FORMAT_S8_Z24:
|
||||||
|
case MESA_FORMAT_Z24_S8:
|
||||||
|
case MESA_FORMAT_Z32:
|
||||||
|
return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
sifm_format(gl_format format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case MESA_FORMAT_A8:
|
||||||
|
case MESA_FORMAT_L8:
|
||||||
|
case MESA_FORMAT_I8:
|
||||||
|
case MESA_FORMAT_RGB332:
|
||||||
|
case MESA_FORMAT_CI8:
|
||||||
|
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_AY8;
|
||||||
|
|
||||||
|
case MESA_FORMAT_RGB565:
|
||||||
|
case MESA_FORMAT_RGB565_REV:
|
||||||
|
case MESA_FORMAT_ARGB4444:
|
||||||
|
case MESA_FORMAT_ARGB4444_REV:
|
||||||
|
case MESA_FORMAT_ARGB1555:
|
||||||
|
case MESA_FORMAT_RGBA5551:
|
||||||
|
case MESA_FORMAT_ARGB1555_REV:
|
||||||
|
case MESA_FORMAT_AL88:
|
||||||
|
case MESA_FORMAT_AL88_REV:
|
||||||
|
case MESA_FORMAT_YCBCR:
|
||||||
|
case MESA_FORMAT_YCBCR_REV:
|
||||||
|
case MESA_FORMAT_Z16:
|
||||||
|
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5;
|
||||||
|
|
||||||
|
case MESA_FORMAT_RGBA8888:
|
||||||
|
case MESA_FORMAT_RGBA8888_REV:
|
||||||
|
case MESA_FORMAT_XRGB8888:
|
||||||
|
case MESA_FORMAT_ARGB8888:
|
||||||
|
case MESA_FORMAT_ARGB8888_REV:
|
||||||
|
case MESA_FORMAT_S8_Z24:
|
||||||
|
case MESA_FORMAT_Z24_S8:
|
||||||
|
case MESA_FORMAT_Z32:
|
||||||
|
return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nv04_surface_copy_swizzle(GLcontext *ctx,
|
||||||
|
struct nouveau_surface *dst,
|
||||||
|
struct nouveau_surface *src,
|
||||||
|
int dx, int dy, int sx, int sy,
|
||||||
|
int w, int h)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_screen *screen = to_nouveau_context(ctx)->screen;
|
||||||
|
struct nouveau_grobj *swzsurf = screen->swzsurf;
|
||||||
|
struct nouveau_grobj *sifm = screen->sifm;
|
||||||
|
struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE);
|
||||||
|
const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART;
|
||||||
|
/* Max width & height may not be the same on all HW, but must be POT */
|
||||||
|
const unsigned max_w = 1024;
|
||||||
|
const unsigned max_h = 1024;
|
||||||
|
unsigned sub_w = w > max_w ? max_w : w;
|
||||||
|
unsigned sub_h = h > max_h ? max_h : h;
|
||||||
|
unsigned x, y;
|
||||||
|
|
||||||
|
/* Swizzled surfaces must be POT */
|
||||||
|
assert(_mesa_is_pow_two(dst->width) &&
|
||||||
|
_mesa_is_pow_two(dst->height));
|
||||||
|
|
||||||
|
/* If area is too large to copy in one shot we must copy it in
|
||||||
|
* POT chunks to meet alignment requirements */
|
||||||
|
assert(sub_w == w || _mesa_is_pow_two(sub_w));
|
||||||
|
assert(sub_h == h || _mesa_is_pow_two(sub_h));
|
||||||
|
|
||||||
|
nouveau_bo_marko(bctx, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE,
|
||||||
|
src->bo, bo_flags | NOUVEAU_BO_RD);
|
||||||
|
nouveau_bo_marko(bctx, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE,
|
||||||
|
dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||||
|
nouveau_bo_markl(bctx, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET,
|
||||||
|
dst->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1);
|
||||||
|
OUT_RING (chan, swzsurf_format(dst->format) |
|
||||||
|
log2i(dst->width) << 16 |
|
||||||
|
log2i(dst->height) << 24);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1);
|
||||||
|
OUT_RING (chan, swzsurf->handle);
|
||||||
|
|
||||||
|
for (y = 0; y < h; y += sub_h) {
|
||||||
|
sub_h = MIN2(sub_h, h - y);
|
||||||
|
|
||||||
|
for (x = 0; x < w; x += sub_w) {
|
||||||
|
sub_w = MIN2(sub_w, w - x);
|
||||||
|
/* Must be 64-byte aligned */
|
||||||
|
assert(!(dst->offset & 63));
|
||||||
|
|
||||||
|
MARK_RING(chan, 15, 1);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, sifm,
|
||||||
|
NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 8);
|
||||||
|
OUT_RING(chan, sifm_format(src->format));
|
||||||
|
OUT_RING(chan, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
|
||||||
|
OUT_RING(chan, (y + dy) << 16 | (x + dx));
|
||||||
|
OUT_RING(chan, sub_h << 16 | sub_w);
|
||||||
|
OUT_RING(chan, (y + dy) << 16 | (x + dx));
|
||||||
|
OUT_RING(chan, sub_h << 16 | sub_w);
|
||||||
|
OUT_RING(chan, 1 << 20);
|
||||||
|
OUT_RING(chan, 1 << 20);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, sifm,
|
||||||
|
NV03_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
|
||||||
|
OUT_RING(chan, sub_h << 16 | sub_w);
|
||||||
|
OUT_RING(chan, src->pitch |
|
||||||
|
NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
|
||||||
|
NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
|
||||||
|
OUT_RELOCl(chan, src->bo, src->offset +
|
||||||
|
(y + sy) * src->pitch +
|
||||||
|
(x + sx) * src->cpp,
|
||||||
|
bo_flags | NOUVEAU_BO_RD);
|
||||||
|
OUT_RING(chan, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nouveau_bo_context_reset(bctx);
|
||||||
|
|
||||||
|
if (context_chipset(ctx) < 0x10)
|
||||||
|
FIRE_RING(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nv04_surface_copy_m2mf(GLcontext *ctx,
|
||||||
|
struct nouveau_surface *dst,
|
||||||
|
struct nouveau_surface *src,
|
||||||
|
int dx, int dy, int sx, int sy,
|
||||||
|
int w, int h)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_screen *screen = to_nouveau_context(ctx)->screen;
|
||||||
|
struct nouveau_grobj *m2mf = screen->m2mf;
|
||||||
|
struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE);
|
||||||
|
const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART;
|
||||||
|
unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp;
|
||||||
|
unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp;
|
||||||
|
|
||||||
|
nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN,
|
||||||
|
src->bo, bo_flags | NOUVEAU_BO_RD);
|
||||||
|
nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_OUT,
|
||||||
|
dst->bo, bo_flags | NOUVEAU_BO_WR);
|
||||||
|
|
||||||
|
while (h) {
|
||||||
|
int count = (h > 2047) ? 2047 : h;
|
||||||
|
|
||||||
|
MARK_RING(chan, 9, 2);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
|
||||||
|
OUT_RELOCl(chan, src->bo, src_offset,
|
||||||
|
bo_flags | NOUVEAU_BO_RD);
|
||||||
|
OUT_RELOCl(chan, dst->bo, dst_offset,
|
||||||
|
bo_flags | NOUVEAU_BO_WR);
|
||||||
|
OUT_RING (chan, src->pitch);
|
||||||
|
OUT_RING (chan, dst->pitch);
|
||||||
|
OUT_RING (chan, w * src->cpp);
|
||||||
|
OUT_RING (chan, count);
|
||||||
|
OUT_RING (chan, 0x0101);
|
||||||
|
OUT_RING (chan, 0);
|
||||||
|
|
||||||
|
h -= count;
|
||||||
|
src_offset += src->pitch * count;
|
||||||
|
dst_offset += dst->pitch * count;
|
||||||
|
}
|
||||||
|
|
||||||
|
nouveau_bo_context_reset(bctx);
|
||||||
|
|
||||||
|
if (context_chipset(ctx) < 0x10)
|
||||||
|
FIRE_RING(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_surface_copy(GLcontext *ctx,
|
||||||
|
struct nouveau_surface *dst,
|
||||||
|
struct nouveau_surface *src,
|
||||||
|
int dx, int dy, int sx, int sy,
|
||||||
|
int w, int h)
|
||||||
|
{
|
||||||
|
/* Setup transfer to swizzle the texture to vram if needed */
|
||||||
|
if (src->layout != SWIZZLED &&
|
||||||
|
dst->layout == SWIZZLED &&
|
||||||
|
dst->width > 2 && dst->height > 1) {
|
||||||
|
nv04_surface_copy_swizzle(ctx, dst, src,
|
||||||
|
dx, dy, sx, sy, w, h);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nv04_surface_copy_m2mf(ctx, dst, src, dx, dy, sx, sy, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_surface_fill(GLcontext *ctx,
|
||||||
|
struct nouveau_surface *dst,
|
||||||
|
unsigned mask, unsigned value,
|
||||||
|
int dx, int dy, int w, int h)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_screen *screen = to_nouveau_context(ctx)->screen;
|
||||||
|
struct nouveau_grobj *surf2d = screen->surf2d;
|
||||||
|
struct nouveau_grobj *patt = screen->patt;
|
||||||
|
struct nouveau_grobj *rect = screen->rect;
|
||||||
|
unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART;
|
||||||
|
|
||||||
|
MARK_RING (chan, 19, 4);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
|
||||||
|
OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR);
|
||||||
|
OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR);
|
||||||
|
BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
|
||||||
|
OUT_RING (chan, surf2d_format(dst->format));
|
||||||
|
OUT_RING (chan, (dst->pitch << 16) | dst->pitch);
|
||||||
|
OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR);
|
||||||
|
OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_COLOR_FORMAT, 1);
|
||||||
|
OUT_RING (chan, rect_format(dst->format));
|
||||||
|
BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_COLOR1, 1);
|
||||||
|
OUT_RING (chan, mask | ~0 << (8 * dst->cpp));
|
||||||
|
|
||||||
|
BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1);
|
||||||
|
OUT_RING (chan, rect_format(dst->format));
|
||||||
|
BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
|
||||||
|
OUT_RING (chan, value);
|
||||||
|
BEGIN_RING(chan, rect,
|
||||||
|
NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2);
|
||||||
|
OUT_RING (chan, (dx << 16) | dy);
|
||||||
|
OUT_RING (chan, ( w << 16) | h);
|
||||||
|
|
||||||
|
if (context_chipset(ctx) < 0x10)
|
||||||
|
FIRE_RING(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv04_surface_takedown(struct nouveau_screen *screen)
|
||||||
|
{
|
||||||
|
nouveau_grobj_free(&screen->swzsurf);
|
||||||
|
nouveau_grobj_free(&screen->sifm);
|
||||||
|
nouveau_grobj_free(&screen->rect);
|
||||||
|
nouveau_grobj_free(&screen->rop);
|
||||||
|
nouveau_grobj_free(&screen->patt);
|
||||||
|
nouveau_grobj_free(&screen->surf2d);
|
||||||
|
nouveau_grobj_free(&screen->m2mf);
|
||||||
|
nouveau_notifier_free(&screen->ntfy);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean
|
||||||
|
nv04_surface_init(struct nouveau_screen *screen)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = screen->chan;
|
||||||
|
const unsigned chipset = screen->device->chipset;
|
||||||
|
unsigned handle = 0x88000000, class;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Notifier object. */
|
||||||
|
ret = nouveau_notifier_alloc(chan, handle++, 1, &screen->ntfy);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* Memory to memory format. */
|
||||||
|
ret = nouveau_grobj_alloc(chan, handle++, NV04_MEMORY_TO_MEMORY_FORMAT,
|
||||||
|
&screen->m2mf);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
BEGIN_RING(chan, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
|
||||||
|
OUT_RING (chan, screen->ntfy->handle);
|
||||||
|
|
||||||
|
/* Context surfaces 2D. */
|
||||||
|
if (chan->device->chipset < 0x10)
|
||||||
|
class = NV04_CONTEXT_SURFACES_2D;
|
||||||
|
else
|
||||||
|
class = NV10_CONTEXT_SURFACES_2D;
|
||||||
|
|
||||||
|
ret = nouveau_grobj_alloc(chan, handle++, class, &screen->surf2d);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* Raster op. */
|
||||||
|
ret = nouveau_grobj_alloc(chan, handle++, NV03_CONTEXT_ROP,
|
||||||
|
&screen->rop);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1);
|
||||||
|
OUT_RING (chan, screen->ntfy->handle);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_ROP, 1);
|
||||||
|
OUT_RING (chan, 0xca); /* DPSDxax in the GDI speech. */
|
||||||
|
|
||||||
|
/* Image pattern. */
|
||||||
|
ret = nouveau_grobj_alloc(chan, handle++, NV04_IMAGE_PATTERN,
|
||||||
|
&screen->patt);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
BEGIN_RING(chan, screen->patt,
|
||||||
|
NV04_IMAGE_PATTERN_DMA_NOTIFY, 1);
|
||||||
|
OUT_RING (chan, screen->ntfy->handle);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, screen->patt,
|
||||||
|
NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3);
|
||||||
|
OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE);
|
||||||
|
OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8);
|
||||||
|
OUT_RING (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, screen->patt,
|
||||||
|
NV04_IMAGE_PATTERN_MONOCHROME_COLOR0, 4);
|
||||||
|
OUT_RING (chan, 0);
|
||||||
|
OUT_RING (chan, 0);
|
||||||
|
OUT_RING (chan, ~0);
|
||||||
|
OUT_RING (chan, ~0);
|
||||||
|
|
||||||
|
/* GDI rectangle text. */
|
||||||
|
ret = nouveau_grobj_alloc(chan, handle++, NV04_GDI_RECTANGLE_TEXT,
|
||||||
|
&screen->rect);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
|
||||||
|
OUT_RING (chan, screen->ntfy->handle);
|
||||||
|
BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
|
||||||
|
OUT_RING (chan, screen->surf2d->handle);
|
||||||
|
BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1);
|
||||||
|
OUT_RING (chan, screen->rop->handle);
|
||||||
|
BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
|
||||||
|
OUT_RING (chan, screen->patt->handle);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
|
||||||
|
OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND);
|
||||||
|
BEGIN_RING(chan, screen->rect,
|
||||||
|
NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
|
||||||
|
OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
|
||||||
|
|
||||||
|
/* Swizzled surface. */
|
||||||
|
switch (chan->device->chipset & 0xf0) {
|
||||||
|
case 0x00:
|
||||||
|
case 0x10:
|
||||||
|
class = NV04_SWIZZLED_SURFACE;
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
class = NV20_SWIZZLED_SURFACE;
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
class = NV30_SWIZZLED_SURFACE;
|
||||||
|
break;
|
||||||
|
case 0x40:
|
||||||
|
case 0x60:
|
||||||
|
class = NV40_SWIZZLED_SURFACE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Famous last words: this really can't happen.. */
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = nouveau_grobj_alloc(chan, handle++, class, &screen->swzsurf);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* Scaled image from memory. */
|
||||||
|
switch (chan->device->chipset & 0xf0) {
|
||||||
|
case 0x10:
|
||||||
|
case 0x20:
|
||||||
|
class = NV10_SCALED_IMAGE_FROM_MEMORY;
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
class = NV30_SCALED_IMAGE_FROM_MEMORY;
|
||||||
|
break;
|
||||||
|
case 0x40:
|
||||||
|
case 0x60:
|
||||||
|
class = NV40_SCALED_IMAGE_FROM_MEMORY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
class = NV04_SCALED_IMAGE_FROM_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = nouveau_grobj_alloc(chan, handle++, class, &screen->sifm);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (chipset >= 0x10) {
|
||||||
|
BEGIN_RING(chan, screen->sifm,
|
||||||
|
NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1);
|
||||||
|
OUT_RING(chan, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
nv04_surface_takedown(screen);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
91
src/mesa/drivers/dri/nouveau/nv10_context.c
Normal file
91
src/mesa/drivers/dri/nouveau/nv10_context.c
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 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 "nouveau_driver.h"
|
||||||
|
#include "nouveau_context.h"
|
||||||
|
#include "nouveau_fbo.h"
|
||||||
|
#include "nouveau_util.h"
|
||||||
|
#include "nouveau_class.h"
|
||||||
|
#include "nv10_driver.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
nv10_clear(GLcontext *ctx, GLbitfield buffers)
|
||||||
|
{
|
||||||
|
struct nouveau_channel *chan = context_chan(ctx);
|
||||||
|
struct nouveau_grobj *celsius = context_eng3d(ctx);
|
||||||
|
struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(
|
||||||
|
ctx->DrawBuffer);
|
||||||
|
|
||||||
|
nouveau_validate_framebuffer(ctx);
|
||||||
|
|
||||||
|
/* Clear the LMA depth buffer, if present. */
|
||||||
|
if ((buffers & BUFFER_BIT_DEPTH) && ctx->Depth.Mask &&
|
||||||
|
nfb->lma_bo) {
|
||||||
|
struct nouveau_surface *s = &to_nouveau_renderbuffer(
|
||||||
|
nfb->base._DepthBuffer->Wrapped)->surface;
|
||||||
|
|
||||||
|
BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_FILL_VALUE, 1);
|
||||||
|
OUT_RING(chan, pack_zs_f(s->format, ctx->Depth.Clear, 0));
|
||||||
|
BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_BUFFER_CLEAR, 1);
|
||||||
|
OUT_RING(chan, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
nouveau_clear(ctx, buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLcontext *
|
||||||
|
nv10_context_create(struct nouveau_screen *screen, const GLvisual *visual,
|
||||||
|
GLcontext *share_ctx)
|
||||||
|
{
|
||||||
|
struct nouveau_context *nctx;
|
||||||
|
GLcontext *ctx;
|
||||||
|
|
||||||
|
nctx = CALLOC_STRUCT(nouveau_context);
|
||||||
|
if (!nctx)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ctx = &nctx->base;
|
||||||
|
nouveau_context_init(ctx, screen, visual, share_ctx);
|
||||||
|
|
||||||
|
ctx->Const.MaxTextureLevels = 12;
|
||||||
|
ctx->Const.MaxTextureCoordUnits = NV10_TEXTURE_UNITS;
|
||||||
|
ctx->Const.MaxTextureImageUnits = NV10_TEXTURE_UNITS;
|
||||||
|
ctx->Const.MaxTextureUnits = NV10_TEXTURE_UNITS;
|
||||||
|
ctx->Const.MaxTextureMaxAnisotropy = 2;
|
||||||
|
ctx->Const.MaxTextureLodBias = 15;
|
||||||
|
ctx->Driver.Clear = nv10_clear;
|
||||||
|
|
||||||
|
nv10_render_init(ctx);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nv10_context_destroy(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
nv10_render_destroy(ctx);
|
||||||
|
FREE(ctx);
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue