Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 "nouveau_driver.h"
  28. #include "nouveau_fbo.h"
  29. #include "nouveau_context.h"
  30. #include "nouveau_texture.h"
  31.  
  32. #include "main/framebuffer.h"
  33. #include "main/renderbuffer.h"
  34. #include "main/fbobject.h"
  35.  
  36. static GLboolean
  37. set_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat)
  38. {
  39.         struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
  40.  
  41.         rb->InternalFormat  = internalFormat;
  42.  
  43.         switch (internalFormat) {
  44.         case GL_RGB:
  45.         case GL_RGB8:
  46.                 rb->_BaseFormat  = GL_RGB;
  47.                 rb->Format = MESA_FORMAT_XRGB8888;
  48.                 s->cpp = 4;
  49.                 break;
  50.         case GL_RGBA:
  51.         case GL_RGBA8:
  52.                 rb->_BaseFormat  = GL_RGBA;
  53.                 rb->Format = MESA_FORMAT_ARGB8888;
  54.                 s->cpp = 4;
  55.                 break;
  56.         case GL_RGB5:
  57.                 rb->_BaseFormat  = GL_RGB;
  58.                 rb->Format = MESA_FORMAT_RGB565;
  59.                 s->cpp = 2;
  60.                 break;
  61.         case GL_DEPTH_COMPONENT16:
  62.                 rb->_BaseFormat  = GL_DEPTH_COMPONENT;
  63.                 rb->Format = MESA_FORMAT_Z16;
  64.                 s->cpp = 2;
  65.                 break;
  66.         case GL_DEPTH_COMPONENT:
  67.         case GL_DEPTH_COMPONENT24:
  68.         case GL_STENCIL_INDEX8_EXT:
  69.         case GL_DEPTH24_STENCIL8_EXT:
  70.                 rb->_BaseFormat  = GL_DEPTH_STENCIL;
  71.                 rb->Format = MESA_FORMAT_Z24_S8;
  72.                 s->cpp = 4;
  73.                 break;
  74.         default:
  75.                 return GL_FALSE;
  76.         }
  77.  
  78.         s->format = rb->Format;
  79.  
  80.         return GL_TRUE;
  81. }
  82.  
  83. static GLboolean
  84. nouveau_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
  85.                              GLenum internalFormat,
  86.                              GLuint width, GLuint height)
  87. {
  88.         struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
  89.  
  90.         if (!set_renderbuffer_format(rb, internalFormat))
  91.                 return GL_FALSE;
  92.  
  93.         rb->Width = width;
  94.         rb->Height = height;
  95.  
  96.         nouveau_surface_alloc(ctx, s, TILED, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP,
  97.                               rb->Format, width, height);
  98.  
  99.         context_dirty(ctx, FRAMEBUFFER);
  100.         return GL_TRUE;
  101. }
  102.  
  103. static void
  104. nouveau_renderbuffer_del(struct gl_context *ctx, struct gl_renderbuffer *rb)
  105. {
  106.         struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
  107.  
  108.         nouveau_surface_ref(NULL, s);
  109.         _mesa_delete_renderbuffer(ctx, rb);
  110. }
  111.  
  112. static struct gl_renderbuffer *
  113. nouveau_renderbuffer_new(struct gl_context *ctx, GLuint name)
  114. {
  115.         struct gl_renderbuffer *rb;
  116.  
  117.         rb = (struct gl_renderbuffer *)
  118.                 CALLOC_STRUCT(nouveau_renderbuffer);
  119.         if (!rb)
  120.                 return NULL;
  121.  
  122.         _mesa_init_renderbuffer(rb, name);
  123.  
  124.         rb->AllocStorage = nouveau_renderbuffer_storage;
  125.         rb->Delete = nouveau_renderbuffer_del;
  126.  
  127.         return rb;
  128. }
  129.  
  130. static void
  131. nouveau_renderbuffer_map(struct gl_context *ctx,
  132.                          struct gl_renderbuffer *rb,
  133.                          GLuint x, GLuint y, GLuint w, GLuint h,
  134.                          GLbitfield mode,
  135.                          GLubyte **out_map,
  136.                          GLint *out_stride)
  137. {
  138.         struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface;
  139.         GLubyte *map;
  140.         int stride;
  141.         int flags = 0;
  142.  
  143.         if (mode & GL_MAP_READ_BIT)
  144.                 flags |= NOUVEAU_BO_RD;
  145.         if (mode & GL_MAP_WRITE_BIT)
  146.                 flags |= NOUVEAU_BO_WR;
  147.  
  148.         nouveau_bo_map(s->bo, flags, context_client(ctx));
  149.  
  150.         map = s->bo->map;
  151.         stride = s->pitch;
  152.  
  153.         if (rb->Name == 0) {
  154.                 map += stride * (rb->Height - 1);
  155.                 stride = -stride;
  156.         }
  157.  
  158.         map += x * s->cpp;
  159.         map += (int)y * stride;
  160.  
  161.         *out_map = map;
  162.         *out_stride = stride;
  163. }
  164.  
  165. static void
  166. nouveau_renderbuffer_unmap(struct gl_context *ctx,
  167.                            struct gl_renderbuffer *rb)
  168. {
  169. }
  170.  
  171. static GLboolean
  172. nouveau_renderbuffer_dri_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
  173.                                  GLenum internalFormat,
  174.                                  GLuint width, GLuint height)
  175. {
  176.         if (!set_renderbuffer_format(rb, internalFormat))
  177.                 return GL_FALSE;
  178.  
  179.         rb->Width = width;
  180.         rb->Height = height;
  181.  
  182.         return GL_TRUE;
  183. }
  184.  
  185. struct gl_renderbuffer *
  186. nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable)
  187. {
  188.         struct gl_renderbuffer *rb;
  189.  
  190.         rb = nouveau_renderbuffer_new(NULL, 0);
  191.         if (!rb)
  192.                 return NULL;
  193.  
  194.         rb->AllocStorage = nouveau_renderbuffer_dri_storage;
  195.  
  196.         if (!set_renderbuffer_format(rb, format)) {
  197.                 nouveau_renderbuffer_del(NULL, rb);
  198.                 return NULL;
  199.         }
  200.  
  201.         return rb;
  202. }
  203.  
  204. static struct gl_framebuffer *
  205. nouveau_framebuffer_new(struct gl_context *ctx, GLuint name)
  206. {
  207.         struct nouveau_framebuffer *nfb;
  208.  
  209.         nfb = CALLOC_STRUCT(nouveau_framebuffer);
  210.         if (!nfb)
  211.                 return NULL;
  212.  
  213.         _mesa_initialize_user_framebuffer(&nfb->base, name);
  214.  
  215.         return &nfb->base;
  216. }
  217.  
  218. struct gl_framebuffer *
  219. nouveau_framebuffer_dri_new(const struct gl_config *visual)
  220. {
  221.         struct nouveau_framebuffer *nfb;
  222.  
  223.         nfb = CALLOC_STRUCT(nouveau_framebuffer);
  224.         if (!nfb)
  225.                 return NULL;
  226.  
  227.         _mesa_initialize_window_framebuffer(&nfb->base, visual);
  228.         nfb->need_front = !visual->doubleBufferMode;
  229.  
  230.         return &nfb->base;
  231. }
  232.  
  233. static void
  234. nouveau_bind_framebuffer(struct gl_context *ctx, GLenum target,
  235.                          struct gl_framebuffer *dfb,
  236.                          struct gl_framebuffer *rfb)
  237. {
  238.         context_dirty(ctx, FRAMEBUFFER);
  239. }
  240.  
  241. static void
  242. nouveau_framebuffer_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
  243.                                  GLenum attachment, struct gl_renderbuffer *rb)
  244. {
  245.         _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
  246.  
  247.         context_dirty(ctx, FRAMEBUFFER);
  248. }
  249.  
  250. static void
  251. nouveau_render_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
  252.                        struct gl_renderbuffer_attachment *att)
  253. {
  254.         struct gl_renderbuffer *rb = att->Renderbuffer;
  255.         struct gl_texture_image *ti = rb->TexImage;
  256.  
  257.         /* Update the renderbuffer fields from the texture. */
  258.         nouveau_surface_ref(&to_nouveau_teximage(ti)->surface,
  259.                             &to_nouveau_renderbuffer(rb)->surface);
  260.  
  261.         context_dirty(ctx, FRAMEBUFFER);
  262. }
  263.  
  264. static void
  265. nouveau_finish_render_texture(struct gl_context *ctx,
  266.                               struct gl_renderbuffer *rb)
  267. {
  268.         texture_dirty(rb->TexImage->TexObject);
  269. }
  270.  
  271. void
  272. nouveau_fbo_functions_init(struct dd_function_table *functions)
  273. {
  274.         functions->NewFramebuffer = nouveau_framebuffer_new;
  275.         functions->NewRenderbuffer = nouveau_renderbuffer_new;
  276.         functions->MapRenderbuffer = nouveau_renderbuffer_map;
  277.         functions->UnmapRenderbuffer = nouveau_renderbuffer_unmap;
  278.         functions->BindFramebuffer = nouveau_bind_framebuffer;
  279.         functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer;
  280.         functions->RenderTexture = nouveau_render_texture;
  281.         functions->FinishRenderTexture = nouveau_finish_render_texture;
  282. }
  283.