include surface.offset in address calculations
[mesa.git] / src / mesa / pipe / softpipe / sp_context.c
index 8655aa83fd4518542dbdb139efb10e69de203573..0794d9a88802a88f8c11c71398761b4c31e80a9c 100644 (file)
 #include "main/macros.h"
 #include "pipe/draw/draw_context.h"
 #include "pipe/p_defines.h"
-#include "sp_context.h"
+#include "sp_buffer.h"
 #include "sp_clear.h"
+#include "sp_context.h"
+#include "sp_flush.h"
+#include "sp_prim_setup.h"
+#include "sp_region.h"
 #include "sp_state.h"
 #include "sp_surface.h"
-#include "sp_prim_setup.h"
+#include "sp_tex_layout.h"
+#include "sp_winsys.h"
+
+
+
+/**
+ * Return list of supported surface/texture formats.
+ * If we find texture and drawable support differs, add a selector
+ * parameter or another function.
+ */
+static const GLuint *
+softpipe_supported_formats(struct pipe_context *pipe, GLuint *numFormats)
+{
+   static const GLuint supported[] = {
+      PIPE_FORMAT_U_R8_G8_B8_A8,
+      PIPE_FORMAT_U_A8_R8_G8_B8,
+      PIPE_FORMAT_U_R5_G6_B5,
+      PIPE_FORMAT_U_L8,
+      PIPE_FORMAT_U_A8,
+      PIPE_FORMAT_U_I8,
+      PIPE_FORMAT_U_L8_A8,
+      PIPE_FORMAT_S_R16_G16_B16_A16,
+      PIPE_FORMAT_YCBCR,
+      PIPE_FORMAT_YCBCR_REV,
+      PIPE_FORMAT_U_Z16,
+      PIPE_FORMAT_U_Z32,
+      PIPE_FORMAT_F_Z32,
+      PIPE_FORMAT_S8_Z24,
+      PIPE_FORMAT_U_S8
+   };
+
+   *numFormats = sizeof(supported)/sizeof(supported[0]);
+   return supported;
+}
+
 
 
 static void map_surfaces(struct softpipe_context *sp)
 {
+   struct pipe_context *pipe = &sp->pipe;
    GLuint i;
 
    for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
       struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.cbufs[i]);
-      struct pipe_buffer *buf = &sps->surface.buffer;
-      buf->map(buf, PIPE_MAP_READ_WRITE);
+      if (sps->surface.region)
+         pipe->region_map(pipe, sps->surface.region);
    }
 
    if (sp->framebuffer.zbuf) {
       struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.zbuf);
-      struct pipe_buffer *buf = &sps->surface.buffer;
-      buf->map(buf, PIPE_MAP_READ_WRITE);
+      if (sps->surface.region)
+         pipe->region_map(pipe, sps->surface.region);
+   }
+
+   /* textures */
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      struct pipe_mipmap_tree *mt = sp->texture[i];
+      if (mt) {
+         pipe->region_map(pipe, mt->region);
+      }
    }
 
    /* XXX depth & stencil bufs */
@@ -62,19 +109,29 @@ static void map_surfaces(struct softpipe_context *sp)
 
 static void unmap_surfaces(struct softpipe_context *sp)
 {
+   struct pipe_context *pipe = &sp->pipe;
    GLuint i;
 
    for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
       struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.cbufs[i]);
-      struct pipe_buffer *buf = &sps->surface.buffer;
-      buf->unmap(buf);
+      if (sps->surface.region)
+         pipe->region_unmap(pipe, sps->surface.region);
    }
 
    if (sp->framebuffer.zbuf) {
       struct softpipe_surface *sps = softpipe_surface(sp->framebuffer.zbuf);
-      struct pipe_buffer *buf = &sps->surface.buffer;
-      buf->unmap(buf);
+      if (sps->surface.region)
+         pipe->region_unmap(pipe, sps->surface.region);
    }
+
+   /* textures */
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      struct pipe_mipmap_tree *mt = sp->texture[i];
+      if (mt) {
+         pipe->region_unmap(pipe, mt->region);
+      }
+   }
+
    /* XXX depth & stencil bufs */
 }
 
@@ -104,6 +161,25 @@ static void softpipe_draw_vb( struct pipe_context *pipe,
 }
 
 
+static void
+softpipe_draw_vertices(struct pipe_context *pipe,
+                       GLuint mode,
+                       GLuint numVertex, const GLfloat *verts,
+                       GLuint numAttribs, const GLuint attribs[])
+{
+   struct softpipe_context *softpipe = softpipe_context( pipe );
+
+   if (softpipe->dirty)
+      softpipe_update_derived( softpipe );
+
+   /* XXX move mapping/unmapping to higher/coarser level? */
+   map_surfaces(softpipe);
+   draw_vertices(softpipe->draw, mode, numVertex, verts, numAttribs, attribs);
+   unmap_surfaces(softpipe);
+}
+
+
+
 static void softpipe_reset_occlusion_counter(struct pipe_context *pipe)
 {
    struct softpipe_context *softpipe = softpipe_context( pipe );
@@ -118,11 +194,14 @@ static GLuint softpipe_get_occlusion_counter(struct pipe_context *pipe)
 }
 
 
-struct pipe_context *softpipe_create( void )
+struct pipe_context *softpipe_create( struct softpipe_winsys *sws )
 {
    struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
 
    softpipe->pipe.destroy = softpipe_destroy;
+
+   softpipe->pipe.supported_formats = softpipe_supported_formats;
+
    softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state;
    softpipe->pipe.set_blend_color = softpipe_set_blend_color;
    softpipe->pipe.set_blend_state = softpipe_set_blend_state;
@@ -139,10 +218,16 @@ struct pipe_context *softpipe_create( void )
    softpipe->pipe.set_texture_state = softpipe_set_texture_state;
    softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
    softpipe->pipe.draw_vb = softpipe_draw_vb;
+   softpipe->pipe.draw_vertices = softpipe_draw_vertices;
    softpipe->pipe.clear = softpipe_clear;
+   softpipe->pipe.flush = softpipe_flush;
+   softpipe->pipe.finish = softpipe_finish;
    softpipe->pipe.reset_occlusion_counter = softpipe_reset_occlusion_counter;
    softpipe->pipe.get_occlusion_counter = softpipe_get_occlusion_counter;
 
+   softpipe->pipe.mipmap_tree_layout = softpipe_mipmap_tree_layout;
+   softpipe->pipe.get_tex_surface = softpipe_get_tex_surface;
+
    softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
    softpipe->quad.shade = sp_quad_shade_stage(softpipe);
    softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
@@ -155,12 +240,19 @@ struct pipe_context *softpipe_create( void )
    softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
    softpipe->quad.output = sp_quad_output_stage(softpipe);
 
+   softpipe->winsys = sws;
+
    /*
     * Create drawing context and plug our rendering stage into it.
     */
    softpipe->draw = draw_create();
+   assert(softpipe->draw);
    draw_set_setup_stage(softpipe->draw, sp_draw_render_stage(softpipe));
 
+   sp_init_buffer_functions(softpipe);
+   sp_init_region_functions(softpipe);
+   sp_init_surface_functions(softpipe);
+
    /*
     * XXX we could plug GL selection/feedback into the drawing pipeline
     * by specifying a different setup/render stage.