i965: Fix regs read for FS_OPCODE_INTERP_PER_SLOT_OFFSET
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_fbo.c
index 1db8c5dd8de34a964a23010e3f1b4e488f5d03f9..6c479f5f0c637c1ea0700479eaa8380b130624d1 100644 (file)
@@ -44,35 +44,31 @@ set_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat)
        case GL_RGB:
        case GL_RGB8:
                rb->_BaseFormat  = GL_RGB;
-               rb->Format = MESA_FORMAT_XRGB8888;
-               rb->DataType = GL_UNSIGNED_BYTE;
+               rb->Format = MESA_FORMAT_B8G8R8X8_UNORM;
                s->cpp = 4;
                break;
        case GL_RGBA:
        case GL_RGBA8:
                rb->_BaseFormat  = GL_RGBA;
-               rb->Format = MESA_FORMAT_ARGB8888;
-               rb->DataType = GL_UNSIGNED_BYTE;
+               rb->Format = MESA_FORMAT_B8G8R8A8_UNORM;
                s->cpp = 4;
                break;
        case GL_RGB5:
                rb->_BaseFormat  = GL_RGB;
-               rb->Format = MESA_FORMAT_RGB565;
-               rb->DataType = GL_UNSIGNED_BYTE;
+               rb->Format = MESA_FORMAT_B5G6R5_UNORM;
                s->cpp = 2;
                break;
        case GL_DEPTH_COMPONENT16:
                rb->_BaseFormat  = GL_DEPTH_COMPONENT;
-               rb->Format = MESA_FORMAT_Z16;
-               rb->DataType = GL_UNSIGNED_SHORT;
+               rb->Format = MESA_FORMAT_Z_UNORM16;
                s->cpp = 2;
                break;
+       case GL_DEPTH_COMPONENT:
        case GL_DEPTH_COMPONENT24:
        case GL_STENCIL_INDEX8_EXT:
        case GL_DEPTH24_STENCIL8_EXT:
                rb->_BaseFormat  = GL_DEPTH_STENCIL;
-               rb->Format = MESA_FORMAT_Z24_S8;
-               rb->DataType = GL_UNSIGNED_INT;
+               rb->Format = MESA_FORMAT_S8_UINT_Z24_UNORM;
                s->cpp = 4;
                break;
        default:
@@ -85,7 +81,7 @@ set_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat)
 }
 
 static GLboolean
-nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+nouveau_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
                             GLenum internalFormat,
                             GLuint width, GLuint height)
 {
@@ -105,16 +101,16 @@ nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
 }
 
 static void
-nouveau_renderbuffer_del(struct gl_renderbuffer *rb)
+nouveau_renderbuffer_del(struct gl_context *ctx, struct gl_renderbuffer *rb)
 {
        struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
 
        nouveau_surface_ref(NULL, s);
-       FREE(rb);
+       _mesa_delete_renderbuffer(ctx, rb);
 }
 
 static struct gl_renderbuffer *
-nouveau_renderbuffer_new(GLcontext *ctx, GLuint name)
+nouveau_renderbuffer_new(struct gl_context *ctx, GLuint name)
 {
        struct gl_renderbuffer *rb;
 
@@ -131,8 +127,49 @@ nouveau_renderbuffer_new(GLcontext *ctx, GLuint name)
        return rb;
 }
 
+static void
+nouveau_renderbuffer_map(struct gl_context *ctx,
+                        struct gl_renderbuffer *rb,
+                        GLuint x, GLuint y, GLuint w, GLuint h,
+                        GLbitfield mode,
+                        GLubyte **out_map,
+                        GLint *out_stride)
+{
+       struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
+       GLubyte *map;
+       int stride;
+       int flags = 0;
+
+       if (mode & GL_MAP_READ_BIT)
+               flags |= NOUVEAU_BO_RD;
+       if (mode & GL_MAP_WRITE_BIT)
+               flags |= NOUVEAU_BO_WR;
+
+       nouveau_bo_map(s->bo, flags, context_client(ctx));
+
+       map = s->bo->map;
+       stride = s->pitch;
+
+       if (rb->Name == 0) {
+               map += stride * (rb->Height - 1);
+               stride = -stride;
+       }
+
+       map += x * s->cpp;
+       map += (int)y * stride;
+
+       *out_map = map;
+       *out_stride = stride;
+}
+
+static void
+nouveau_renderbuffer_unmap(struct gl_context *ctx,
+                          struct gl_renderbuffer *rb)
+{
+}
+
 static GLboolean
-nouveau_renderbuffer_dri_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+nouveau_renderbuffer_dri_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
                                 GLenum internalFormat,
                                 GLuint width, GLuint height)
 {
@@ -157,7 +194,7 @@ nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable)
        rb->AllocStorage = nouveau_renderbuffer_dri_storage;
 
        if (!set_renderbuffer_format(rb, format)) {
-               nouveau_renderbuffer_del(rb);
+               nouveau_renderbuffer_del(NULL, rb);
                return NULL;
        }
 
