i965: clip: Add VUE map computation to clip stage for Gen4-5.
[mesa.git] / src / mesa / drivers / dri / swrast / swrast.c
index e9ca99a86f0d20ae60591ebf39935db1908f9a19..719b406ec05feeef79ff22f8dace5ba3230d3954 100644 (file)
 #include "drivers/common/meta.h"
 #include "utils.h"
 
+#include "main/teximage.h"
+#include "main/texformat.h"
+#include "main/texstate.h"
+
 #include "swrast_priv.h"
 
 
  * Screen and config-related functions
  */
 
+static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
+                               GLint texture_format, __DRIdrawable *dPriv)
+{
+    struct dri_context *dri_ctx;
+    int x, y, w, h;
+    __DRIscreen *sPriv = dPriv->driScreenPriv;
+    struct gl_texture_unit *texUnit;
+    struct gl_texture_object *texObj;
+    struct gl_texture_image *texImage;
+    uint32_t internalFormat;
+    gl_format texFormat;
+
+    dri_ctx = pDRICtx->driverPrivate;
+
+    internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
+
+    texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base);
+    texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target);
+    texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0);
+
+    _mesa_lock_texture(&dri_ctx->Base, texObj);
+
+    sPriv->swrast_loader->getDrawableInfo(dPriv, &x, &y, &w, &h, dPriv->loaderPrivate);
+
+    if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
+       texFormat = MESA_FORMAT_XRGB8888;
+    else
+       texFormat = MESA_FORMAT_ARGB8888;
+
+    _mesa_init_teximage_fields(&dri_ctx->Base, target, texImage,
+                              w, h, 1, 0, internalFormat, texFormat);
+
+    sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)texImage->Data,
+                                  dPriv->loaderPrivate);
+
+    _mesa_unlock_texture(&dri_ctx->Base, texObj);
+}
+
+static void swrastSetTexBuffer(__DRIcontext *pDRICtx, GLint target,
+                              __DRIdrawable *dPriv)
+{
+    swrastSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+static const __DRItexBufferExtension swrastTexBufferExtension = {
+    { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+    swrastSetTexBuffer,
+    swrastSetTexBuffer2,
+};
+
 static const __DRIextension *dri_screen_extensions[] = {
+    &swrastTexBufferExtension.base,
     NULL
 };
 
@@ -168,7 +223,7 @@ dri_destroy_screen(__DRIscreen * sPriv)
  */
 
 static GLuint
-choose_pixel_format(const GLvisual *v)
+choose_pixel_format(const struct gl_config *v)
 {
     int depth = v->rgbBits;
 
@@ -206,12 +261,20 @@ swrast_delete_renderbuffer(struct gl_renderbuffer *rb)
     free(rb);
 }
 
+/* see bytes_per_line in libGL */
+static INLINE int
+bytes_per_line(unsigned pitch_bits, unsigned mul)
+{
+   unsigned mask = mul - 1;
+
+   return ((pitch_bits + mask) & ~mask) / 8;
+}
+
 static GLboolean
-swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
                           GLenum internalFormat, GLuint width, GLuint height)
 {
     struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
-    unsigned mask = PITCH_ALIGN_BITS - 1;
 
     TRACE;
 
@@ -219,14 +282,13 @@ swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
     rb->Width = width;
     rb->Height = height;
 
-    /* always pad to PITCH_ALIGN_BITS */
-    xrb->pitch = ((width * xrb->bpp + mask) & ~mask) / 8;
+    xrb->pitch = bytes_per_line(width * xrb->bpp, 32);
 
     return GL_TRUE;
 }
 
 static GLboolean
-swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+swrast_alloc_back_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
                          GLenum internalFormat, GLuint width, GLuint height)
 {
     struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb);
@@ -243,7 +305,7 @@ swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
 }
 
 static struct swrast_renderbuffer *
-swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
+swrast_new_renderbuffer(const struct gl_config *visual, GLboolean front)
 {
     struct swrast_renderbuffer *xrb = calloc(1, sizeof *xrb);
     GLuint pixel_format;
@@ -306,10 +368,10 @@ swrast_new_renderbuffer(const GLvisual *visual, GLboolean front)
 static GLboolean
 dri_create_buffer(__DRIscreen * sPriv,
                  __DRIdrawable * dPriv,
-                 const __GLcontextModes * visual, GLboolean isPixmap)
+                 const struct gl_config * visual, GLboolean isPixmap)
 {
     struct dri_drawable *drawable = NULL;
-    GLframebuffer *fb;
+    struct gl_framebuffer *fb;
     struct swrast_renderbuffer *frontrb, *backrb;
 
     TRACE;
@@ -368,7 +430,7 @@ dri_destroy_buffer(__DRIdrawable * dPriv)
 
     if (dPriv) {
        struct dri_drawable *drawable = dri_drawable(dPriv);
-       GLframebuffer *fb;
+       struct gl_framebuffer *fb;
 
        free(drawable->row);
 
@@ -387,15 +449,17 @@ dri_swap_buffers(__DRIdrawable * dPriv)
     GET_CURRENT_CONTEXT(ctx);
 
     struct dri_drawable *drawable = dri_drawable(dPriv);
-    GLframebuffer *fb;
+    struct gl_framebuffer *fb;
     struct swrast_renderbuffer *frontrb, *backrb;
 
     TRACE;
 
     fb = &drawable->Base;
 
-    frontrb = swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
-    backrb = swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+    frontrb =
+       swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+    backrb =
+       swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
 
     /* check for signle-buffered */
     if (backrb == NULL)
@@ -421,7 +485,7 @@ dri_swap_buffers(__DRIdrawable * dPriv)
  */
 
 static void
-get_window_size( GLframebuffer *fb, GLsizei *w, GLsizei *h )
+get_window_size( struct gl_framebuffer *fb, GLsizei *w, GLsizei *h )
 {
     __DRIdrawable *dPriv = swrast_drawable(fb)->dPriv;
     __DRIscreen *sPriv = dPriv->driScreenPriv;
@@ -433,7 +497,7 @@ get_window_size( GLframebuffer *fb, GLsizei *w, GLsizei *h )
 }
 
 static void
-swrast_check_and_update_window_size( GLcontext *ctx, GLframebuffer *fb )
+swrast_check_and_update_window_size( struct gl_context *ctx, struct gl_framebuffer *fb )
 {
     GLsizei width, height;
 
@@ -444,7 +508,7 @@ swrast_check_and_update_window_size( GLcontext *ctx, GLframebuffer *fb )
 }
 
 static const GLubyte *
-get_string(GLcontext *ctx, GLenum pname)
+get_string(struct gl_context *ctx, GLenum pname)
 {
     (void) ctx;
     switch (pname) {
@@ -458,7 +522,7 @@ get_string(GLcontext *ctx, GLenum pname)
 }
 
 static void
-update_state( GLcontext *ctx, GLuint new_state )
+update_state( struct gl_context *ctx, GLuint new_state )
 {
     /* not much to do here - pass it on */
     _swrast_InvalidateState( ctx, new_state );
@@ -468,15 +532,25 @@ update_state( GLcontext *ctx, GLuint new_state )
 }
 
 static void
-viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 {
-    GLframebuffer *draw = ctx->WinSysDrawBuffer;
-    GLframebuffer *read = ctx->WinSysReadBuffer;
+    struct gl_framebuffer *draw = ctx->WinSysDrawBuffer;
+    struct gl_framebuffer *read = ctx->WinSysReadBuffer;
 
     swrast_check_and_update_window_size(ctx, draw);
     swrast_check_and_update_window_size(ctx, read);
 }
 
+static gl_format swrastChooseTextureFormat(struct gl_context * ctx,
+                                          GLint internalFormat,
+                                          GLenum format,
+                                          GLenum type)
+{
+    if (internalFormat == GL_RGB)
+       return MESA_FORMAT_XRGB8888;
+    return _mesa_choose_tex_format(ctx, internalFormat, format, type);
+}
+
 static void
 swrast_init_driver_functions(struct dd_function_table *driver)
 {
@@ -484,21 +558,77 @@ swrast_init_driver_functions(struct dd_function_table *driver)
     driver->UpdateState = update_state;
     driver->GetBufferSize = NULL;
     driver->Viewport = viewport;
+    driver->ChooseTextureFormat = swrastChooseTextureFormat;
 }
 
+static const char *es2_extensions[] = {
+   /* Used by mesa internally (cf all_mesa_extensions in ../common/utils.c) */
+   "GL_ARB_draw_buffers",
+   "GL_ARB_multisample",
+   "GL_ARB_texture_compression",
+   "GL_ARB_transpose_matrix",
+   "GL_ARB_vertex_buffer_object",
+   "GL_ARB_window_pos",
+   "GL_EXT_blend_func_separate",
+   "GL_EXT_compiled_vertex_array",
+   "GL_EXT_framebuffer_blit",
+   "GL_EXT_multi_draw_arrays",
+   "GL_EXT_polygon_offset",
+   "GL_EXT_texture_object",
+   "GL_EXT_vertex_array",
+   "GL_IBM_multimode_draw_arrays",
+   "GL_MESA_window_pos",
+   "GL_NV_vertex_program",
+
+   /* Required by GLES2 */
+   "GL_ARB_fragment_program",
+   "GL_ARB_fragment_shader",
+   "GL_ARB_multitexture",
+   "GL_ARB_shader_objects",
+   "GL_ARB_texture_cube_map",
+   "GL_ARB_texture_mirrored_repeat",
+   "GL_ARB_texture_non_power_of_two",
+   "GL_ARB_vertex_shader",
+   "GL_EXT_blend_color",
+   "GL_EXT_blend_equation_separate",
+   "GL_EXT_blend_minmax",
+   "GL_EXT_blend_subtract",
+   "GL_EXT_stencil_wrap",
+
+   /* Optional GLES2 */
+   "GL_ARB_framebuffer_object",
+   "GL_EXT_texture_filter_anisotropic",
+   "GL_ARB_depth_texture",
+   "GL_EXT_packed_depth_stencil",
+   "GL_EXT_framebuffer_object",
+   NULL,
+};
+
+static void
+InitExtensionsES2(struct gl_context *ctx)
+{
+   int i;
+
+   /* Can't use driInitExtensions() since it uses extensions from
+    * main/remap_helper.h when called the first time. */
+
+   for (i = 0; es2_extensions[i]; i++)
+      _mesa_enable_extension(ctx, es2_extensions[i]);
+}
 
 /**
  * Context-related functions.
  */
 
 static GLboolean
-dri_create_context(const __GLcontextModes * visual,
+dri_create_context(gl_api api,
+                  const struct gl_config * visual,
                   __DRIcontext * cPriv, void *sharedContextPrivate)
 {
     struct dri_context *ctx = NULL;
     struct dri_context *share = (struct dri_context *)sharedContextPrivate;
-    GLcontext *mesaCtx = NULL;
-    GLcontext *sharedCtx = NULL;
+    struct gl_context *mesaCtx = NULL;
+    struct gl_context *sharedCtx = NULL;
     struct dd_function_table functions;
 
     TRACE;
@@ -521,7 +651,7 @@ dri_create_context(const __GLcontextModes * visual,
     mesaCtx = &ctx->Base;
 
     /* basic context setup */
-    if (!_mesa_initialize_context(mesaCtx, visual, sharedCtx, &functions, (void *) cPriv)) {
+    if (!_mesa_initialize_context(mesaCtx, api, visual, sharedCtx, &functions, (void *) cPriv)) {
        goto context_fail;
     }
 
@@ -541,16 +671,29 @@ dri_create_context(const __GLcontextModes * visual,
        tnl->Driver.RunPipeline = _tnl_run_pipeline;
     }
 
-    _mesa_enable_sw_extensions(mesaCtx);
-    _mesa_enable_1_3_extensions(mesaCtx);
-    _mesa_enable_1_4_extensions(mesaCtx);
-    _mesa_enable_1_5_extensions(mesaCtx);
-    _mesa_enable_2_0_extensions(mesaCtx);
-    _mesa_enable_2_1_extensions(mesaCtx);
-
     _mesa_meta_init(mesaCtx);
+    _mesa_enable_sw_extensions(mesaCtx);
 
-    driInitExtensions( mesaCtx, NULL, GL_FALSE );
+    switch (api) {
+    case API_OPENGL:
+        _mesa_enable_1_3_extensions(mesaCtx);
+        _mesa_enable_1_4_extensions(mesaCtx);
+        _mesa_enable_1_5_extensions(mesaCtx);
+        _mesa_enable_2_0_extensions(mesaCtx);
+        _mesa_enable_2_1_extensions(mesaCtx);
+
+        driInitExtensions( mesaCtx, NULL, GL_FALSE );
+        break;
+    case API_OPENGLES:
+        _mesa_enable_1_3_extensions(mesaCtx);
+        _mesa_enable_1_4_extensions(mesaCtx);
+        _mesa_enable_1_5_extensions(mesaCtx);
+
+        break;
+    case API_OPENGLES2:
+        InitExtensionsES2( mesaCtx);
+        break;
+    }
 
     return GL_TRUE;
 
@@ -568,7 +711,7 @@ dri_destroy_context(__DRIcontext * cPriv)
 
     if (cPriv) {
        struct dri_context *ctx = dri_context(cPriv);
-       GLcontext *mesaCtx;
+       struct gl_context *mesaCtx;
 
        mesaCtx = &ctx->Base;
 
@@ -586,19 +729,21 @@ dri_make_current(__DRIcontext * cPriv,
                 __DRIdrawable * driDrawPriv,
                 __DRIdrawable * driReadPriv)
 {
-    GLcontext *mesaCtx;
-    GLframebuffer *mesaDraw;
-    GLframebuffer *mesaRead;
+    struct gl_context *mesaCtx;
+    struct gl_framebuffer *mesaDraw;
+    struct gl_framebuffer *mesaRead;
     TRACE;
 
     if (cPriv) {
        struct dri_context *ctx = dri_context(cPriv);
-       struct dri_drawable *draw = dri_drawable(driDrawPriv);
-       struct dri_drawable *read = dri_drawable(driReadPriv);
+       struct dri_drawable *draw;
+       struct dri_drawable *read;
 
        if (!driDrawPriv || !driReadPriv)
            return GL_FALSE;
 
+       draw = dri_drawable(driDrawPriv);
+       read = dri_drawable(driReadPriv);
        mesaCtx = &ctx->Base;
        mesaDraw = &draw->Base;
        mesaRead = &read->Base;
@@ -633,6 +778,10 @@ dri_unbind_context(__DRIcontext * cPriv)
 {
     TRACE;
     (void) cPriv;
+
+    /* Unset current context and dispath table */
+    _mesa_make_current(NULL, NULL, NULL);
+
     return GL_TRUE;
 }