From aacea5218199b6fb614c75d4f6ee14dd27af70b3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 28 Jan 2007 17:02:40 +1100 Subject: [PATCH] nouveau: initial GL_ARB_occlusion_query support Only enabled on NV40, NV20/NV30 code is untested.. However, NV30 should be identical to NV40. --- src/mesa/drivers/dri/nouveau/Makefile | 1 + .../drivers/dri/nouveau/nouveau_context.c | 4 + .../drivers/dri/nouveau/nouveau_context.h | 5 + src/mesa/drivers/dri/nouveau/nouveau_object.h | 3 +- src/mesa/drivers/dri/nouveau/nouveau_query.c | 198 ++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_query.h | 38 ++++ src/mesa/drivers/dri/nouveau/nouveau_sync.c | 27 +++ src/mesa/drivers/dri/nouveau/nouveau_sync.h | 27 +++ 8 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_query.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_query.h 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_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index e154e0acff0..daad281029f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -15,7 +15,8 @@ enum DMAObjects { NvCtxSurf3D = 0x80000023, NvDmaFB = 0xD0FB0001, NvDmaAGP = 0xD0AA0001, - NvSyncNotify = 0xD0000001 + NvSyncNotify = 0xD0000001, + NvQueryNotify = 0xD0000002 }; enum DMASubchannel { 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; iquery_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_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 5fb8dec7d80..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" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index 5c941bbb1c4..019d5f6629b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -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. + * + */ + #ifndef __NOUVEAU_SYNC_H__ #define __NOUVEAU_SYNC_H__ -- 2.30.2