X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fnouveau%2Fnouveau_fbo.c;h=6c479f5f0c637c1ea0700479eaa8380b130624d1;hb=092c73a7c32b240a26ffeab2ee475f6d590540b2;hp=8be7edb150bf8bbde835eed86ee0ecdcf3fd9a37;hpb=7567f05199f1ca114cc57e3a11ac101d3707f819;p=mesa.git diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c index 8be7edb150b..6c479f5f0c6 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -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_24_8_EXT; + 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,46 +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_XRGB8888: - return GL_RGB8; - 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); @@ -256,10 +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) +{ + 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) { - texture_dirty(att->Texture); + 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; + } + + return; +err: + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; } void @@ -267,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; }