*
**************************************************************************/
-#include "main/imports.h"
+#include "util/imports.h"
#include "main/shaderimage.h"
#include "program/prog_parameter.h"
#include "program/prog_print.h"
#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) {
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;
}
}
+/**
+ * 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)
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);
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];
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];
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];
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];
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];
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
-};