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