1bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez/* 2bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Copyright (C) 2009 Francisco Jerez. 3bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * All Rights Reserved. 4bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * 5bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * Permission is hereby granted, free of charge, to any person obtaining 6bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * a copy of this software and associated documentation files (the 7bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * "Software"), to deal in the Software without restriction, including 8bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * without limitation the rights to use, copy, modify, merge, publish, 9bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * distribute, sublicense, and/or sell copies of the Software, and to 10bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * permit persons to whom the Software is furnished to do so, subject to 11bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * the following conditions: 12bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * 13bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * The above copyright notice and this permission notice (including the 14bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * next paragraph) shall be included in all copies or substantial 15bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * portions of the Software. 16bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * 17bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez * 25bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez */ 26bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 271933e97034a1774e37268035f67ca5973220e8c6Vinson Lee#include "main/mfeatures.h" 28264b584294dc1c00c53f6a0622b7e6e55e8dce37Brian Paul#include "main/mtypes.h" 29264b584294dc1c00c53f6a0622b7e6e55e8dce37Brian Paul#include "main/fbobject.h" 301933e97034a1774e37268035f67ca5973220e8c6Vinson Lee 31bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_driver.h" 32bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_context.h" 33bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_fbo.h" 34bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "nouveau_util.h" 35bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 36bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez#include "drivers/common/meta.h" 37bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 38bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic const GLubyte * 39f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_get_string(struct gl_context *ctx, GLenum name) 40bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 41bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez static char buffer[128]; 42bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez char hardware_name[32]; 43bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 44bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez switch (name) { 45bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez case GL_VENDOR: 46bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez return (GLubyte *)"Nouveau"; 47bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 48bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez case GL_RENDERER: 49bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez sprintf(hardware_name, "nv%02X", context_chipset(ctx)); 500fe34b7bbc9a8e089bbb4d0fe401b09095a571ebIan Romanick driGetRendererString(buffer, hardware_name, 0); 51bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 52bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez return (GLubyte *)buffer; 53bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez default: 54bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez return NULL; 55bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 56bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 57bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 58bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 59f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_flush(struct gl_context *ctx) 60bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 61bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_context *nctx = to_nouveau_context(ctx); 622e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs struct nouveau_pushbuf *push = context_push(ctx); 63bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 642e47d01c9e5325906cf3bb979279599991c6328eBen Skeggs PUSH_KICK(push); 65bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 66264b584294dc1c00c53f6a0622b7e6e55e8dce37Brian Paul if (_mesa_is_winsys_fbo(ctx->DrawBuffer) && 67bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { 68bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez __DRIscreen *screen = nctx->screen->dri_screen; 69bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez __DRIdri2LoaderExtension *dri2 = screen->dri2.loader; 70bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez __DRIdrawable *drawable = nctx->dri_context->driDrawablePriv; 71bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 72bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez dri2->flushFrontBuffer(drawable, drawable->loaderPrivate); 73bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 74bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 75bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 76bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezstatic void 77f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_finish(struct gl_context *ctx) 78bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 79666004148353fa46e818772e496f6d09bd979737Ben Skeggs struct nouveau_context *nctx = to_nouveau_context(ctx); 80666004148353fa46e818772e496f6d09bd979737Ben Skeggs struct nouveau_pushbuf *push = context_push(ctx); 81666004148353fa46e818772e496f6d09bd979737Ben Skeggs struct nouveau_pushbuf_refn refn = 82666004148353fa46e818772e496f6d09bd979737Ben Skeggs { nctx->fence, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR }; 83666004148353fa46e818772e496f6d09bd979737Ben Skeggs 84bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez nouveau_flush(ctx); 85666004148353fa46e818772e496f6d09bd979737Ben Skeggs 86666004148353fa46e818772e496f6d09bd979737Ben Skeggs if (!nouveau_pushbuf_space(push, 16, 0, 0) && 87666004148353fa46e818772e496f6d09bd979737Ben Skeggs !nouveau_pushbuf_refn(push, &refn, 1)) { 88666004148353fa46e818772e496f6d09bd979737Ben Skeggs PUSH_DATA(push, 0); 89666004148353fa46e818772e496f6d09bd979737Ben Skeggs PUSH_KICK(push); 90666004148353fa46e818772e496f6d09bd979737Ben Skeggs } 91666004148353fa46e818772e496f6d09bd979737Ben Skeggs 92666004148353fa46e818772e496f6d09bd979737Ben Skeggs nouveau_bo_wait(nctx->fence, NOUVEAU_BO_RDWR, context_client(ctx)); 93bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 94bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 95bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid 96f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergnouveau_clear(struct gl_context *ctx, GLbitfield buffers) 97bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 98bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct gl_framebuffer *fb = ctx->DrawBuffer; 99bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez int x, y, w, h; 100bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez int i, buf; 101bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 102bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez nouveau_validate_framebuffer(ctx); 103bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez get_scissors(fb, &x, &y, &w, &h); 104bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 105bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez for (i = 0; i < BUFFER_COUNT; i++) { 106bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez struct nouveau_surface *s; 107bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez unsigned mask, value; 108bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 109bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez buf = buffers & (1 << i); 110bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (!buf) 111bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez continue; 112bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 113bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez s = &to_nouveau_renderbuffer( 11459a5b5a193d5d9c5776aa586b34657b6e315479dBrian Paul fb->Attachment[i].Renderbuffer)->surface; 115bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 116bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (buf & BUFFER_BITS_COLOR) { 117bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez mask = pack_rgba_i(s->format, ctx->Color.ColorMask[0]); 118093dc9e548537e6c77e33064a584f849ad90dfa5Dave Airlie value = pack_rgba_clamp_f(s->format, ctx->Color.ClearColor.f); 119bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 120bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (mask) 121bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez context_drv(ctx)->surface_fill( 122bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez ctx, s, mask, value, x, y, w, h); 123bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 124bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez buffers &= ~buf; 125bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 126bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } else if (buf & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) { 127bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez mask = pack_zs_i(s->format, 128bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez (buffers & BUFFER_BIT_DEPTH && 129bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez ctx->Depth.Mask) ? ~0 : 0, 13091af398b32f0f63a1560fe023651be0861c08f8aFrancisco Jerez (buffers & BUFFER_BIT_STENCIL ? 13191af398b32f0f63a1560fe023651be0861c08f8aFrancisco Jerez ctx->Stencil.WriteMask[0] : 0)); 132bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez value = pack_zs_f(s->format, 133bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez ctx->Depth.Clear, 134bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez ctx->Stencil.Clear); 135bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 136bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (mask) 137bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez context_drv(ctx)->surface_fill( 138bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez ctx, s, mask, value, x, y, w, h); 139bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 140bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); 141bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 142bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez } 143bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 144bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez if (buffers) 145bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez _mesa_meta_Clear(ctx, buffers); 146bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 147bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez 148bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerezvoid 149bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jereznouveau_driver_functions_init(struct dd_function_table *functions) 150bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez{ 151bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez functions->GetString = nouveau_get_string; 152bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez functions->Flush = nouveau_flush; 153bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez functions->Finish = nouveau_finish; 154bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez functions->Clear = nouveau_clear; 155fc7890dc6c1f70a4f1c4bffb0fca7ae0cde30a2eFrancisco Jerez functions->DrawPixels = _mesa_meta_DrawPixels; 156fc7890dc6c1f70a4f1c4bffb0fca7ae0cde30a2eFrancisco Jerez functions->CopyPixels = _mesa_meta_CopyPixels; 157fc7890dc6c1f70a4f1c4bffb0fca7ae0cde30a2eFrancisco Jerez functions->Bitmap = _mesa_meta_Bitmap; 15870f9f5f7d4f1daadfcddc0fb0fea324c38353004nobled#if FEATURE_EXT_framebuffer_blit 159fe7d0e6dc81c493b9ff7163c640d75db25386675Francisco Jerez functions->BlitFramebuffer = _mesa_meta_BlitFramebuffer; 16070f9f5f7d4f1daadfcddc0fb0fea324c38353004nobled#endif 161bfb5dc68fcc9f5dee71f66d9499b8bdcde9627eaFrancisco Jerez} 162