i965: Add support for sampling texture buffer objects on gen7+.
authorEric Anholt <eric@anholt.net>
Tue, 27 Mar 2012 16:37:40 +0000 (09:37 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 9 Apr 2012 21:35:27 +0000 (14:35 -0700)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/gen7_sampler_state.c
src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
src/mesa/drivers/dri/intel/intel_tex_validate.c

index e59ab622c6c16618c6c224950e785496c30e5e66..b358306a92820bc9c00ba05823010cdad4cb21c2 100644 (file)
@@ -328,7 +328,7 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx,
 {
    const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
 
-   if (unit->_ReallyEnabled) {
+   if (unit->_ReallyEnabled && unit->_Current->Target != GL_TEXTURE_BUFFER) {
       const struct gl_texture_object *t = unit->_Current;
       const struct gl_texture_image *img = t->Image[0][t->BaseLevel];
       struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, i);
index d2699a159113b98692dafdee587d4f6013b93fce..0cf62298412a8da9162c148f4a18916ccb8f637c 100644 (file)
@@ -43,6 +43,10 @@ gen7_update_sampler_state(struct brw_context *brw, int unit,
    struct gl_sampler_object *gl_sampler = _mesa_get_samplerobj(ctx, unit);
    bool using_nearest = false;
 
+   /* These don't use samplers at all. */
+   if (texObj->Target == GL_TEXTURE_BUFFER)
+      return;
+
    switch (gl_sampler->MinFilter) {
    case GL_NEAREST:
       sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST;
index 439d8b082cacb9998a742d2eb28cb930247fde73..cbccd2b852d6b52d6dd1e3dec0673f5c84a8f6a9 100644 (file)
@@ -28,6 +28,7 @@
 #include "intel_batchbuffer.h"
 #include "intel_tex.h"
 #include "intel_fbo.h"
+#include "intel_buffer_objects.h"
 
 #include "brw_context.h"
 #include "brw_state.h"
@@ -53,6 +54,62 @@ gen7_set_surface_tiling(struct gen7_surface_state *surf, uint32_t tiling)
    }
 }
 
+static void
+gen7_update_buffer_texture_surface(struct gl_context *ctx, GLuint unit)
+{
+   struct brw_context *brw = brw_context(ctx);
+   struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
+   const GLuint surf_index = SURF_INDEX_TEXTURE(unit);
+   struct gen7_surface_state *surf;
+   struct intel_buffer_object *intel_obj =
+      intel_buffer_object(tObj->BufferObject);
+   drm_intel_bo *bo = intel_obj ? intel_obj->buffer : NULL;
+   gl_format format = tObj->_BufferObjectFormat;
+   int texel_size = _mesa_get_format_bytes(format);
+
+   surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
+                         sizeof(*surf), 32, &brw->wm.surf_offset[surf_index]);
+   memset(surf, 0, sizeof(*surf));
+
+   surf->ss0.surface_type = BRW_SURFACE_BUFFER;
+   surf->ss0.surface_format = brw_format_for_mesa_format(format);
+
+   surf->ss0.render_cache_read_write = 1;
+
+   if (surf->ss0.surface_format == 0 && format != MESA_FORMAT_RGBA_FLOAT32) {
+      _mesa_problem(NULL, "bad format %s for texture buffer\n",
+                   _mesa_get_format_name(format));
+   }
+
+   if (bo) {
+      surf->ss1.base_addr = bo->offset; /* reloc */
+
+      /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
+       * bspec ("Data Cache") says that the data cache does not exist as
+       * a separate cache and is just the sampler cache.
+       */
+      drm_intel_bo_emit_reloc(brw->intel.batch.bo,
+                             (brw->wm.surf_offset[surf_index] +
+                              offsetof(struct gen7_surface_state, ss1)),
+                             bo, 0,
+                             I915_GEM_DOMAIN_SAMPLER, 0);
+
+      int w = intel_obj->Base.Size / texel_size;
+      surf->ss2.width = w & 0x7f;            /* bits 6:0 of size or width */
+      surf->ss2.height = (w >> 7) & 0x1fff;  /* bits 19:7 of size or width */
+      surf->ss3.depth = (w >> 20) & 0x7f;    /* bits 26:20 of size or width */
+      surf->ss3.pitch = texel_size - 1;
+} else {
+      surf->ss1.base_addr = 0;
+      surf->ss2.width = 0;
+      surf->ss2.height = 0;
+      surf->ss3.depth = 0;
+      surf->ss3.pitch = 0;
+   }
+
+   gen7_set_surface_tiling(surf, I915_TILING_NONE);
+}
+
 static void
 gen7_update_texture_surface(struct gl_context *ctx, GLuint unit)
 {
@@ -66,6 +123,11 @@ gen7_update_texture_surface(struct gl_context *ctx, GLuint unit)
    struct gen7_surface_state *surf;
    int width, height, depth;
 
+   if (tObj->Target == GL_TEXTURE_BUFFER) {
+      gen7_update_buffer_texture_surface(ctx, unit);
+      return;
+   }
+
    intel_miptree_get_dimensions_for_image(firstImage, &width, &height, &depth);
 
    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
index 0f4a1a831933e20f8d17314349705d3a860390ab..256c21ec826defd527ebe5fcc15f977a9ff91ab1 100644 (file)
@@ -43,6 +43,10 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
    struct intel_texture_image *firstImage;
    int width, height, depth;
 
+   /* TBOs require no validation -- they always just point to their BO. */
+   if (tObj->Target == GL_TEXTURE_BUFFER)
+      return true;
+
    /* We know/require this is true by now: 
     */
    assert(intelObj->base._BaseComplete);