@@ -165,7 +202,7 @@ nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable)
 }
 
 static struct gl_framebuffer *
-nouveau_framebuffer_new(GLcontext *ctx, GLuint name)
+nouveau_framebuffer_new(struct gl_context *ctx, GLuint name)
 {
        struct nouveau_framebuffer *nfb;
 
@@ -179,7 +216,7 @@ nouveau_framebuffer_new(GLcontext *ctx, GLuint name)
 }
 
 struct gl_framebuffer *
-nouveau_framebuffer_dri_new(const GLvisual *visual)
+nouveau_framebuffer_dri_new(const struct gl_config *visual)
 {
        struct nouveau_framebuffer *nfb;
 
@@ -188,12 +225,13 @@ nouveau_framebuffer_dri_new(const GLvisual *visual)
                return NULL;
 
        _mesa_initialize_window_framebuffer(&nfb->base, visual);
+       nfb->need_front = !visual->doubleBufferMode;
 
        return &nfb->base;
 }
 
 static void
-nouveau_bind_framebuffer(GLcontext *ctx, GLenum target,
+nouveau_bind_framebuffer(struct gl_context *ctx, GLenum target,
                         struct gl_framebuffer *dfb,
                         struct gl_framebuffer *rfb)
 {
@@ -201,7 +239,7 @@ nouveau_bind_framebuffer(GLcontext *ctx, GLenum target,
 }
 
 static void
-nouveau_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+nouveau_framebuffer_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
                                 GLenum attachment, struct gl_renderbuffer *rb)
 {
        _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
@@ -209,44 +247,14 @@ nouveau_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *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_RGB565:
-               return GL_RGB5;
-       default:
-               assert(0);
-       }
-}
-
 static void
-nouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb,
+nouveau_render_texture(struct gl_context *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);
-       }
+       struct gl_texture_image *ti = rb->TexImage;
 
        /* 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);
 
@@ -254,14 +262,61 @@ nouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb,
 }
 
 static void
-nouveau_finish_render_texture(GLcontext *ctx,
-                             struct gl_renderbuffer_attachment *att)
+nouveau_finish_render_texture(struct gl_context *ctx,
+                             struct gl_renderbuffer *rb)
 {
-       struct nouveau_renderbuffer *nrb
-               = to_nouveau_renderbuffer(att->Renderbuffer);
+       if (rb && rb->TexImage)
+               texture_dirty(rb->TexImage->TexObject);
+}
+
+static int
+validate_format_bpp(mesa_format format)
+{
+       switch (format) {
+       case MESA_FORMAT_B8G8R8X8_UNORM:
+       case MESA_FORMAT_B8G8R8A8_UNORM:
+       case MESA_FORMAT_S8_UINT_Z24_UNORM:
+               return 32;
+       case MESA_FORMAT_B5G6R5_UNORM:
+       case MESA_FORMAT_Z_UNORM16:
+               return 16;
+       default:
+               return 0;
+       }
+}
+
+static void
+nouveau_check_framebuffer_complete(struct gl_context *ctx,
+                                  struct gl_framebuffer *fb)
+{
+       struct gl_renderbuffer_attachment *color =
+               &fb->Attachment[BUFFER_COLOR0];
+       struct gl_renderbuffer_attachment *depth =
+               &fb->Attachment[BUFFER_DEPTH];
+       int color_bpp = 0, zeta_bpp;
+
+       if (color->Type == GL_TEXTURE) {
+               color_bpp = validate_format_bpp(
+                               color->Renderbuffer->TexImage->TexFormat);
+               if (!color_bpp)
+                       goto err;
+       }
+
+       if (depth->Type == GL_TEXTURE) {
+               zeta_bpp = validate_format_bpp(
+                               depth->Renderbuffer->TexImage->TexFormat);
+               if (!zeta_bpp)
+                       goto err;
+               /* NV04/NV05 requires same bpp-ness for color/zeta */
+               if (context_chipset(ctx) < 0x10 &&
+                   color_bpp && color_bpp != zeta_bpp)
+                       goto err;
+       }
 
-       texture_dirty(att->Texture);
-       nouveau_surface_ref(NULL, &nrb->surface);
+       return;
+err:
+       fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+       return;
 }
 
 void
@@ -269,8 +324,11 @@ nouveau_fbo_functions_init(struct dd_function_table *functions)
 {
        functions->NewFramebuffer = nouveau_framebuffer_new;
        functions->NewRenderbuffer = nouveau_renderbuffer_new;
+       functions->MapRenderbuffer = nouveau_renderbuffer_map;
+       functions->UnmapRenderbuffer = nouveau_renderbuffer_unmap;
        functions->BindFramebuffer = nouveau_bind_framebuffer;
        functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer;
        functions->RenderTexture = nouveau_render_texture;
        functions->FinishRenderTexture = nouveau_finish_render_texture;
+       functions->ValidateFramebuffer = nouveau_check_framebuffer_complete;
 }