X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fnouveau%2Fnouveau_fbo.c;h=8be7edb150bf8bbde835eed86ee0ecdcf3fd9a37;hb=4fb2daf42c8171579cdc18605c5ceeb1963f8b31;hp=23525509d14388192d8762d8ff71acaa34f14854;hpb=ff73c783cc47361ff0dd819c82d067b4b85870dd;p=mesa.git diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c index 23525509d14..8be7edb150b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -1,289 +1,274 @@ -#include "utils.h" -#include "framebuffer.h" -#include "renderbuffer.h" -#include "fbobject.h" - -#include "nouveau_context.h" +/* + * Copyright (C) 2009 Francisco Jerez. + * 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 "nouveau_driver.h" #include "nouveau_fbo.h" -#include "nouveau_fifo.h" -#include "nouveau_msg.h" -#include "nouveau_object.h" -#include "nouveau_reg.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" + +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/fbobject.h" static GLboolean -nouveau_renderbuffer_pixelformat(nouveau_renderbuffer_t * nrb, - GLenum internalFormat) +set_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat) { - nrb->mesa.InternalFormat = internalFormat; + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + rb->InternalFormat = internalFormat; - /*TODO: We probably want to extend this a bit, and maybe make - * card-specific? - */ switch (internalFormat) { + case GL_RGB: + case GL_RGB8: + rb->_BaseFormat = GL_RGB; + rb->Format = MESA_FORMAT_XRGB8888; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 4; + break; case GL_RGBA: case GL_RGBA8: - nrb->mesa._BaseFormat = GL_RGBA; - nrb->mesa._ActualFormat = GL_RGBA8; - nrb->mesa.DataType = GL_UNSIGNED_BYTE; - nrb->mesa.RedBits = 8; - nrb->mesa.GreenBits = 8; - nrb->mesa.BlueBits = 8; - nrb->mesa.AlphaBits = 8; - nrb->cpp = 4; + rb->_BaseFormat = GL_RGBA; + rb->Format = MESA_FORMAT_ARGB8888; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 4; break; - case GL_RGB: case GL_RGB5: - nrb->mesa._BaseFormat = GL_RGB; - nrb->mesa._ActualFormat = GL_RGB5; - nrb->mesa.DataType = GL_UNSIGNED_BYTE; - nrb->mesa.RedBits = 5; - nrb->mesa.GreenBits = 6; - nrb->mesa.BlueBits = 5; - nrb->mesa.AlphaBits = 0; - nrb->cpp = 2; + rb->_BaseFormat = GL_RGB; + rb->Format = MESA_FORMAT_RGB565; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 2; break; case GL_DEPTH_COMPONENT16: - nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; - nrb->mesa._ActualFormat = GL_DEPTH_COMPONENT16; - nrb->mesa.DataType = GL_UNSIGNED_SHORT; - nrb->mesa.DepthBits = 16; - nrb->cpp = 2; + rb->_BaseFormat = GL_DEPTH_COMPONENT; + rb->Format = MESA_FORMAT_Z16; + rb->DataType = GL_UNSIGNED_SHORT; + s->cpp = 2; break; case GL_DEPTH_COMPONENT24: - nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; - nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; - nrb->mesa.DepthBits = 24; - nrb->cpp = 4; - break; case GL_STENCIL_INDEX8_EXT: - nrb->mesa._BaseFormat = GL_STENCIL_INDEX; - nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; - nrb->mesa.StencilBits = 8; - nrb->cpp = 4; - break; case GL_DEPTH24_STENCIL8_EXT: - nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT; - nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; - nrb->mesa.DepthBits = 24; - nrb->mesa.StencilBits = 8; - nrb->cpp = 4; + rb->_BaseFormat = GL_DEPTH_STENCIL; + rb->Format = MESA_FORMAT_Z24_S8; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + s->cpp = 4; break; default: return GL_FALSE; - break; } + s->format = rb->Format; + return GL_TRUE; } static GLboolean -nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, +nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { - nouveau_renderbuffer_t *nrb = (nouveau_renderbuffer_t *) rb; + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; - if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { - fprintf(stderr, "%s: unknown internalFormat\n", __func__); + if (!set_renderbuffer_format(rb, internalFormat)) return GL_FALSE; - } - - /* If this buffer isn't statically alloc'd, we may need to ask the - * drm for more memory */ - if (rb->Width != width || rb->Height != height) { - GLuint pitch; - - /* align pitches to 64 bytes */ - pitch = ((width * nrb->cpp) + 63) & ~63; - - if (nrb->mem) - nouveau_mem_free(ctx, nrb->mem); - nrb->mem = nouveau_mem_alloc(ctx, - NOUVEAU_MEM_FB | - NOUVEAU_MEM_MAPPED, - pitch * height, 0); - if (!nrb->mem) - return GL_FALSE; - - /* update nouveau_renderbuffer info */ - nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem); - nrb->pitch = pitch; - } rb->Width = width; rb->Height = height; - rb->InternalFormat = internalFormat; - nouveauSpanSetFunctions(nrb); + nouveau_surface_alloc(ctx, s, TILED, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, + rb->Format, width, height); + context_dirty(ctx, FRAMEBUFFER); return GL_TRUE; } static void -nouveau_renderbuffer_delete(struct gl_renderbuffer *rb) +nouveau_renderbuffer_del(struct gl_renderbuffer *rb) { - GET_CURRENT_CONTEXT(ctx); - nouveau_renderbuffer_t *nrb = (nouveau_renderbuffer_t *) rb; + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; - if (nrb->mem) - nouveau_mem_free(ctx, nrb->mem); - FREE(nrb); + nouveau_surface_ref(NULL, s); + FREE(rb); } -nouveau_renderbuffer_t * -nouveau_renderbuffer_new(GLenum internalFormat) +static struct gl_renderbuffer * +nouveau_renderbuffer_new(GLcontext *ctx, GLuint name) { - nouveau_renderbuffer_t *nrb; + struct gl_renderbuffer *rb; - nrb = CALLOC_STRUCT(nouveau_renderbuffer); - if (!nrb) + rb = (struct gl_renderbuffer *) + CALLOC_STRUCT(nouveau_renderbuffer); + if (!rb) return NULL; - _mesa_init_renderbuffer(&nrb->mesa, 0); + _mesa_init_renderbuffer(rb, name); - if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { - fprintf(stderr, "%s: unknown internalFormat\n", __func__); - return GL_FALSE; - } + rb->AllocStorage = nouveau_renderbuffer_storage; + rb->Delete = nouveau_renderbuffer_del; - nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; - nrb->mesa.Delete = nouveau_renderbuffer_delete; - - return nrb; + return rb; } -static void -nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa, - nouveau_renderbuffer_t * nrb) +static GLboolean +nouveau_renderbuffer_dri_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) { - nmesa->numClipRects = 1; - nmesa->pClipRects = &nmesa->osClipRect; - nmesa->osClipRect.x1 = 0; - nmesa->osClipRect.y1 = 0; - nmesa->osClipRect.x2 = nrb->mesa.Width; - nmesa->osClipRect.y2 = nrb->mesa.Height; - nmesa->drawX = 0; - nmesa->drawY = 0; - nmesa->drawW = nrb->mesa.Width; - nmesa->drawH = nrb->mesa.Height; -} + if (!set_renderbuffer_format(rb, internalFormat)) + return GL_FALSE; -void -nouveau_window_moved(GLcontext * ctx) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_renderbuffer_t *nrb; - - nrb = (nouveau_renderbuffer_t *) ctx->DrawBuffer->_ColorDrawBuffers[0]; - if (!nrb) - return; - - nouveau_cliprects_renderbuffer_set(nmesa, nrb); - - /* Viewport depends on window size/position, nouveauCalcViewport - * will take care of calling the hw-specific WindowMoved - */ - ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, - ctx->Viewport.Width, ctx->Viewport.Height); - /* Scissor depends on window position */ - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); + rb->Width = width; + rb->Height = height; + + return GL_TRUE; } -GLboolean -nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) +struct gl_renderbuffer * +nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_renderbuffer_t *color[MAX_DRAW_BUFFERS]; - nouveau_renderbuffer_t *depth; - - _mesa_update_framebuffer(ctx); - _mesa_update_draw_buffer_bounds(ctx); + struct gl_renderbuffer *rb; - color[0] = (nouveau_renderbuffer_t *) fb->_ColorDrawBuffers[0]; - if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) - depth = (nouveau_renderbuffer_t *) fb->_DepthBuffer->Wrapped; - else - depth = (nouveau_renderbuffer_t *) fb->_DepthBuffer; + rb = nouveau_renderbuffer_new(NULL, 0); + if (!rb) + return NULL; - if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth)) - return GL_FALSE; - nouveau_window_moved(ctx); + rb->AllocStorage = nouveau_renderbuffer_dri_storage; - return GL_TRUE; -} + if (!set_renderbuffer_format(rb, format)) { + nouveau_renderbuffer_del(rb); + return NULL; + } -static void -nouveauDrawBuffer(GLcontext *ctx, GLenum buffer) -{ - nouveau_build_framebuffer(ctx, ctx->DrawBuffer); + return rb; } static struct gl_framebuffer * -nouveauNewFramebuffer(GLcontext *ctx, GLuint name) +nouveau_framebuffer_new(GLcontext *ctx, GLuint name) { - return _mesa_new_framebuffer(ctx, name); + struct nouveau_framebuffer *nfb; + + nfb = CALLOC_STRUCT(nouveau_framebuffer); + if (!nfb) + return NULL; + + _mesa_initialize_user_framebuffer(&nfb->base, name); + + return &nfb->base; } -static struct gl_renderbuffer * -nouveauNewRenderbuffer(GLcontext *ctx, GLuint name) +struct gl_framebuffer * +nouveau_framebuffer_dri_new(const GLvisual *visual) { - nouveau_renderbuffer_t *nrb; + struct nouveau_framebuffer *nfb; - nrb = CALLOC_STRUCT(nouveau_renderbuffer); - if (!nrb) + nfb = CALLOC_STRUCT(nouveau_framebuffer); + if (!nfb) return NULL; - _mesa_init_renderbuffer(&nrb->mesa, name); + _mesa_initialize_window_framebuffer(&nfb->base, visual); - nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; - nrb->mesa.Delete = nouveau_renderbuffer_delete; - return &nrb->mesa; + return &nfb->base; } static void -nouveauBindFramebuffer(GLcontext *ctx, GLenum target, - struct gl_framebuffer *fb, - struct gl_framebuffer *fbread) +nouveau_bind_framebuffer(GLcontext *ctx, GLenum target, + struct gl_framebuffer *dfb, + struct gl_framebuffer *rfb) { - if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { - nouveau_build_framebuffer(ctx, fb); - } + context_dirty(ctx, FRAMEBUFFER); } static void -nouveauFramebufferRenderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, - GLenum attachment, struct gl_renderbuffer *rb) +nouveau_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) { _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); - nouveau_build_framebuffer(ctx, fb); + + context_dirty(ctx, FRAMEBUFFER); +} + +static GLenum +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return GL_RGBA8; + case MESA_FORMAT_XRGB8888: + return GL_RGB8; + case MESA_FORMAT_RGB565: + return GL_RGB5; + default: + assert(0); + } } static void -nouveauRenderTexture(GLcontext * ctx, struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att) +nouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) { + struct gl_renderbuffer *rb = att->Renderbuffer; + struct gl_texture_image *ti = + att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + int ret; + + /* Allocate a renderbuffer object for the texture if we + * haven't already done so. */ + if (!rb) { + rb = nouveau_renderbuffer_new(ctx, ~0); + assert(rb); + + rb->AllocStorage = NULL; + _mesa_reference_renderbuffer(&att->Renderbuffer, rb); + } + + /* Update the renderbuffer fields from the texture. */ + ret = set_renderbuffer_format(rb, get_tex_format(ti)); + assert(ret); + + rb->Width = ti->Width; + rb->Height = ti->Height; + nouveau_surface_ref(&to_nouveau_teximage(ti)->surface, + &to_nouveau_renderbuffer(rb)->surface); + + context_dirty(ctx, FRAMEBUFFER); } static void -nouveauFinishRenderTexture(GLcontext * ctx, - struct gl_renderbuffer_attachment *att) +nouveau_finish_render_texture(GLcontext *ctx, + struct gl_renderbuffer_attachment *att) { + texture_dirty(att->Texture); } void -nouveauInitBufferFuncs(struct dd_function_table *func) +nouveau_fbo_functions_init(struct dd_function_table *functions) { - func->DrawBuffer = nouveauDrawBuffer; - - func->NewFramebuffer = nouveauNewFramebuffer; - func->NewRenderbuffer = nouveauNewRenderbuffer; - func->BindFramebuffer = nouveauBindFramebuffer; - func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer; - func->RenderTexture = nouveauRenderTexture; - func->FinishRenderTexture = nouveauFinishRenderTexture; + functions->NewFramebuffer = nouveau_framebuffer_new; + functions->NewRenderbuffer = nouveau_renderbuffer_new; + functions->BindFramebuffer = nouveau_bind_framebuffer; + functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer; + functions->RenderTexture = nouveau_render_texture; + functions->FinishRenderTexture = nouveau_finish_render_texture; } -