X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_atom_image.c;h=421c926cf04163628feb18a7d8574ff0be74aa4f;hb=5530cb1296cef759ea2f94e581da0a4d853a9f5f;hp=2fb37f5b0c6ef2c1b8fdbd7109f591e2060da60d;hpb=ae632afe4fd860f016d2e5b360d66dc4e72ce72a;p=mesa.git diff --git a/src/mesa/state_tracker/st_atom_image.c b/src/mesa/state_tracker/st_atom_image.c index 2fb37f5b0c6..421c926cf04 100644 --- a/src/mesa/state_tracker/st_atom_image.c +++ b/src/mesa/state_tracker/st_atom_image.c @@ -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" @@ -44,177 +45,169 @@ #include "st_program.h" #include "st_format.h" -static void -st_bind_images(struct st_context *st, struct gl_linked_shader *shader, - enum pipe_shader_type shader_type) +/** + * Convert a gl_image_unit object to a pipe_image_view object. + */ +void +st_convert_image(const struct st_context *st, const struct gl_image_unit *u, + struct pipe_image_view *img) { - unsigned i; - struct pipe_image_view images[MAX_IMAGE_UNIFORMS]; - struct gl_program_constants *c; + struct st_texture_object *stObj = st_texture_object(u->TexObj); + + img->format = st_mesa_format_to_pipe_format(st, u->_ActualFormat); + + switch (u->Access) { + case GL_READ_ONLY: + img->access = PIPE_IMAGE_ACCESS_READ; + break; + case GL_WRITE_ONLY: + img->access = PIPE_IMAGE_ACCESS_WRITE; + break; + case GL_READ_WRITE: + img->access = PIPE_IMAGE_ACCESS_READ_WRITE; + break; + default: + unreachable("bad gl_image_unit::Access"); + } - if (!shader || !st->pipe->set_shader_images) - return; + if (stObj->base.Target == GL_TEXTURE_BUFFER) { + struct st_buffer_object *stbuf = + st_buffer_object(stObj->base.BufferObject); + unsigned base, size; - c = &st->ctx->Const.Program[shader->Stage]; + if (!stbuf || !stbuf->buffer) { + memset(img, 0, sizeof(*img)); + return; + } + struct pipe_resource *buf = stbuf->buffer; - for (i = 0; i < shader->Program->info.num_images; i++) { - struct gl_image_unit *u = - &st->ctx->ImageUnits[shader->Program->sh.ImageUnits[i]]; - struct st_texture_object *stObj = st_texture_object(u->TexObj); - struct pipe_image_view *img = &images[i]; + base = stObj->base.BufferOffset; + assert(base < buf->width0); + size = MIN2(buf->width0 - base, (unsigned)stObj->base.BufferSize); - if (!_mesa_is_image_unit_valid(st->ctx, u) || - !st_finalize_texture(st->ctx, st->pipe, u->TexObj) || + 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)); - continue; + return; } img->resource = stObj->pt; - img->format = st_mesa_format_to_pipe_format(st, u->_ActualFormat); - - switch (u->Access) { - case GL_READ_ONLY: - img->access = PIPE_IMAGE_ACCESS_READ; - break; - case GL_WRITE_ONLY: - img->access = PIPE_IMAGE_ACCESS_WRITE; - break; - case GL_READ_WRITE: - img->access = PIPE_IMAGE_ACCESS_READ_WRITE; - break; - default: - unreachable("bad gl_image_unit::Access"); + 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; + img->u.tex.last_layer = u_minify(stObj->pt->depth0, img->u.tex.level) - 1; + } else { + img->u.tex.first_layer = u->_Layer; + img->u.tex.last_layer = u->_Layer; + } + } else { + img->u.tex.first_layer = u->_Layer + stObj->base.MinLayer; + img->u.tex.last_layer = u->_Layer + stObj->base.MinLayer; + if (u->Layered && img->resource->array_size > 1) { + if (stObj->base.Immutable) + img->u.tex.last_layer += stObj->base.NumLayers - 1; + else + img->u.tex.last_layer += img->resource->array_size - 1; + } } + } +} - if (stObj->pt->target == PIPE_BUFFER) { - unsigned base, size; +/** + * 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) +{ + struct gl_image_unit *u = &st->ctx->ImageUnits[imgUnit]; - base = stObj->base.BufferOffset; - assert(base < stObj->pt->width0); - size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize); + if (!_mesa_is_image_unit_valid(st->ctx, u)) { + memset(img, 0, sizeof(*img)); + return; + } - img->u.buf.offset = base; - img->u.buf.size = size; - } else { - img->u.tex.level = u->Level + stObj->base.MinLevel; - if (stObj->pt->target == PIPE_TEXTURE_3D) { - if (u->Layered) { - img->u.tex.first_layer = 0; - img->u.tex.last_layer = u_minify(stObj->pt->depth0, img->u.tex.level) - 1; - } else { - img->u.tex.first_layer = u->_Layer; - img->u.tex.last_layer = u->_Layer; - } - } else { - img->u.tex.first_layer = u->_Layer + stObj->base.MinLayer; - img->u.tex.last_layer = u->_Layer + stObj->base.MinLayer; - if (u->Layered && img->resource->array_size > 1) { - if (stObj->base.Immutable) - img->u.tex.last_layer += stObj->base.NumLayers - 1; - else - img->u.tex.last_layer += img->resource->array_size - 1; - } - } - } + st_convert_image(st, u, img); +} + +static void +st_bind_images(struct st_context *st, struct gl_program *prog, + enum pipe_shader_type shader_type) +{ + unsigned i; + struct pipe_image_view images[MAX_IMAGE_UNIFORMS]; + struct gl_program_constants *c; + + if (!prog || !st->pipe->set_shader_images) + return; + + c = &st->ctx->Const.Program[prog->info.stage]; + + for (i = 0; i < prog->info.num_images; i++) { + struct pipe_image_view *img = &images[i]; + + st_convert_image_from_unit(st, img, prog->sh.ImageUnits[i]); } cso_set_shader_images(st->cso_context, shader_type, 0, - shader->Program->info.num_images, images); + prog->info.num_images, images); /* clear out any stale shader images */ - if (shader->Program->info.num_images < c->MaxImageUniforms) + if (prog->info.num_images < c->MaxImageUniforms) cso_set_shader_images( - st->cso_context, shader_type, - shader->Program->info.num_images, - c->MaxImageUniforms - shader->Program->info.num_images, - NULL); + st->cso_context, shader_type, prog->info.num_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_shader_program *prog = + struct gl_program *prog = st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; - if (!prog) - return; - - st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_VERTEX], PIPE_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_shader_program *prog = + struct gl_program *prog = st->ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; - if (!prog) - return; - - st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_FRAGMENT], PIPE_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_shader_program *prog = + struct gl_program *prog = st->ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; - if (!prog) - return; - - st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_GEOMETRY], PIPE_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_shader_program *prog = + struct gl_program *prog = st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; - if (!prog) - return; - - st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_TESS_CTRL], PIPE_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_shader_program *prog = + struct gl_program *prog = st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; - if (!prog) - return; - - st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_TESS_EVAL], PIPE_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_shader_program *prog = + struct gl_program *prog = st->ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; - if (!prog) - return; - - st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_COMPUTE], PIPE_SHADER_COMPUTE); + st_bind_images(st, prog, PIPE_SHADER_COMPUTE); } - -const struct st_tracked_state st_bind_cs_images = { - bind_cs_images -};