diff options
Diffstat (limited to 'src/mesa/drivers')
21 files changed, 721 insertions, 124 deletions
diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 3c8c6c256e6..ebcbfbcc651 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -1,18 +1,19 @@ /* - * Copyright (C) 2004-2006 Claudio Ciccani <[email protected]> + * Copyright (C) 2004-2007 Claudio Ciccani <[email protected]> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * Based on glfbdev.c, written by Brian Paul. diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h index d6d51cdd165..c7984964255 100644 --- a/src/mesa/drivers/dri/common/extension_helper.h +++ b/src/mesa/drivers/dri/common/extension_helper.h @@ -2466,10 +2466,10 @@ static const char MultiTexCoord4ivARB_names[] = ""; #endif -#if defined(need_GL_VERSION_2_0) -static const char GetVertexAttribPointervARB_names[] = - "iip\0" /* Parameter signature */ - "glGetVertexAttribPointerv\0" +#if defined(need_GL_EXT_gpu_program_parameters) +static const char ProgramLocalParameters4fvEXT_names[] = + "iiip\0" /* Parameter signature */ + "glProgramLocalParameters4fvEXT\0" ""; #endif @@ -3152,13 +3152,6 @@ static const char VertexAttribPointerNV_names[] = ""; #endif -#if defined(need_GL_EXT_gpu_program_parameters) -static const char ProgramLocalParameters4fvEXT_names[] = - "iiip\0" /* Parameter signature */ - "glProgramLocalParameters4fvEXT\0" - ""; -#endif - #if defined(need_GL_EXT_framebuffer_object) static const char GetFramebufferAttachmentParameterivEXT_names[] = "iiip\0" /* Parameter signature */ @@ -3781,9 +3774,10 @@ static const char ReplacementCodeuiColor3fVertex3fSUN_names[] = ""; #endif -#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) static const char GetVertexAttribPointervNV_names[] = "iip\0" /* Parameter signature */ + "glGetVertexAttribPointerv\0" "glGetVertexAttribPointervARB\0" "glGetVertexAttribPointervNV\0" ""; @@ -5343,8 +5337,8 @@ static const struct dri_extension_function GL_EXT_framebuffer_object_functions[] #if defined(need_GL_EXT_gpu_program_parameters) static const struct dri_extension_function GL_EXT_gpu_program_parameters_functions[] = { - { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 }, { ProgramLocalParameters4fvEXT_names, ProgramLocalParameters4fvEXT_remap_index, -1 }, + { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 }, { NULL, 0, 0 } }; #endif @@ -6263,7 +6257,6 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 }, { GetAttribLocationARB_names, GetAttribLocationARB_remap_index, -1 }, { Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 }, - { GetVertexAttribPointervARB_names, GetVertexAttribPointervARB_remap_index, -1 }, { VertexAttrib4sARB_names, VertexAttrib4sARB_remap_index, -1 }, { VertexAttrib2dvARB_names, VertexAttrib2dvARB_remap_index, -1 }, { VertexAttrib2fvARB_names, VertexAttrib2fvARB_remap_index, -1 }, @@ -6295,6 +6288,7 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { Uniform4iARB_names, Uniform4iARB_remap_index, -1 }, { UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 }, { DeleteProgram_names, DeleteProgram_remap_index, -1 }, + { GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 }, { Uniform2iARB_names, Uniform2iARB_remap_index, -1 }, { VertexAttrib4dARB_names, VertexAttrib4dARB_remap_index, -1 }, { GetUniformLocationARB_names, GetUniformLocationARB_remap_index, -1 }, diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 492e743360a..20d2de5eefb 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -27,6 +27,7 @@ DRIVER_SOURCES = \ nouveau_tex.c \ nouveau_swtcl.c \ nouveau_sync.c \ + nouveau_query.c \ nv04_state.c \ nv04_swtcl.c \ nv10_state.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 5db93eb0124..e18cebcd291 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 "nouveau_query.h" #include "nv04_swtcl.h" #include "nv10_swtcl.h" @@ -71,6 +72,7 @@ static const struct dri_debug_control debug_control[] = }; #define need_GL_ARB_vertex_program +#define need_GL_ARB_occlusion_query #include "extension_helper.h" const struct dri_extension common_extensions[] = @@ -100,6 +102,7 @@ const struct dri_extension nv40_extensions[] = * written for those cards. */ { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, { NULL, 0 } }; @@ -229,6 +232,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nouveauInitBufferObjects(ctx); if (!nouveauSyncInitFuncs(ctx)) return GL_FALSE; + nouveauQueryInitFuncs(ctx); nmesa->hw_func.InitCard(nmesa); nouveauInitState(ctx); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index bcfbb9fb8d2..c1d06654ee9 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -105,6 +105,11 @@ typedef struct nouveau_context { /* Channel synchronisation */ nouveau_notifier *syncNotifier; + /* ARB_occlusion_query / EXT_timer_query */ + GLuint query_object_max; + GLboolean * query_alloc; + nouveau_notifier *queryNotifier; + /* Additional hw-specific functions */ nouveau_hw_func hw_func; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 9056bfb2557..490089f71a4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -33,15 +33,30 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_ctrlreg.h" #include "nouveau_state_cache.h" +//#define NOUVEAU_RING_TRACE //#define NOUVEAU_RING_DEBUG //#define NOUVEAU_STATE_CACHE_DISABLE +#ifndef NOUVEAU_RING_TRACE +#define NOUVEAU_RING_TRACE 0 +#else +#undef NOUVEAU_RING_TRACE +#define NOUVEAU_RING_TRACE 1 +#endif + #define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg)) #define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) #define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) = value; #define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.put_base) >> 2) -#define NV_FIFO_WRITE_PUT(val) NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base) +#define NV_FIFO_WRITE_PUT(val) do { \ + if (NOUVEAU_RING_TRACE) {\ + printf("FIRE_RING : 0x%08x\n", nmesa->fifo.current << 2); \ + fflush(stdout); \ + sleep(1); \ + } \ + NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base); \ +} while(0) /* * Ring/fifo interface @@ -75,15 +90,23 @@ int i; printf("OUT_RINGp: (size 0x%x dwords)\n",sz); for(i=0;i<sz;i++) printf(" #else #define OUT_RINGp(ptr,sz) do{ \ + if (NOUVEAU_RING_TRACE) { \ + uint32_t* p=(uint32_t*)(ptr); \ + int i; printf("OUT_RINGp: (size 0x%x dwords) (%s)\n",sz, __func__); for(i=0;i<sz;i++) printf(" [0x%08x] 0x%08x %f\n", (nmesa->fifo.current+i) << 2, *(p+i), *((float*)(p+i))); \ + } \ memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,(sz)*4); \ nmesa->fifo.current+=(sz); \ }while(0) #define OUT_RING(n) do { \ +if (NOUVEAU_RING_TRACE) \ + printf("OUT_RINGn: [0x%08x] 0x%08x (%s)\n", nmesa->fifo.current << 2, n, __func__); \ nmesa->fifo.buffer[nmesa->fifo.current++]=(n); \ }while(0) #define OUT_RINGf(n) do { \ +if (NOUVEAU_RING_TRACE) \ + printf("OUT_RINGf: [0x%08x] %.04f (%s)\n", nmesa->fifo.current << 2, n, __func__); \ *((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=(n); \ }while(0) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index 26086e16e43..302009c8b17 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -70,6 +70,8 @@ void nouveauObjectInit(nouveauContextPtr nmesa) } else { nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D, 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D, + 0, 0, 0, 0); nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT, NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index b1ff5a5d0dc..daad281029f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -12,15 +12,18 @@ enum DMAObjects { NvCtxSurf2D = 0x80000020, NvImageBlit = 0x80000021, NvMemFormat = 0x80000022, + NvCtxSurf3D = 0x80000023, NvDmaFB = 0xD0FB0001, NvDmaAGP = 0xD0AA0001, - NvSyncNotify = 0xD0000001 + NvSyncNotify = 0xD0000001, + NvQueryNotify = 0xD0000002 }; enum DMASubchannel { NvSubCtxSurf2D = 0, NvSubImageBlit = 1, NvSubMemFormat = 2, + NvSubCtxSurf3D = 3, NvSub3D = 7, }; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.c b/src/mesa/drivers/dri/nouveau/nouveau_query.c new file mode 100644 index 00000000000..de3f5b0378b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2007 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. + * + */ + +/* GL_ARB_occlusion_query support for NV20/30/40 */ + +#include "mtypes.h" + +#include "nouveau_fifo.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" +#include "nouveau_reg.h" +#include "nouveau_sync.h" +#include "nouveau_query.h" + +static struct gl_query_object * +nouveauNewQueryObject(GLcontext *ctx, GLuint id) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq; + int i; + + for (i=0; i<nmesa->query_object_max; i++) + if (nmesa->query_alloc[i] == GL_FALSE) + break; + if (i==nmesa->query_object_max) + return NULL; + + nq = CALLOC_STRUCT(nouveau_query_object_t); + if (nq) { + nq->notifier_id = i; + + nq->mesa.Id = id; + nq->mesa.Result = 0; + nq->mesa.Active = GL_FALSE; + nq->mesa.Ready = GL_TRUE; + } + + return (struct gl_query_object *)nq; +} + +static void +nouveauBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + + nouveau_notifier_reset(nmesa->queryNotifier, nq->notifier_id); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_CACHE(NvSub3D, 0x17c8, 1); + OUT_RING_CACHE (1); + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (1); + break; + case NV_30: + case NV_40: + case NV_44: + /* I don't think this is OCC_QUERY enable, but it *is* needed to make + * the SET_OBJECT7 notifier block work with STORE_RESULT. + * + * Also, this appears to reset the pixel pass counter */ + BEGIN_RING_SIZE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE, + 1); + OUT_RING (1); + /* Probably OCC_QUERY_ENABLE */ + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (1); + break; + default: + WARN_ONCE("no support for this card\n"); + break; + } +} + +static void +nouveauUpdateQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + int status; + + status = nouveau_notifier_status(nmesa->queryNotifier, + nq->notifier_id); + + q->Ready = (status == NV_NOTIFY_STATE_STATUS_COMPLETED); + if (q->Ready) + q->Result = nouveau_notifier_return_val(nmesa->queryNotifier, + nq->notifier_id); +} + +static void +nouveauWaitQueryResult(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + + nouveau_notifier_wait_status(nmesa->queryNotifier, nq->notifier_id, + NV_NOTIFY_STATE_STATUS_COMPLETED, 0); + nouveauUpdateQuery(ctx, target, q); +} + +static void +nouveauEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveau_query_object *nq = (nouveau_query_object *)q; + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_SIZE(NvSub3D, 0x17d0, 1); + OUT_RING (0x01000000 | nq->notifier_id*32); + break; + case NV_30: + case NV_40: + case NV_44: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STORE_RESULT, 1); + OUT_RING (0x01000000 | nq->notifier_id*32); + break; + default: + WARN_ONCE("no support for this card\n"); + break; + } + FIRE_RING(); + + /*XXX: wait for query to complete, mesa doesn't give the driver + * an interface to query the status of a query object so + * this has to stall the channel. + */ + nouveauWaitQueryResult(ctx, target, q); + + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (0); +} + +void +nouveauQueryInitFuncs(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->screen->card->type < NV_20) + return; + + nmesa->query_object_max = (0x4000 / 32); + nmesa->queryNotifier = + nouveau_notifier_new(ctx, NvQueryNotify, + nmesa->query_object_max); + nmesa->query_alloc = calloc(nmesa->query_object_max, sizeof(GLboolean)); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING_CACHE (NvQueryNotify); + break; + case NV_30: + case NV_40: + case NV_44: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT7, 1); + OUT_RING_CACHE (NvQueryNotify); + break; + default: + break; + }; + + ctx->Driver.NewQueryObject = nouveauNewQueryObject; + ctx->Driver.BeginQuery = nouveauBeginQuery; + ctx->Driver.EndQuery = nouveauEndQuery; +#if 0 + ctx->Driver.UpdateQuery = nouveauUpdateQuery; + ctx->Driver.WaitQueryResult = nouveauWaitQueryResult; +#endif +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.h b/src/mesa/drivers/dri/nouveau/nouveau_query.h new file mode 100644 index 00000000000..3ded41417e1 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007 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. + * + */ + +#ifndef __NOUVEAU_QUERY_H__ +#define __NOUVEAU_QUERY_H__ + +typedef struct nouveau_query_object_t { + struct gl_query_object mesa; + + int notifier_id; +} nouveau_query_object; + +extern void nouveauQueryInitFuncs(GLcontext *ctx); +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index cdb79fca1e6..c78b72bd113 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -126,15 +126,16 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs) /* Update state parameters */ plist = nvs->mesa.vp.Base.Parameters; _mesa_load_state_parameters(ctx, plist); - for (i=0; i<plist->NumParameters; i++) { + for (i=0; i<nvs->param_high; i++) { + if (!nvs->params[i].in_use) + continue; + if (!nvs->on_hardware) { /* if we've been kicked off the hardware there's no guarantee our * consts are still there.. reupload them all */ nvs->func->UpdateConst(ctx, nvs, i); - } else if (plist->Parameters[i].Type == PROGRAM_STATE_VAR) { - if (!nvs->params[i].source_val) /* this is a workaround when consts aren't alloc'd from id=0.. */ - continue; + } else if (nvs->params[i].source_val) { /* update any changed state parameters */ if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val)) nvs->func->UpdateConst(ctx, nvs, i); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 7329ccd9ead..b2df3546f62 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -26,11 +26,13 @@ typedef struct _nvs_fragment_header { typedef union { struct { - uint32_t fp_control; + GLboolean uses_kil; + GLuint num_regs; } NV30FP; struct { uint32_t vp_in_reg; uint32_t vp_out_reg; + uint32_t clip_enables; } NV30VP; } nvsCardPriv; @@ -54,8 +56,11 @@ typedef struct _nouveauShader { int inst_count; nvsCardPriv card_priv; + int vp_attrib_map[NVS_MAX_ATTRIBS]; struct { + GLboolean in_use; + GLfloat *source_val; /* NULL if invariant */ float val[4]; /* Hardware-specific tracking, currently only nv30_fragprog @@ -64,6 +69,7 @@ typedef struct _nouveauShader { int *hw_index; int hw_index_cnt; } params[NVS_MAX_CONSTS]; + int param_high; /* Pass-private data */ void *pass_rec; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 3bcc2ba755c..73c1f7c2a53 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -54,18 +54,6 @@ static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = { NVS_FR_UNKNOWN /* DEPR */ }; -static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = { - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, -/* Generic attribs 0-15, aliased to the above */ - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 -}; - static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = { NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, @@ -125,6 +113,10 @@ static nvsCond _tx_mesa_condmask[] = { struct pass0_rec { int nvs_ipos; int next_temp; + + int mesa_const_base; + int mesa_const_last; + int swzconst_done; int swzconst_id; nvsRegister const_half; @@ -320,8 +312,9 @@ pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, static void pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) { + struct pass0_rec *rec = nvs->pass_rec; struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; - struct gl_program_parameter_list *p = mesa->Parameters; + int i; *reg = nvr_unused; @@ -329,43 +322,30 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) case PROGRAM_INPUT: reg->file = NVS_FILE_ATTRIB; if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - reg->index = (src->Index < VERT_ATTRIB_MAX) ? - _tx_mesa_vp_src_reg[src->Index] : - NVS_FR_UNKNOWN; + for (i=0; i<NVS_MAX_ATTRIBS; i++) { + if (nvs->vp_attrib_map[i] == src->Index) { + reg->index = i; + break; + } + } + if (i==NVS_MAX_ATTRIBS) + reg->index = NVS_FR_UNKNOWN; } else { reg->index = (src->Index < FRAG_ATTRIB_MAX) ? _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN; } break; - /* All const types seem to get shoved into here, not really sure why */ case PROGRAM_STATE_VAR: - switch (p->Parameters[src->Index].Type) { - case PROGRAM_NAMED_PARAM: - case PROGRAM_CONSTANT: - nvs->params[src->Index].source_val = NULL; - COPY_4V(nvs->params[src->Index].val, - p->ParameterValues[src->Index]); - break; - case PROGRAM_STATE_VAR: - nvs->params[src->Index].source_val = - p->ParameterValues[src->Index]; - break; - default: - fprintf(stderr, "Unknown parameter type %d\n", - p->Parameters[src->Index].Type); - assert(0); - break; + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + reg->file = NVS_FILE_CONST; + reg->index = src->Index + rec->mesa_const_base; + reg->indexed = src->RelAddr; + if (reg->indexed) { + reg->addr_reg = 0; + reg->addr_comp = NVS_SWZ_X; } - - if (src->RelAddr) { - reg->indexed = 1; - reg->addr_reg = 0; - reg->addr_comp = NVS_SWZ_X; - } else - reg->indexed = 0; - reg->file = NVS_FILE_CONST; - reg->index = src->Index; break; case PROGRAM_TEMPORARY: reg->file = NVS_FILE_TEMP; @@ -574,7 +554,6 @@ pass0_emulate_instruction(nouveauShader *nvs, nvsFunc *shader = nvs->func; nvsRegister src[3], dest, temp; nvsInstruction *nvsinst; - struct pass0_rec *rec = nvs->pass_rec; unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); int i, sat; @@ -787,6 +766,183 @@ pass0_translate_instructions(nouveauShader *nvs, int ipos, int fpos, return GL_TRUE; } +static void +pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) +{ + GLuint inputs_read = vp->Base.InputsRead; + GLuint input_alloc = ~0xFFFF; + int i; + + for (i=0; i<NVS_MAX_ATTRIBS; i++) + nvs->vp_attrib_map[i] = -1; + + while (inputs_read) { + int in = ffs(inputs_read) - 1; + int hw; + inputs_read &= ~(1<<in); + + if (vp->IsNVProgram) { + /* NVvp: must alias */ + if (in >= VERT_ATTRIB_GENERIC0) + hw = in - VERT_ATTRIB_GENERIC0; + else + hw = in; + } else { + /* ARBvp: may alias (but we won't) + * GL2.0: must not alias + */ + if (in >= VERT_ATTRIB_GENERIC0) + hw = ffs(~input_alloc) - 1; + else + hw = in; + input_alloc |= (1<<hw); + } + + nvs->vp_attrib_map[hw] = in; + } + + if (NOUVEAU_DEBUG & DEBUG_SHADERS) { + printf("vtxprog attrib map:\n"); + for (i=0; i<NVS_MAX_ATTRIBS; i++) { + printf(" hw:%d = attrib:%d\n", + i, nvs->vp_attrib_map[i]); + } + } +} + +static void +pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs) +{ + struct gl_program *prog = &nvs->mesa.vp.Base; + nvsFragmentHeader *parent = nvs->program_tree; + nvsInstruction *nvsinst; + GLuint fpos = 0; + nvsRegister opos, epos, eqn, mv[4]; + GLint tokens[6] = { STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 }; + GLint id; + int i; + + /* modelview transform */ + pass0_make_reg(nvs, &opos, NVS_FILE_ATTRIB, NVS_FR_POSITION); + pass0_make_reg(nvs, &epos, NVS_FILE_TEMP , -1); + for (i=0; i<4; i++) { + tokens[3] = tokens[4] = i; + id = _mesa_add_state_reference(prog->Parameters, tokens); + pass0_make_reg(nvs, &mv[i], NVS_FILE_CONST, id); + } + ARITHu(NVS_OP_DP4, epos, SMASK_X, 0, opos, mv[0], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_Y, 0, opos, mv[1], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_Z, 0, opos, mv[2], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_W, 0, opos, mv[3], nvr_unused); + + /* Emit code to emulate fixed-function glClipPlane */ + for (i=0; i<6; i++) { + GLuint clipmask = SMASK_X; + nvsRegister clip; + + if (!(ctx->Transform.ClipPlanesEnabled & (1<<i))) + continue; + + /* Point a const at a user clipping plane */ + tokens[0] = STATE_CLIPPLANE; + tokens[1] = i; + id = _mesa_add_state_reference(prog->Parameters, tokens); + pass0_make_reg(nvs, &eqn , NVS_FILE_CONST , id); + pass0_make_reg(nvs, &clip, NVS_FILE_RESULT, NVS_FR_CLIP0 + i); + + /*XXX: something else needs to take care of modifying the + * instructions to write to the correct hw clip register. + */ + switch (i) { + case 0: case 3: clipmask = SMASK_Y; break; + case 1: case 4: clipmask = SMASK_Z; break; + case 2: case 5: clipmask = SMASK_W; break; + } + + /* Emit transform */ + ARITHu(NVS_OP_DP4, clip, clipmask, 0, epos, eqn, nvr_unused); + } +} + +static void +pass0_rebase_mesa_consts(nouveauShader *nvs) +{ + struct pass0_rec *rec = nvs->pass_rec; + struct gl_program *prog = &nvs->mesa.vp.Base; + struct prog_instruction *inst = prog->Instructions; + int i; + + /*XXX: not a good idea, params->hw_index is malloc'd */ + memset(nvs->params, 0x00, sizeof(nvs->params)); + + /* When doing relative addressing on constants, the hardware needs us + * to fill the "const id" field with a positive value. Determine the + * most negative index that is used so that all accesses to a + * mesa-provided constant can be rebased to a positive index. + */ + while (inst->Opcode != OPCODE_END) { + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + + switch (src->File) { + case PROGRAM_STATE_VAR: + case PROGRAM_CONSTANT: + case PROGRAM_NAMED_PARAM: + if (src->RelAddr && src->Index < 0) { + int base = src->Index * -1; + if (rec->mesa_const_base < base) + rec->mesa_const_base = base; + } + break; + default: + break; + } + } + + inst++; + } +} + +static void +pass0_resolve_mesa_consts(nouveauShader *nvs) +{ + struct pass0_rec *rec = nvs->pass_rec; + struct gl_program *prog = &nvs->mesa.vp.Base; + struct gl_program_parameter_list *plist = prog->Parameters; + int i; + + /* Init all const tracking/alloc info from the parameter list, rather + * than doing it as we translate the program. Otherwise: + * 1) we can't get at the correct constant info when relative + * addressing is being used due to src->Index not pointing + * at the exact const; + * 2) as we add extra consts to the program, mesa will call realloc() + * and we get invalid pointers to the const data. + */ + rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base; + nvs->param_high = rec->mesa_const_last; + for (i=0; i<plist->NumParameters; i++) { + int hw = rec->mesa_const_base + i; + + switch (plist->Parameters[i].Type) { + case PROGRAM_NAMED_PARAM: + case PROGRAM_STATE_VAR: + nvs->params[hw].in_use = GL_TRUE; + nvs->params[hw].source_val = plist->ParameterValues[i]; + COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]); + break; + case PROGRAM_CONSTANT: + nvs->params[hw].in_use = GL_TRUE; + nvs->params[hw].source_val = NULL; + COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]); + break; + default: + assert(0); + break; + } + } +} + GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) { @@ -797,45 +953,54 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) struct pass0_rec *rec; int ret = GL_FALSE; + rec = CALLOC_STRUCT(pass0_rec); + if (!rec) + return GL_FALSE; + + rec->next_temp = prog->NumTemporaries; + nvs->pass_rec = rec; + + nvs->program_tree = (nvsFragmentHeader*) + pass0_create_subroutine(nvs, "program body"); + if (!nvs->program_tree) { + FREE(rec); + return GL_FALSE; + } + switch (prog->Target) { case GL_VERTEX_PROGRAM_ARB: nvs->func = &nmesa->VPfunc; if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); -#if 0 - if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) - pass0_insert_ff_clip_planes(); -#endif + pass0_rebase_mesa_consts(nvs); + + if (!prog->String && ctx->Transform.ClipPlanesEnabled) + pass0_vp_insert_ff_clip_planes(ctx, nvs); + + pass0_build_attrib_map(nvs, vp); break; case GL_FRAGMENT_PROGRAM_ARB: nvs->func = &nmesa->FPfunc; if (fp->FogOption != GL_NONE) _mesa_append_fog_code(ctx, fp); + pass0_rebase_mesa_consts(nvs); break; default: fprintf(stderr, "Unknown program type %d", prog->Target); + FREE(rec); + /* DESTROY TREE!! */ return GL_FALSE; } nvs->func->card_priv = &nvs->card_priv; - rec = CALLOC_STRUCT(pass0_rec); - if (rec) { - rec->next_temp = prog->NumTemporaries; - nvs->pass_rec = rec; - - nvs->program_tree = (nvsFragmentHeader*) - pass0_create_subroutine(nvs, "program body"); - if (nvs->program_tree) { - ret = pass0_translate_instructions(nvs, - 0, 0, - nvs->program_tree); - /*XXX: if (!ret) DESTROY TREE!!! */ - } - FREE(rec); - } + ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree); + if (ret) + pass0_resolve_mesa_consts(nvs); + /*XXX: if (!ret) DESTROY TREE!!! */ + FREE(rec); return ret; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index e7bc4fcd5ee..c47ff3a985d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -1,3 +1,30 @@ +/* + * Copyright (C) 2007 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. + * + */ + #include "vblank.h" /* for DO_USLEEP */ #include "nouveau_context.h" @@ -9,7 +36,7 @@ #include "nouveau_sync.h" nouveau_notifier * -nouveau_notifier_new(GLcontext *ctx, GLuint handle) +nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nouveau_notifier *notifier; @@ -24,7 +51,7 @@ nouveau_notifier_new(GLcontext *ctx, GLuint handle) notifier->mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, - 32, + count * NV_NOTIFIER_SIZE, 0); if (!notifier->mem) { FREE(notifier); @@ -53,9 +80,9 @@ nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier) } void -nouveau_notifier_reset(nouveau_notifier *notifier) +nouveau_notifier_reset(nouveau_notifier *notifier, GLuint id) { - volatile GLuint *n = notifier->mem->map; + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); #ifdef NOUVEAU_RING_DEBUG return; @@ -68,11 +95,27 @@ nouveau_notifier_reset(nouveau_notifier *notifier) NV_NOTIFY_STATE_STATUS_SHIFT); } +GLuint +nouveau_notifier_status(nouveau_notifier *notifier, GLuint id) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + + return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; +} + +GLuint +nouveau_notifier_return_val(nouveau_notifier *notifier, GLuint id) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + + return n[NV_NOTIFY_RETURN_VALUE/4]; +} + GLboolean -nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status, - GLuint timeout) +nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint id, + GLuint status, GLuint timeout) { - volatile GLuint *n = notifier->mem->map; + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); unsigned int time = 0; #ifdef NOUVEAU_RING_DEBUG @@ -108,7 +151,7 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLboolean ret; - nouveau_notifier_reset(notifier); + nouveau_notifier_reset(notifier, 0); BEGIN_RING_SIZE(subc, NV_NOTIFY, 1); OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY); @@ -116,7 +159,7 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, OUT_RING (0); FIRE_RING(); - ret = nouveau_notifier_wait_status(notifier, + ret = nouveau_notifier_wait_status(notifier, 0, NV_NOTIFY_STATE_STATUS_COMPLETED, 0 /* no timeout */); if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n"); @@ -130,7 +173,7 @@ GLboolean nouveauSyncInitFuncs(GLcontext *ctx) return GL_TRUE; #endif - nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify); + nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1); if (!nmesa->syncNotifier) { MESSAGE("Failed to create channel sync notifier\n"); return GL_FALSE; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index d9e3d4b80c1..019d5f6629b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -1,8 +1,36 @@ +/* + * Copyright (C) 2007 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. + * + */ + #ifndef __NOUVEAU_SYNC_H__ #define __NOUVEAU_SYNC_H__ #include "nouveau_buffers.h" +#define NV_NOTIFIER_SIZE 32 #define NV_NOTIFY_TIME_0 0x00000000 #define NV_NOTIFY_TIME_1 0x00000004 #define NV_NOTIFY_RETURN_VALUE 0x00000008 @@ -24,10 +52,13 @@ typedef struct nouveau_notifier_t { nouveau_mem *mem; } nouveau_notifier; -extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle); +extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle, + GLuint count); extern void nouveau_notifier_destroy(GLcontext *, nouveau_notifier *); -extern void nouveau_notifier_reset(nouveau_notifier *); -extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, +extern void nouveau_notifier_reset(nouveau_notifier *, GLuint id); +extern GLuint nouveau_notifier_status(nouveau_notifier *, GLuint id); +extern GLuint nouveau_notifier_return_val(nouveau_notifier *, GLuint id); +extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, GLuint id, GLuint status, GLuint timeout); extern void nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *, GLuint subc); diff --git a/src/mesa/drivers/dri/nouveau/nv04_state.c b/src/mesa/drivers/dri/nouveau/nv04_state.c index 83ad8ae4327..ec4cd40d877 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_state.c +++ b/src/mesa/drivers/dri/nouveau/nv04_state.c @@ -267,6 +267,7 @@ static void nv04Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; case GL_FOG: nv04_emit_blend(ctx); + nv04_emit_fog_color(ctx); break; // case GL_HISTOGRAM: // case GL_INDEX_LOGIC_OP: @@ -436,14 +437,54 @@ static void nv04WindowMoved(nouveauContextPtr nmesa) /* Initialise any card-specific non-GL related state */ static GLboolean nv04InitCard(nouveauContextPtr nmesa) { + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf3D, NvCtxSurf3D); + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_SURFACE, 1); + OUT_RING(NvCtxSurf3D); return GL_TRUE; } /* Update buffer offset/pitch/format */ static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) { + GLuint x, y, w, h; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + /* FIXME pitches have to be aligned ! */ + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_PITCH, 2); + OUT_RING(color[0]->pitch|(depth->pitch<<16)); + OUT_RING(color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); + OUT_RING(depth->offset); + } + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2); + OUT_RING((w<<16)|x); + OUT_RING((h<<16)|y); + + /* FIXME not sure... */ + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_SIZE, 1); + OUT_RING((h<<16)|w); + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); + if (color[0]->mesa._ActualFormat == GL_RGBA8) + OUT_RING(108/*A8R8G8B8*/); + else + OUT_RING(103/*R5G6B5*/); + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 0e912e73ffe..f6e47b7f480 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -322,7 +322,7 @@ static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) switch(pname) { case GL_FOG_MODE: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); //OUT_RING_CACHE (params); break; /* TODO: unsure about the rest.*/ @@ -688,10 +688,10 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, if (color[0]->mesa._ActualFormat != GL_RGBA8) { format = 0x103; /* R5G6B5 color buffer */ } - OUT_RING(format); - OUT_RING(pitch); - OUT_RING(color[0]->offset); - OUT_RING(depth ? depth->offset : color[0]->offset); + OUT_RING_CACHE(format); + OUT_RING_CACHE(pitch); + OUT_RING_CACHE(color[0]->offset); + OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index 3c7501dd629..02bd8014cc1 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -24,6 +24,7 @@ static void NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nvsCardPriv *priv = &nvs->card_priv; uint32_t offset; if (!nvs->program_buffer) @@ -46,8 +47,9 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) */ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); OUT_RING (offset | 1); - BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1); - OUT_RING (nvs->card_priv.NV30FP.fp_control | 0x03000000); + BEGIN_RING_SIZE(NvSub3D, 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); + OUT_RING ((priv->NV30FP.uses_kil << 7) | + (priv->NV30FP.num_regs << 24)); } static void @@ -95,7 +97,7 @@ static void NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) { if (opcode == NV30_FP_OP_OPCODE_KIL) - shader->card_priv->NV30FP.fp_control |= (1<<7); + shader->card_priv->NV30FP.uses_kil = GL_TRUE; shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK; shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT); } @@ -146,6 +148,16 @@ NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, } static void +NV30FPSetHighReg(nvsFunc *shader, int id) +{ + if (shader->card_priv->NV30FP.num_regs < (id+1)) { + if (id == 0) + id = 1; /* necessary? */ + shader->card_priv->NV30FP.num_regs = (id+1); + } +} + +static void NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) { unsigned int hwreg; @@ -163,6 +175,7 @@ NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) shader->inst[0] &= ~NV30_FP_OP_UNK0_7; hwreg = reg->index; } + NV30FPSetHighReg(shader, hwreg); shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT; shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT); } @@ -176,6 +189,7 @@ NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos) case NVS_FILE_TEMP: hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT); hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT); + NV30FPSetHighReg(shader, reg->index); break; case NVS_FILE_ATTRIB: { diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 9b0d7425c81..96a07fd5363 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -127,6 +127,11 @@ static void nv30ClearStencil(GLcontext *ctx, GLint s) static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (NOUVEAU_CARD_USING_SHADERS) + return; + + plane -= GL_CLIP_PLANE0; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); OUT_RING_CACHEf(equation[0]); OUT_RING_CACHEf(equation[1]); @@ -208,8 +213,14 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); - OUT_RING_CACHE(state); + if (NOUVEAU_CARD_USING_SHADERS) { + nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current; + if (nvs) + nvs->translated = GL_FALSE; + } else { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING_CACHE(state); + } break; case GL_COLOR_LOGIC_OP: BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); @@ -233,6 +244,8 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) OUT_RING_CACHE(state); break; case GL_FOG: + if (NOUVEAU_CARD_USING_SHADERS) + break; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); OUT_RING_CACHE(state); break; @@ -559,7 +572,7 @@ static void nv30LineWidth(GLcontext *ctx, GLfloat width) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte ubWidth; - CLAMPED_FLOAT_TO_UBYTE(ubWidth, width); + ubWidth = (GLubyte)(width * 8.0) & 0xFF; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); OUT_RING_CACHE(ubWidth); @@ -725,9 +738,13 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); - /*XXX: This SHOULD work.*/ - OUT_RING_CACHEp(mat->m, 16); + + if (!NOUVEAU_CARD_USING_SHADERS) { + BEGIN_RING_CACHE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); + } } static void nv30WindowMoved(nouveauContextPtr nmesa) diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c index afcacf36c2e..d023e8439e3 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -33,6 +33,9 @@ NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); OUT_RING(nvs->card_priv.NV30VP.vp_in_reg); OUT_RING(nvs->card_priv.NV30VP.vp_out_reg); + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1); + OUT_RING_CACHE (nvs->card_priv.NV30VP.clip_enables); } static void diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index 6cb7e1cfd68..d054140bcd0 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -86,6 +86,7 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, unsigned int *mask_ret) { unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg; + unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables; *mask_ret = 0xf; @@ -111,14 +112,17 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP0: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0; + (*clip_en) |= 0x00000002; *mask_ret = 0x4; return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP1: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1; + (*clip_en) |= 0x00000020; *mask_ret = 0x2; return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP2: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2; + (*clip_en) |= 0x00000200; *mask_ret = 0x1; return NV40_VP_INST_DEST_FOGC; case NVS_FR_POINTSZ: @@ -127,13 +131,16 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP3: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3; + (*clip_en) |= 0x00002000; *mask_ret = 0x4; return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP4: + (*clip_en) |= 0x00020000; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4; *mask_ret = 0x2; return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP5: + (*clip_en) |= 0x00200000; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5; *mask_ret = 0x1; return NV40_VP_INST_DEST_PSZ; |