summaryrefslogtreecommitdiff
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorJeremy Kolb <jkolb@brandeis.edu>2007-01-21 20:47:10 -0500
committerJeremy Kolb <jkolb@brandeis.edu>2007-01-21 20:47:10 -0500
commit95fc270b06f07268732ade745084410bbc877168 (patch)
tree8666e2d1052afc3881038a34d94ffbf001a2160e /src/mesa/drivers
parentea441355d304ceff0d7eac4e112ed713ea08a43f (diff)
parentd1f0a55af42c8a34c2d59ca003e7d7a8263665fb (diff)
Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/mesa
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/nouveau/Makefile13
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_context.c3
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_context.h18
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_object.c11
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader.c4
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader.h12
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_0.c (renamed from src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c)2
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_1.c304
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_shader_2.c16
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_state.c4
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_state.h1
-rw-r--r--src/mesa/drivers/dri/nouveau/nv04_state.c497
-rw-r--r--src/mesa/drivers/dri/nouveau/nv10_swtcl.c21
-rw-r--r--src/mesa/drivers/dri/nouveau/nv30_vertprog.c7
-rw-r--r--src/mesa/drivers/dri/nouveau/nv40_fragprog.c45
-rw-r--r--src/mesa/drivers/dri/nouveau/nv40_vertprog.c10
16 files changed, 618 insertions, 350 deletions
diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile
index 7ffba27bac..492e743360 100644
--- a/src/mesa/drivers/dri/nouveau/Makefile
+++ b/src/mesa/drivers/dri/nouveau/Makefile
@@ -19,25 +19,26 @@ DRIVER_SOURCES = \
nouveau_screen.c \
nouveau_span.c \
nouveau_state.c \
+ nouveau_state_cache.c \
nouveau_shader.c \
- nouveau_shader_0_arb.c \
+ nouveau_shader_0.c \
nouveau_shader_1.c \
nouveau_shader_2.c \
nouveau_tex.c \
nouveau_swtcl.c \
nouveau_sync.c \
+ nv04_state.c \
nv04_swtcl.c \
- nv10_swtcl.c \
nv10_state.c \
+ nv10_swtcl.c \
nv20_state.c \
- nv30_state.c \
- nv50_state.c \
- nouveau_state_cache.c \
nv20_vertprog.c \
+ nv30_state.c \
nv30_fragprog.c \
nv30_vertprog.c \
nv40_fragprog.c \
- nv40_vertprog.c
+ nv40_vertprog.c \
+ nv50_state.c
C_SOURCES = \
$(COMMON_SOURCES) \
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c
index 79da46fc0b..5db93eb012 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c
@@ -50,6 +50,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "nouveau_msg.h"
#include "nouveau_reg.h"
#include "nouveau_lock.h"
+#include "nv04_swtcl.h"
#include "nv10_swtcl.h"
#include "vblank.h"
@@ -212,7 +213,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
break;
case NV_04:
case NV_05:
- //nv04TriInitFunctions( ctx );
+ nv04TriInitFunctions( ctx );
break;
case NV_10:
case NV_20:
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h
index c7bf387210..bcfbb9fb8d 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_context.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h
@@ -170,15 +170,15 @@ typedef struct nouveau_context {
/* Configuration cache */
driOptionCache optionCache;
- /* vblank stuff */
- uint32_t vblank_flags;
- uint32_t vblank_seq;
-
- GLuint new_state;
- GLuint new_render_state;
- GLuint render_index;
- GLmatrix viewport;
- GLfloat depth_scale;
+ /* vblank stuff */
+ uint32_t vblank_flags;
+ uint32_t vblank_seq;
+
+ GLuint new_state;
+ GLuint new_render_state;
+ GLuint render_index;
+ GLmatrix viewport;
+ GLfloat depth_scale;
}nouveauContextRec, *nouveauContextPtr;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c
index 1558f2963d..26086e16e4 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_object.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c
@@ -62,10 +62,17 @@ void nouveauObjectInit(nouveauContextPtr nmesa)
nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d,
0, 0, 0, 0);
- nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D,
+ if (nmesa->screen->card->type>=NV_10) {
+ nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D,
0, 0, 0, 0);
- nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT,
+ nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT,
NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0);
+ } else {
+ nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D,
+ 0, 0, 0, 0);
+ nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT,
+ NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0);
+ }
nouveauCreateContextObject(nmesa, NvMemFormat,
NV_MEMORY_TO_MEMORY_FORMAT,
0, 0, 0, 0);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c
index dc366b36c0..e4db115362 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c
@@ -111,7 +111,7 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs)
/* Translate to HW format now if necessary */
if (!nvs->translated) {
/* Mesa ASM shader -> nouveauShader */
- if (!nouveau_shader_pass0_arb(ctx, nvs))
+ if (!nouveau_shader_pass0(ctx, nvs))
return GL_FALSE;
/* Basic dead code elimination + register usage info */
if (!nouveau_shader_pass1(nvs))
@@ -187,7 +187,7 @@ nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text)
&nvs->mesa.fp);
}
- nouveau_shader_pass0_arb(ctx, nvs);
+ nouveau_shader_pass0(ctx, nvs);
nouveau_shader_pass1(nvs);
nouveau_shader_pass2(nvs);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
index 08cb7817cf..1a971e56bf 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h
@@ -56,10 +56,6 @@ typedef struct _nouveauShader {
int hw_index_cnt;
} params[NVS_MAX_CONSTS];
- struct {
- int last_use;
- } temps[NVS_MAX_TEMPS];
-
/* Pass-private data */
void *pass_rec;
@@ -275,6 +271,11 @@ struct _nvsFunc {
void (*SetSaturate) (nvsFunc *);
void (*SetLastInst) (nvsFunc *);
+ void (*SetBranchTarget) (nvsFunc *, int addr);
+ void (*SetBranchElse) (nvsFunc *, int addr);
+ void (*SetBranchEnd) (nvsFunc *, int addr);
+ void (*SetLoopParams) (nvsFunc *, int cnt, int init, int inc);
+
int (*HasMergedInst) (nvsFunc *);
int (*IsLastInst) (nvsFunc *);
int (*GetOffsetNext) (nvsFunc *);
@@ -365,8 +366,7 @@ extern void NV40FPInitShaderFuncs(nvsFunc *);
extern void nouveauShaderInitFuncs(GLcontext *ctx);
-extern GLboolean nouveau_shader_pass0_arb(GLcontext *ctx, nouveauShader *nvs);
-extern GLboolean nouveau_shader_pass0_slang(GLcontext *ctx, nouveauShader *nvs);
+extern GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs);
extern GLboolean nouveau_shader_pass1(nvsPtr nvs);
extern GLboolean nouveau_shader_pass2(nvsPtr nvs);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
index afb889d421..34475cad03 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
@@ -666,7 +666,7 @@ pass0_translate_instructions(nouveauShader *nvs)
}
GLboolean
-nouveau_shader_pass0_arb(GLcontext *ctx, nouveauShader *nvs)
+nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
struct gl_program *prog = (struct gl_program*)nvs;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c
index 5de9017f58..90c57d3807 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c
@@ -1,316 +1,12 @@
-/*
- * Copyright (C) 2006 Ben Skeggs.
- *
- * 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.
- *
- */
-
-/*
- * Authors:
- * Ben Skeggs <darktama@iinet.net.au>
- */
-
#include "glheader.h"
#include "macros.h"
#include "enums.h"
#include "nouveau_shader.h"
-#define PASS1_OK 0
-#define PASS1_KILL 1
-#define PASS1_FAIL 2
-
-struct pass1_rec {
- unsigned int temp[NVS_MAX_TEMPS];
- unsigned int result[NVS_MAX_ATTRIBS];
- unsigned int address[NVS_MAX_ADDRESS];
- unsigned int cc[2];
-};
-
-static void
-pass1_remove_fragment(nvsPtr nvs, nvsFragmentList *item)
-{
- if (item->prev) item->prev->next = item->next;
- if (item->next) item->next->prev = item->prev;
- if (nvs->list_head == item) nvs->list_head = item->next;
- if (nvs->list_tail == item) nvs->list_tail = item->prev;
-
- nvs->inst_count--;
-}
-
-static int
-pass1_result_needed(struct pass1_rec *rec, nvsInstruction *inst)
-{
- if (inst->cond_update && rec->cc[inst->cond_reg])
- return 1;
- /* Only write components that are read later */
- if (inst->dest.file == NVS_FILE_TEMP)
- return (inst->mask & rec->temp[inst->dest.index]);
- if (inst->dest.file == NVS_FILE_ADDRESS)
- return (inst->mask & rec->address[inst->dest.index]);
- /* No point writing result components that are written later */
- if (inst->dest.file == NVS_FILE_RESULT)
- return (inst->mask & ~rec->result[inst->dest.index]);
- assert(0);
-}
-
-static void
-pass1_track_result(struct pass1_rec *rec, nvsInstruction *inst)
-{
- if (inst->cond_test)
- rec->cc[inst->cond_reg] = 1;
- if (inst->dest.file == NVS_FILE_TEMP) {
- inst->mask &= rec->temp[inst->dest.index];
- } else if (inst->dest.file == NVS_FILE_RESULT) {
- inst->mask &= ~rec->result[inst->dest.index];
- rec->result[inst->dest.index] |= inst->mask;
- } else if (inst->dest.file == NVS_FILE_ADDRESS) {
- inst->mask &= rec->address[inst->dest.index];
- }
-}
-
-static void
-pass1_track_source(nouveauShader *nvs, nvsInstruction *inst, int pos,
- unsigned int read)
-{
- struct pass1_rec *rec = nvs->pass_rec;
- nvsRegister *src = &inst->src[pos];
- unsigned int really_read = 0;
- int i,sc;
-
- /* Account for swizzling */
- for (i=0; i<4; i++)
- if (read & (1<<i)) really_read |= (1 << src->swizzle[i]);
-
- /* Track register reads */
- if (src->file == NVS_FILE_TEMP) {
- if (nvs->temps[src->index].last_use == -1)
- nvs->temps[src->index].last_use = inst->header.position;
- rec->temp [src->index] |= really_read;
- } else if (src->indexed) {
- rec->address[src->addr_reg] |= (1<<src->addr_comp);
- }
-
- /* Modify swizzle to only access read components */
- /* Find a component that is used.. */
- for (sc=0;sc<4;sc++)
- if (really_read & (1<<sc))
- break;
- /* Now set all unused components to that value */
- for (i=0;i<4;i++)
- if (!(read & (1<<i))) src->swizzle[i] = sc;
-}
-
-static int
-pass1_check_instruction(nouveauShader *nvs, nvsInstruction *inst)
-{
- struct pass1_rec *rec = nvs->pass_rec;
- unsigned int read0, read1, read2;
-
- if (inst->op != NVS_OP_KIL) {
- if (!pass1_result_needed(rec, inst))
- return PASS1_KILL;
- }
- pass1_track_result(rec, inst);
-
- read0 = read1 = read2 = 0;
-
- switch (inst->op) {
- case NVS_OP_FLR:
- case NVS_OP_FRC:
- case NVS_OP_MOV:
- case NVS_OP_SSG:
- case NVS_OP_ARL:
- read0 = inst->mask;
- break;
- case NVS_OP_ADD:
- case NVS_OP_MAX:
- case NVS_OP_MIN:
- case NVS_OP_MUL:
- case NVS_OP_SEQ:
- case NVS_OP_SFL:
- case NVS_OP_SGE:
- case NVS_OP_SGT:
- case NVS_OP_SLE:
- case NVS_OP_SLT:
- case NVS_OP_SNE:
- case NVS_OP_STR:
- case NVS_OP_SUB:
- read0 = inst->mask;
- read1 = inst->mask;
- break;
- case NVS_OP_CMP:
- case NVS_OP_LRP:
- case NVS_OP_MAD:
- read0 = inst->mask;
- read1 = inst->mask;
- read2 = inst->mask;
- break;
- case NVS_OP_XPD:
- if (inst->mask & SMASK_X) read0 |= SMASK_Y|SMASK_Z;
- if (inst->mask & SMASK_Y) read0 |= SMASK_X|SMASK_Z;
- if (inst->mask & SMASK_Z) read0 |= SMASK_X|SMASK_Y;
- read1 = read0;
- break;
- case NVS_OP_COS:
- case NVS_OP_EX2:
- case NVS_OP_EXP:
- case NVS_OP_LG2:
- case NVS_OP_LOG:
- case NVS_OP_RCC:
- case NVS_OP_RCP:
- case NVS_OP_RSQ:
- case NVS_OP_SCS:
- case NVS_OP_SIN:
- read0 = SMASK_X;
- break;
- case NVS_OP_POW:
- read0 = SMASK_X;
- read1 = SMASK_X;
- break;
- case NVS_OP_DIV:
- read0 = inst->mask;
- read1 = SMASK_X;
- break;
- case NVS_OP_DP2:
- read0 = SMASK_X|SMASK_Y;
- read1 = SMASK_X|SMASK_Y;
- break;
- case NVS_OP_DP3:
- case NVS_OP_RFL:
- read0 = SMASK_X|SMASK_Y|SMASK_Z;
- read1 = SMASK_X|SMASK_Y|SMASK_Z;
- break;
- case NVS_OP_DP4:
- read0 = SMASK_ALL;
- read1 = SMASK_ALL;
- break;
- case NVS_OP_DPH:
- read0 = SMASK_X|SMASK_Y|SMASK_Z;
- read1 = SMASK_ALL;
- break;
- case NVS_OP_DST:
- if (inst->mask & SMASK_Y) read0 = read1 = SMASK_Y;
- if (inst->mask & SMASK_Z) read0 |= SMASK_Z;
- if (inst->mask & SMASK_W) read1 |= SMASK_W;
- break;
- case NVS_OP_NRM:
- read0 = SMASK_X|SMASK_Y|SMASK_Z;
- break;
- case NVS_OP_PK2H:
- case NVS_OP_PK2US:
- read0 = SMASK_X|SMASK_Y;
- break;
- case NVS_OP_DDX:
- case NVS_OP_DDY:
- case NVS_OP_UP2H:
- case NVS_OP_UP2US:
- case NVS_OP_PK4B:
- case NVS_OP_PK4UB:
- case NVS_OP_UP4B:
- case NVS_OP_UP4UB:
- read0 = SMASK_ALL;
- break;
- case NVS_OP_X2D:
- read1 = SMASK_X|SMASK_Y;
- if (inst->mask & (SMASK_X|SMASK_Z)) {
- read0 |= SMASK_X;
- read2 |= SMASK_X|SMASK_Y;
- }
- if (inst->mask & (SMASK_Y|SMASK_W)) {
- read0 |= SMASK_Y;
- read2 |= SMASK_Z|SMASK_W;
- }
- break;
- case NVS_OP_LIT:
- read0 |= SMASK_X|SMASK_Y|SMASK_W;
- break;
- case NVS_OP_TEX:
- case NVS_OP_TXP:
- case NVS_OP_TXL:
- case NVS_OP_TXB:
- read0 = SMASK_ALL;
- break;
- case NVS_OP_TXD:
- read0 = SMASK_ALL;
- read1 = SMASK_ALL;
- read2 = SMASK_ALL;
- break;
- case NVS_OP_KIL:
- break;
- default:
- fprintf(stderr, "Unknown sop=%d", inst->op);
- return PASS1_FAIL;
- }
-
- /* Any values that are written by this inst can't have been read further up */
- if (inst->dest.file == NVS_FILE_TEMP)
- rec->temp[inst->dest.index] &= ~inst->mask;
-
- if (read0) pass1_track_source(nvs, inst, 0, read0);
- if (read1) pass1_track_source(nvs, inst, 1, read1);
- if (read2) pass1_track_source(nvs, inst, 2, read2);
-
- return PASS1_OK;
-}
-
-/* Some basic dead code elimination
- * - Remove unused instructions
- * - Don't write unused register components
- * - Modify swizzles to not reference unneeded components.
- */
GLboolean
nouveau_shader_pass1(nvsPtr nvs)
{
- nvsFragmentList *list = nvs->list_tail;
- int i;
-
- for (i=0; i<NVS_MAX_TEMPS; i++)
- nvs->temps[i].last_use = -1;
-
- nvs->pass_rec = calloc(1, sizeof(struct pass1_rec));
-
- while (list) {
- assert(list->fragment->type == NVS_INSTRUCTION);
-
- switch(pass1_check_instruction(nvs, (nvsInstruction *)list->fragment)) {
- case PASS1_OK:
- break;
- case PASS1_KILL:
- pass1_remove_fragment(nvs, list);
- break;
- case PASS1_FAIL:
- default:
- free(nvs->pass_rec);
- nvs->pass_rec = NULL;
- return GL_FALSE;
- }
-
- list = list->prev;
- }
-
- free(nvs->pass_rec);
- nvs->pass_rec = NULL;
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
index 2177413b66..0476b05f58 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c
@@ -68,29 +68,15 @@ pass2_alloc_hw_temp(nvsPtr nvs)
return -1;
}
-static void
-pass2_free_hw_temp(nvsPtr nvs, int reg)
-{
- struct pass2_rec *rec = nvs->pass_rec;
- rec->hw_temps[reg] = 0;
-}
-
static nvsRegister
pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg)
{
struct pass2_rec *rec = nvs->pass_rec;
if (reg.file == NVS_FILE_TEMP) {
- int hwidx;
-
if (rec->temps[reg.index] == -1)
rec->temps[reg.index] = pass2_alloc_hw_temp(nvs);
- hwidx = rec->temps[reg.index];
-
- if (nvs->temps[reg.index].last_use <= inst->header.position)
- pass2_free_hw_temp(nvs, hwidx);
-
- reg.index = hwidx;
+ reg.index = rec->temps[reg.index];
}
return reg;
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c
index 1ff881f054..18f6ffb2ad 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_state.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c
@@ -156,9 +156,11 @@ void nouveauDDInitState(nouveauContextPtr nmesa)
switch(type)
{
case NV_03:
+ /* Unimplemented */
+ break;
case NV_04:
case NV_05:
- /* No TCL engines for these ones */
+ nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
break;
case NV_10:
nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h
index 16d63a6ac2..5b85287445 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_state.h
+++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h
@@ -32,6 +32,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
extern void nouveauDDInitState(nouveauContextPtr nmesa);
extern void nouveauDDInitStateFuncs(GLcontext *ctx);
+extern void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
extern void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
extern void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
extern void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func);
diff --git a/src/mesa/drivers/dri/nouveau/nv04_state.c b/src/mesa/drivers/dri/nouveau/nv04_state.c
new file mode 100644
index 0000000000..83ad8ae432
--- /dev/null
+++ b/src/mesa/drivers/dri/nouveau/nv04_state.c
@@ -0,0 +1,497 @@
+/**************************************************************************
+
+Copyright 2007 Stephane Marchesin
+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
+on 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
+ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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_context.h"
+#include "nouveau_object.h"
+#include "nouveau_fifo.h"
+#include "nouveau_reg.h"
+#include "nouveau_msg.h"
+
+#include "tnl/t_pipeline.h"
+
+#include "mtypes.h"
+#include "colormac.h"
+
+static uint32_t nv04_compare_func(GLcontext *ctx,GLuint f)
+{
+ switch ( ctx->Color.AlphaFunc ) {
+ case GL_NEVER: return 1;
+ case GL_LESS: return 2;
+ case GL_EQUAL: return 3;
+ case GL_LEQUAL: return 4;
+ case GL_GREATER: return 5;
+ case GL_NOTEQUAL: return 6;
+ case GL_GEQUAL: return 7;
+ case GL_ALWAYS: return 8;
+ }
+ WARN_ONCE("Unable to find the function\n");
+ return 0;
+}
+
+static uint32_t nv04_blend_func(GLcontext *ctx,GLuint f)
+{
+ switch ( ctx->Color.AlphaFunc ) {
+ 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;
+ }
+ WARN_ONCE("Unable to find the function\n");
+ return 0;
+}
+
+static void nv04_emit_control(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ uint32_t control,cull;
+ GLubyte alpha_ref;
+
+ CLAMPED_FLOAT_TO_UBYTE(alpha_ref, ctx->Color.AlphaRef);
+ control=alpha_ref;
+ control|=(nv04_compare_func(ctx,ctx->Color.AlphaFunc)<<8);
+ control|=(ctx->Color.AlphaEnabled<<12);
+ control|=(1<<13);
+ control|=(ctx->Depth.Test<<14);
+ control|=(nv04_compare_func(ctx,ctx->Depth.Func)<<16);
+ if ((ctx->Polygon.CullFlag)&&(ctx->Polygon.CullFaceMode!=GL_FRONT_AND_BACK))
+ {
+ if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_FRONT))
+ cull=2;
+ if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_BACK))
+ cull=3;
+ if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_FRONT))
+ cull=3;
+ if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_BACK))
+ cull=2;
+ }
+ else
+ if (ctx->Polygon.CullFaceMode==GL_FRONT_AND_BACK)
+ cull=0;
+ else
+ cull=1;
+ control|=(cull<<20);
+ control|=(ctx->Color.DitherFlag<<22);
+ if ((ctx->Depth.Test)&&(ctx->Depth.Mask))
+ control|=(1<<24);
+
+ control|=(1<<30); // integer zbuffer format
+
+ BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
+ OUT_RING_CACHE(control);
+}
+
+static void nv04_emit_blend(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ uint32_t blend;
+
+ blend=0x4; // texture MODULATE_ALPHA
+ blend|=0x20; // alpha is MSB
+ switch(ctx->Light.ShadeModel) {
+ case GL_SMOOTH:blend|=(1<<6);break;
+ case GL_FLAT: blend|=(2<<6);break;
+ default:break;
+ }
+ if (ctx->Hint.PerspectiveCorrection!=GL_FASTEST)
+ blend|=(1<<8);
+ blend|=(ctx->Fog.Enabled<<16);
+ blend|=(ctx->Color.BlendEnabled<<20);
+ blend|=(nv04_blend_func(ctx,ctx->Color.BlendSrcRGB)<<24);
+ blend|=(nv04_blend_func(ctx,ctx->Color.BlendDstRGB)<<28);
+
+ BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1);
+ OUT_RING_CACHE(blend);
+}
+
+static void nv04_emit_fog_color(GLcontext *ctx)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+ GLubyte c[4];
+ c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] );
+ c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] );
+ c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] );
+ c[3] = FLOAT_TO_UBYTE( ctx->Fog.Color[3] );
+ BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_FOG_COLOR, 1);
+ OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3]));
+}
+
+static void nv04AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
+{
+ nv04_emit_control(ctx);
+}
+
+static void nv04BlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+ nv04_emit_blend(ctx);
+}
+
+static void nv04BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA)
+{
+ nv04_emit_blend(ctx);
+}
+
+
+static void nv04BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ nv04_emit_blend(ctx);
+}
+
+static void nv04Clear(GLcontext *ctx, GLbitfield mask)
+{
+ /* TODO */
+}
+
+static void nv04ClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+ /* TODO */
+}
+
+static void nv04ClearDepth(GLcontext *ctx, GLclampd d)
+{
+ /* TODO */
+}
+
+static void nv04ClearStencil(GLcontext *ctx, GLint s)
+{
+ /* TODO */
+}
+
+static void nv04ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
+{
+ /* TODO */
+}
+
+static void nv04ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask,
+ GLboolean bmask, GLboolean amask )
+{
+ /* TODO */
+}
+
+static void nv04ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ /* TODO I need love */
+}
+
+static void nv04CullFace(GLcontext *ctx, GLenum mode)
+{
+ nv04_emit_control(ctx);
+}
+
+static void nv04FrontFace(GLcontext *ctx, GLenum mode)
+{
+ /* TODO */
+}
+
+static void nv04DepthFunc(GLcontext *ctx, GLenum func)
+{
+ nv04_emit_control(ctx);
+}
+
+static void nv04DepthMask(GLcontext *ctx, GLboolean flag)
+{
+ /* TODO */
+}
+
+static void nv04DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
+{
+ /* TODO */
+}
+
+/** Specify the current buffer for writing */
+//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer );
+/** Specify the buffers for writing for fragment programs*/
+//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers );
+
+static void nv04Enable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ switch(cap)
+ {
+ case GL_ALPHA_TEST:
+ nv04_emit_control(ctx);
+ break;
+// case GL_AUTO_NORMAL:
+ case GL_BLEND:
+ nv04_emit_blend(ctx);
+ break;
+// case GL_CLIP_PLANE0:
+// case GL_CLIP_PLANE1:
+// case GL_CLIP_PLANE2:
+// case GL_CLIP_PLANE3:
+// case GL_CLIP_PLANE4:
+// case GL_CLIP_PLANE5:
+// case GL_COLOR_LOGIC_OP:
+// case GL_COLOR_MATERIAL:
+// case GL_COLOR_SUM_EXT:
+// case GL_COLOR_TABLE:
+// case GL_CONVOLUTION_1D:
+// case GL_CONVOLUTION_2D:
+ case GL_CULL_FACE:
+ nv04_emit_control(ctx);
+ break;
+ case GL_DEPTH_TEST:
+ nv04_emit_control(ctx);
+ break;
+ case GL_DITHER:
+ nv04_emit_control(ctx);
+ break;
+ case GL_FOG:
+ nv04_emit_blend(ctx);
+ break;
+// case GL_HISTOGRAM:
+// case GL_INDEX_LOGIC_OP:
+// case GL_LIGHT0:
+// case GL_LIGHT1:
+// case GL_LIGHT2:
+// case GL_LIGHT3:
+// case GL_LIGHT4:
+// case GL_LIGHT5:
+// case GL_LIGHT6:
+// case GL_LIGHT7:
+// case GL_LIGHTING:
+// case GL_LINE_SMOOTH:
+// case GL_LINE_STIPPLE:
+// case GL_MAP1_COLOR_4:
+// case GL_MAP1_INDEX:
+// case GL_MAP1_NORMAL:
+// case GL_MAP1_TEXTURE_COORD_1:
+// case GL_MAP1_TEXTURE_COORD_2:
+// case GL_MAP1_TEXTURE_COORD_3:
+// case GL_MAP1_TEXTURE_COORD_4:
+// case GL_MAP1_VERTEX_3:
+// case GL_MAP1_VERTEX_4:
+// case GL_MAP2_COLOR_4:
+// case GL_MAP2_INDEX:
+// case GL_MAP2_NORMAL:
+// case GL_MAP2_TEXTURE_COORD_1:
+// case GL_MAP2_TEXTURE_COORD_2:
+// case GL_MAP2_TEXTURE_COORD_3:
+// case GL_MAP2_TEXTURE_COORD_4:
+// case GL_MAP2_VERTEX_3:
+// case GL_MAP2_VERTEX_4:
+// case GL_MINMAX:
+// case GL_NORMALIZE:
+// case GL_POINT_SMOOTH:
+// case GL_POLYGON_OFFSET_POINT:
+// case GL_POLYGON_OFFSET_LINE:
+// case GL_POLYGON_OFFSET_FILL:
+// case GL_POLYGON_SMOOTH:
+// case GL_POLYGON_STIPPLE:
+// case GL_POST_COLOR_MATRIX_COLOR_TABLE:
+// case GL_POST_CONVOLUTION_COLOR_TABLE:
+// case GL_RESCALE_NORMAL:
+// case GL_SCISSOR_TEST:
+// case GL_SEPARABLE_2D:
+// case GL_STENCIL_TEST:
+// case GL_TEXTURE_GEN_Q:
+// case GL_TEXTURE_GEN_R:
+// case GL_TEXTURE_GEN_S:
+// case GL_TEXTURE_GEN_T:
+// case GL_TEXTURE_1D:
+// case GL_TEXTURE_2D:
+// case GL_TEXTURE_3D:
+ }
+}
+
+static void nv04Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ nv04_emit_blend(ctx);
+ nv04_emit_fog_color(ctx);
+}
+
+static void nv04Hint(GLcontext *ctx, GLenum target, GLenum mode)
+{
+ switch(target)
+ {
+ case GL_PERSPECTIVE_CORRECTION_HINT:nv04_emit_blend(ctx);break;
+ default:break;
+ }
+}
+
+static void nv04LineStipple(GLcontext *ctx, GLint factor, GLushort pattern )
+{
+ /* TODO not even in your dreams */
+}
+
+static void nv04LineWidth(GLcontext *ctx, GLfloat width)
+{
+ /* TODO */
+}
+
+static void nv04LogicOpcode(GLcontext *ctx, GLenum opcode)
+{
+ /* TODO */
+}
+
+static void nv04PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+ /* TODO */
+}
+
+static void nv04PointSize(GLcontext *ctx, GLfloat size)
+{
+ /* TODO */
+}
+
+static void nv04PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+ /* TODO */
+}
+
+/** Set the scale and units used to calculate depth values */
+static void nv04PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units)
+{
+ /* TODO */
+}
+
+/** Set the polygon stippling pattern */
+static void nv04PolygonStipple(GLcontext *ctx, const GLubyte *mask )
+{
+ /* TODO */
+}
+
+/* Specifies the current buffer for reading */
+void (*ReadBuffer)( GLcontext *ctx, GLenum buffer );
+/** Set rasterization mode */
+void (*RenderMode)(GLcontext *ctx, GLenum mode );
+
+/** Define the scissor box */
+static void nv04Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ /* TODO */
+}
+
+/** Select flat or smooth shading */
+static void nv04ShadeModel(GLcontext *ctx, GLenum mode)
+{
+ nv04_emit_blend(ctx);
+}
+
+/** OpenGL 2.0 two-sided StencilFunc */
+static void nv04StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask)
+{
+ /* TODO */
+}
+
+/** OpenGL 2.0 two-sided StencilMask */
+static void nv04StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
+{
+ /* TODO */
+}
+
+/** OpenGL 2.0 two-sided StencilOp */
+static void nv04StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass)
+{
+ /* TODO */
+}
+
+/** Control the generation of texture coordinates */
+void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname,
+ const GLfloat *params);
+/** Set texture environment parameters */
+void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname,
+ const GLfloat *param);
+/** Set texture parameters */
+void (*TexParameter)(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat *params);
+
+/* Update anything that depends on the window position/size */
+static void nv04WindowMoved(nouveauContextPtr nmesa)
+{
+}
+
+/* Initialise any card-specific non-GL related state */
+static GLboolean nv04InitCard(nouveauContextPtr nmesa)
+{
+ return GL_TRUE;
+}
+
+/* Update buffer offset/pitch/format */
+static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color,
+ nouveau_renderbuffer **color,
+ nouveau_renderbuffer *depth)
+{
+ return GL_TRUE;
+}
+
+void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func)
+{
+ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+ func->AlphaFunc = nv04AlphaFunc;
+ func->BlendColor = nv04BlendColor;
+ func->BlendEquationSeparate = nv04BlendEquationSeparate;
+ func->BlendFuncSeparate = nv04BlendFuncSeparate;
+ func->Clear = nv04Clear;
+ func->ClearColor = nv04ClearColor;
+ func->ClearDepth = nv04ClearDepth;
+ func->ClearStencil = nv04ClearStencil;
+ func->ClipPlane = nv04ClipPlane;
+ func->ColorMask = nv04ColorMask;
+ func->ColorMaterial = nv04ColorMaterial;
+ func->CullFace = nv04CullFace;
+ func->FrontFace = nv04FrontFace;
+ func->DepthFunc = nv04DepthFunc;
+ func->DepthMask = nv04DepthMask;
+ func->DepthRange = nv04DepthRange;
+ func->Enable = nv04Enable;
+ func->Fogfv = nv04Fogfv;
+ func->Hint = nv04Hint;
+/* func->Lightfv = nv04Lightfv;*/
+/* func->LightModelfv = nv04LightModelfv; */
+ func->LineStipple = nv04LineStipple; /* Not for NV04 */
+ func->LineWidth = nv04LineWidth;
+ func->LogicOpcode = nv04LogicOpcode;
+ func->PointParameterfv = nv04PointParameterfv;
+ func->PointSize = nv04PointSize;
+ func->PolygonMode = nv04PolygonMode;
+ func->PolygonOffset = nv04PolygonOffset;
+ func->PolygonStipple = nv04PolygonStipple; /* Not for NV04 */
+/* func->ReadBuffer = nv04ReadBuffer;*/
+/* func->RenderMode = nv04RenderMode;*/
+ func->Scissor = nv04Scissor;
+ func->ShadeModel = nv04ShadeModel;
+ func->StencilFuncSeparate = nv04StencilFuncSeparate;
+ func->StencilMaskSeparate = nv04StencilMaskSeparate;
+ func->StencilOpSeparate = nv04StencilOpSeparate;
+/* func->TexGen = nv04TexGen;*/
+/* func->TexParameter = nv04TexParameter;*/
+/* func->TextureMatrix = nv04TextureMatrix;*/
+
+ nmesa->hw_func.InitCard = nv04InitCard;
+ nmesa->hw_func.BindBuffers = nv04BindBuffers;
+ nmesa->hw_func.WindowMoved = nv04WindowMoved;
+}
diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
index 12b277de45..f916912c7e 100644
--- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
+++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c
@@ -23,7 +23,7 @@
* DEALINGS IN THE SOFTWARE.
*/
-/* Software TCL for NV10, NV20, NV30, NV40, G70 */
+/* Software TCL for NV10, NV20, NV30, NV40, NV50 */
#include <stdio.h>
#include <math.h>
@@ -288,6 +288,20 @@ do { \
nmesa->vertex_attr_count++; \
} while (0)
+static void nv10_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj)
+{
+
+}
+
+static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ GLuint *tmp = VB->Elts;
+ VB->Elts = (GLuint *)elts;
+ nv10_render_generic_primitive_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END,GL_POLYGON );
+ VB->Elts = tmp;
+}
static void nv10ChooseRenderState(GLcontext *ctx)
{
@@ -296,8 +310,8 @@ static void nv10ChooseRenderState(GLcontext *ctx)
tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts;
tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts;
- tnl->Driver.Render.ClippedLine = NULL;
- tnl->Driver.Render.ClippedPolygon = NULL;
+ tnl->Driver.Render.ClippedLine = nv10_render_clipped_line;
+ tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly;
}
@@ -323,6 +337,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa)
0.0, 0.0, 0.0, 1.0
};
+ nmesa->vertex_attr_count = 0;
RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset);
/*
diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
index 6ba8e35d55..0b7678f55d 100644
--- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
+++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c
@@ -48,6 +48,12 @@ NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
/*****************************************************************************
* Assembly routines
*/
+static void
+NV30VPSetBranchTarget(nvsFunc *shader, int addr)
+{
+ shader->inst[2] &= ~NV30_VP_INST_IADDR_MASK;
+ shader->inst[2] |= (addr << NV30_VP_INST_IADDR_SHIFT);
+}
/*****************************************************************************
* Disassembly routines
@@ -349,5 +355,6 @@ NV30VPInitShaderFuncs(nvsFunc * shader)
shader->GetCondRegID = NV30VPGetCondRegID;
shader->GetBranch = NV30VPGetBranch;
+ shader->SetBranchTarget = NV30VPSetBranchTarget;
}
diff --git a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c
index 3d58d6b666..8bca6ae938 100644
--- a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c
+++ b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c
@@ -5,6 +5,47 @@
unsigned int NVFP_TX_BOP_COUNT = 5;
struct _op_xlat NVFP_TX_BOP[64];
+
+/*****************************************************************************
+ * Assembly routines
+ * - These extend the NV30 routines, which are almost identical. NV40
+ * just has branching hacked into the instruction set.
+ */
+static void
+NV40FPSetBranchTarget(nvsFunc *shader, int addr)
+{
+ shader->inst[2] &= ~NV40_FP_OP_IADDR_MASK;
+ shader->inst[2] |= (addr << NV40_FP_OP_IADDR_SHIFT);
+}
+
+static void
+NV40FPSetBranchElse(nvsFunc *shader, int addr)
+{
+ shader->inst[2] &= ~NV40_FP_OP_ELSE_ID_MASK;
+ shader->inst[2] |= (addr << NV40_FP_OP_ELSE_ID_SHIFT);
+}
+
+static void
+NV40FPSetBranchEnd(nvsFunc *shader, int addr)
+{
+ shader->inst[3] &= ~NV40_FP_OP_END_ID_MASK;
+ shader->inst[3] |= (addr << NV40_FP_OP_END_ID_SHIFT);
+}
+
+static void
+NV40FPSetLoopParams(nvsFunc *shader, int count, int initial, int increment)
+{
+ shader->inst[2] &= ~(NV40_FP_OP_LOOP_COUNT_MASK |
+ NV40_FP_OP_LOOP_INDEX_MASK |
+ NV40_FP_OP_LOOP_INCR_MASK);
+ shader->inst[2] |= ((count << NV40_FP_OP_LOOP_COUNT_SHIFT) |
+ (initial << NV40_FP_OP_LOOP_INDEX_SHIFT) |
+ (increment << NV40_FP_OP_LOOP_INCR_SHIFT));
+}
+
+/*****************************************************************************
+ * Disassembly routines
+ */
static struct _op_xlat *
NV40FPGetOPTXRec(nvsFunc * shader, int merged)
{
@@ -149,4 +190,8 @@ NV40FPInitShaderFuncs(nvsFunc * shader)
shader->GetLoopCount = NV40FPGetLoopCount;
shader->GetLoopInitial = NV40FPGetLoopInitial;
shader->GetLoopIncrement = NV40FPGetLoopIncrement;
+ shader->SetBranchTarget = NV40FPSetBranchTarget;
+ shader->SetBranchElse = NV40FPSetBranchElse;
+ shader->SetBranchEnd = NV40FPSetBranchEnd;
+ shader->SetLoopParams = NV40FPSetLoopParams;
}
diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
index 0493e18403..1ba1cfd155 100644
--- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
+++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c
@@ -228,6 +228,15 @@ NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos)
}
static void
+NV40VPSetBranchTarget(nvsFunc *shader, int addr)
+{
+ shader->inst[2] &= ~NV40_VP_INST_IADDRH_MASK;
+ shader->inst[2] |= ((addr & 0xf8) >> 3) << NV40_VP_INST_IADDRH_SHIFT;
+ shader->inst[3] &= ~NV40_VP_INST_IADDRL_MASK;
+ shader->inst[3] |= ((addr & 0x07) << NV40_VP_INST_IADDRL_SHIFT);
+}
+
+static void
NV40VPInitInstruction(nvsFunc *shader)
{
unsigned int hwsrc = 0;
@@ -657,6 +666,7 @@ NV40VPInitShaderFuncs(nvsFunc * shader)
shader->SetResult = NV40VPSetResult;
shader->SetSource = NV40VPSetSource;
shader->SetLastInst = NV40VPSetLastInst;
+ shader->SetBranchTarget = NV40VPSetBranchTarget;
shader->HasMergedInst = NV40VPHasMergedInst;
shader->GetOpcodeHW = NV40VPGetOpcodeHW;