replace _mesa_logbase2 with util_logbase2
[mesa.git] / src / mesa / state_tracker / st_atom_image.c
index 077bafd09a233123d2f1ec3d772bd968942a80c7..598109d24f469f2f81b448524c9c767d7520feea 100644 (file)
@@ -24,7 +24,7 @@
  *
  **************************************************************************/
 
-#include "main/imports.h"
+#include "util/imports.h"
 #include "main/shaderimage.h"
 #include "program/prog_parameter.h"
 #include "program/prog_print.h"
@@ -36,6 +36,7 @@
 #include "util/u_surface.h"
 #include "cso_cache/cso_context.h"
 
+#include "st_cb_bufferobjects.h"
 #include "st_cb_texture.h"
 #include "st_debug.h"
 #include "st_texture.h"
  */
 void
 st_convert_image(const struct st_context *st, const struct gl_image_unit *u,
-                 struct pipe_image_view *img)
+                 struct pipe_image_view *img, unsigned shader_access)
 {
    struct st_texture_object *stObj = st_texture_object(u->TexObj);
 
-   img->resource = stObj->pt;
    img->format = st_mesa_format_to_pipe_format(st, u->_ActualFormat);
 
    switch (u->Access) {
@@ -70,17 +70,51 @@ st_convert_image(const struct st_context *st, const struct gl_image_unit *u,
       unreachable("bad gl_image_unit::Access");
    }
 
-   if (stObj->pt->target == PIPE_BUFFER) {
+   switch (shader_access) {
+   case GL_NONE:
+      img->shader_access = 0;
+      break;
+   case GL_READ_ONLY:
+      img->shader_access = PIPE_IMAGE_ACCESS_READ;
+      break;
+   case GL_WRITE_ONLY:
+      img->shader_access = PIPE_IMAGE_ACCESS_WRITE;
+      break;
+   case GL_READ_WRITE:
+      img->shader_access = PIPE_IMAGE_ACCESS_READ_WRITE;
+      break;
+   default:
+      unreachable("bad gl_image_unit::Access");
+   }
+
+   if (stObj->base.Target == GL_TEXTURE_BUFFER) {
+      struct st_buffer_object *stbuf =
+         st_buffer_object(stObj->base.BufferObject);
       unsigned base, size;
 
+      if (!stbuf || !stbuf->buffer) {
+         memset(img, 0, sizeof(*img));
+         return;
+      }
+      struct pipe_resource *buf = stbuf->buffer;
+
       base = stObj->base.BufferOffset;
-      assert(base < stObj->pt->width0);
-      size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize);
+      assert(base < buf->width0);
+      size = MIN2(buf->width0 - base, (unsigned)stObj->base.BufferSize);
 
+      img->resource = stbuf->buffer;
       img->u.buf.offset = base;
       img->u.buf.size = size;
    } else {
+      if (!st_finalize_texture(st->ctx, st->pipe, u->TexObj, 0) ||
+          !stObj->pt) {
+         memset(img, 0, sizeof(*img));
+         return;
+      }
+
+      img->resource = stObj->pt;
       img->u.tex.level = u->Level + stObj->base.MinLevel;
+      assert(img->u.tex.level <= img->resource->last_level);
       if (stObj->pt->target == PIPE_TEXTURE_3D) {
          if (u->Layered) {
             img->u.tex.first_layer = 0;
@@ -102,6 +136,25 @@ st_convert_image(const struct st_context *st, const struct gl_image_unit *u,
    }
 }
 
+/**
+ * Get a pipe_image_view object from an image unit.
+ */
+void
+st_convert_image_from_unit(const struct st_context *st,
+                           struct pipe_image_view *img,
+                           GLuint imgUnit,
+                           unsigned shader_access)
+{
+   struct gl_image_unit *u = &st->ctx->ImageUnits[imgUnit];
+
+   if (!_mesa_is_image_unit_valid(st->ctx, u)) {
+      memset(img, 0, sizeof(*img));
+      return;
+   }
+
+   st_convert_image(st, u, img, shader_access);
+}
+
 static void
 st_bind_images(struct st_context *st, struct gl_program *prog,
                enum pipe_shader_type shader_type)
@@ -116,19 +169,10 @@ st_bind_images(struct st_context *st, struct gl_program *prog,
    c = &st->ctx->Const.Program[prog->info.stage];
 
    for (i = 0; i < prog->info.num_images; i++) {
-      struct gl_image_unit *u =
-         &st->ctx->ImageUnits[prog->sh.ImageUnits[i]];
-      struct st_texture_object *stObj = st_texture_object(u->TexObj);
       struct pipe_image_view *img = &images[i];
 
-      if (!_mesa_is_image_unit_valid(st->ctx, u) ||
-          !st_finalize_texture(st->ctx, st->pipe, u->TexObj, 0) ||
-          !stObj->pt) {
-         memset(img, 0, sizeof(*img));
-         continue;
-      }
-
-      st_convert_image(st, u, img);
+      st_convert_image_from_unit(st, img, prog->sh.ImageUnits[i],
+                                 prog->sh.ImageAccess[i]);
    }
    cso_set_shader_images(st->cso_context, shader_type, 0,
                          prog->info.num_images, images);
@@ -139,7 +183,7 @@ st_bind_images(struct st_context *st, struct gl_program *prog,
             c->MaxImageUniforms - prog->info.num_images, NULL);
 }
 
-static void bind_vs_images(struct st_context *st)
+void st_bind_vs_images(struct st_context *st)
 {
    struct gl_program *prog =
       st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
@@ -147,11 +191,7 @@ static void bind_vs_images(struct st_context *st)
    st_bind_images(st, prog, PIPE_SHADER_VERTEX);
 }
 
-const struct st_tracked_state st_bind_vs_images = {
-   bind_vs_images
-};
-
-static void bind_fs_images(struct st_context *st)
+void st_bind_fs_images(struct st_context *st)
 {
    struct gl_program *prog =
       st->ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
@@ -159,11 +199,7 @@ static void bind_fs_images(struct st_context *st)
    st_bind_images(st, prog, PIPE_SHADER_FRAGMENT);
 }
 
-const struct st_tracked_state st_bind_fs_images = {
-   bind_fs_images
-};
-
-static void bind_gs_images(struct st_context *st)
+void st_bind_gs_images(struct st_context *st)
 {
    struct gl_program *prog =
       st->ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
@@ -171,11 +207,7 @@ static void bind_gs_images(struct st_context *st)
    st_bind_images(st, prog, PIPE_SHADER_GEOMETRY);
 }
 
-const struct st_tracked_state st_bind_gs_images = {
-   bind_gs_images
-};
-
-static void bind_tcs_images(struct st_context *st)
+void st_bind_tcs_images(struct st_context *st)
 {
    struct gl_program *prog =
       st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
@@ -183,11 +215,7 @@ static void bind_tcs_images(struct st_context *st)
    st_bind_images(st, prog, PIPE_SHADER_TESS_CTRL);
 }
 
-const struct st_tracked_state st_bind_tcs_images = {
-   bind_tcs_images
-};
-
-static void bind_tes_images(struct st_context *st)
+void st_bind_tes_images(struct st_context *st)
 {
    struct gl_program *prog =
       st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
@@ -195,18 +223,10 @@ static void bind_tes_images(struct st_context *st)
    st_bind_images(st, prog, PIPE_SHADER_TESS_EVAL);
 }
 
-const struct st_tracked_state st_bind_tes_images = {
-   bind_tes_images
-};
-
-static void bind_cs_images(struct st_context *st)
+void st_bind_cs_images(struct st_context *st)
 {
    struct gl_program *prog =
       st->ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
 
    st_bind_images(st, prog, PIPE_SHADER_COMPUTE);
 }
-
-const struct st_tracked_state st_bind_cs_images = {
-   bind_cs_images
-};