[Mesa-dev] [PATCH 2/3] gallium: change pipe_image_view::first_element/last_element -> offset/size
Marek Olšák
maraeo at gmail.com
Fri Aug 12 16:46:23 UTC 2016
From: Marek Olšák <marek.olsak at amd.com>
This is required by OpenGL. Our hardware supports this.
Example: Bind RGBA32F with offset = 4 bytes.
---
src/gallium/auxiliary/util/u_dump_state.c | 4 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_state.c | 4 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_tex.c | 24 +++++++-----------------
src/gallium/drivers/radeonsi/si_descriptors.c | 16 ++++------------
src/gallium/drivers/softpipe/sp_image.c | 6 +++---
src/gallium/drivers/trace/tr_dump_state.c | 4 ++--
src/gallium/include/pipe/p_state.h | 4 ++--
src/mesa/state_tracker/st_atom_image.c | 10 ++--------
src/mesa/state_tracker/st_cb_readpixels.c | 5 +++--
9 files changed, 27 insertions(+), 50 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
index 4568dc6..6aecee1 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -715,22 +715,22 @@ util_dump_image_view(FILE *stream, const struct pipe_image_view *state)
util_dump_null(stream);
return;
}
util_dump_struct_begin(stream, "pipe_image_view");
util_dump_member(stream, ptr, state, resource);
util_dump_member(stream, format, state, format);
if (state->resource->target == PIPE_BUFFER) {
- util_dump_member(stream, uint, state, u.buf.first_element);
- util_dump_member(stream, uint, state, u.buf.last_element);
+ util_dump_member(stream, uint, state, u.buf.offset);
+ util_dump_member(stream, uint, state, u.buf.size);
}
else {
util_dump_member(stream, uint, state, u.tex.first_layer);
util_dump_member(stream, uint, state, u.tex.last_layer);
util_dump_member(stream, uint, state, u.tex.level);
}
util_dump_struct_end(stream);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index fcb695a..b9ac9f4 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -1264,22 +1264,22 @@ nvc0_bind_images_range(struct nvc0_context *nvc0, const unsigned s,
for (i = start; i < end; ++i) {
struct pipe_image_view *img = &nvc0->images[s][i];
const unsigned p = i - start;
if (img->resource == pimages[p].resource &&
img->format == pimages[p].format &&
img->access == pimages[p].access) {
if (img->resource == NULL)
continue;
if (img->resource->target == PIPE_BUFFER &&
- img->u.buf.first_element == pimages[p].u.buf.first_element &&
- img->u.buf.last_element == pimages[p].u.buf.last_element)
+ img->u.buf.offset == pimages[p].u.buf.offset &&
+ img->u.buf.size == pimages[p].u.buf.size)
continue;
if (img->resource->target != PIPE_BUFFER &&
img->u.tex.first_layer == pimages[p].u.tex.first_layer &&
img->u.tex.last_layer == pimages[p].u.tex.last_layer &&
img->u.tex.level == pimages[p].u.tex.level)
continue;
}
mask |= (1 << i);
if (pimages[p].resource)
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
index b6e0ba8..4fa2621 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
@@ -252,25 +252,22 @@ gm107_create_texture_view_from_image(struct pipe_context *pipe,
if (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY)
target = PIPE_TEXTURE_2D_ARRAY;
templ.format = view->format;
templ.swizzle_r = PIPE_SWIZZLE_X;
templ.swizzle_g = PIPE_SWIZZLE_Y;
templ.swizzle_b = PIPE_SWIZZLE_Z;
templ.swizzle_a = PIPE_SWIZZLE_W;
if (target == PIPE_BUFFER) {
- templ.u.buf.offset = view->u.buf.first_element *
- util_format_get_blocksize(view->format);
- templ.u.buf.size = (view->u.buf.last_element -
- view->u.buf.first_element + 1) *
- util_format_get_blocksize(view->format);
+ templ.u.buf.offset = view->u.buf.offset;
+ templ.u.buf.size = view->u.buf.size;
} else {
templ.u.tex.first_layer = view->u.tex.first_layer;
templ.u.tex.last_layer = view->u.tex.last_layer;
templ.u.tex.first_level = templ.u.tex.last_level = view->u.tex.level;
}
flags = NV50_TEXVIEW_SCALED_COORDS;
return nvc0_create_texture_view(pipe, &res->base, &templ, flags, target);
}
@@ -769,21 +766,21 @@ static const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT];
static void
nvc0_get_surface_dims(struct pipe_image_view *view, int *width, int *height,
int *depth)
{
struct nv04_resource *res = nv04_resource(view->resource);
int level;
*width = *height = *depth = 1;
if (res->base.target == PIPE_BUFFER) {
- *width = view->u.buf.last_element - view->u.buf.first_element + 1;
+ *width = view->u.buf.size / util_format_get_blocksize(view->format);
return;
}
level = view->u.tex.level;
*width = u_minify(view->resource->width0, level);
*height = u_minify(view->resource->height0, level);
*depth = u_minify(view->resource->depth0, level);
switch (res->base.target) {
case PIPE_TEXTURE_1D_ARRAY:
@@ -800,31 +797,26 @@ nvc0_get_surface_dims(struct pipe_image_view *view, int *width, int *height,
default:
assert(!"unexpected texture target");
break;
}
}
void
nvc0_mark_image_range_valid(const struct pipe_image_view *view)
{
struct nv04_resource *res = (struct nv04_resource *)view->resource;
- const struct util_format_description *desc;
- unsigned stride;
assert(view->resource->target == PIPE_BUFFER);
- desc = util_format_description(view->format);
- stride = desc->block.bits / 8;
-
util_range_add(&res->valid_buffer_range,
- stride * (view->u.buf.first_element),
- stride * (view->u.buf.last_element + 1));
+ view->u.buf.offset,
+ view->u.buf.offset + view->u.buf.size);
}
void
nve4_set_surface_info(struct nouveau_pushbuf *push,
struct pipe_image_view *view,
struct nvc0_context *nvc0)
{
struct nvc0_screen *screen = nvc0->screen;
struct nv04_resource *res;
uint64_t address;
@@ -896,23 +888,21 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
default:
break;
}
#else
info[1] |= log2cpp << 16;
info[1] |= 0x4000;
info[1] |= (0x0f00 & nve4_su_format_aux_map[view->format]);
#endif
if (res->base.target == PIPE_BUFFER) {
- unsigned blocksize = util_format_get_blocksize(view->format);
-
- address += view->u.buf.first_element * blocksize;
+ address += view->u.buf.offset;
info[0] = address >> 8;
info[2] = width - 1;
info[2] |= (0xff & nve4_su_format_aux_map[view->format]) << 22;
info[3] = 0;
info[4] = 0;
info[5] = 0;
info[6] = 0;
info[7] = 0;
info[14] = 0;
@@ -1023,21 +1013,21 @@ nvc0_validate_suf(struct nvc0_context *nvc0, int s)
else
rt = (rt << 4) | (0x14 << 12);
/* get surface dimensions based on the target. */
nvc0_get_surface_dims(view, &width, &height, &depth);
address = res->address;
if (res->base.target == PIPE_BUFFER) {
unsigned blocksize = util_format_get_blocksize(view->format);
- address += view->u.buf.first_element * blocksize;
+ address += view->u.buf.offset;
assert(!(address & 0xff));
if (view->access & PIPE_IMAGE_ACCESS_WRITE)
nvc0_mark_image_range_valid(view);
PUSH_DATAh(push, address);
PUSH_DATA (push, address);
PUSH_DATA (push, align(width * blocksize, 0x100));
PUSH_DATA (push, NVC0_3D_IMAGE_HEIGHT_LINEAR | 1);
PUSH_DATA (push, rt);
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index a3e4564..0e026e9 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -593,31 +593,26 @@ si_disable_shader_image(struct si_context *ctx, unsigned shader, unsigned slot)
images->enabled_mask &= ~(1u << slot);
descs->dirty_mask |= 1u << slot;
ctx->descriptors_dirty |= 1u << si_image_descriptors_idx(shader);
}
}
static void
si_mark_image_range_valid(const struct pipe_image_view *view)
{
struct r600_resource *res = (struct r600_resource *)view->resource;
- const struct util_format_description *desc;
- unsigned stride;
assert(res && res->b.b.target == PIPE_BUFFER);
- desc = util_format_description(view->format);
- stride = desc->block.bits / 8;
-
util_range_add(&res->valid_buffer_range,
- stride * (view->u.buf.first_element),
- stride * (view->u.buf.last_element + 1));
+ view->u.buf.offset,
+ view->u.buf.offset + view->u.buf.size);
}
static void si_set_shader_image(struct si_context *ctx,
unsigned shader,
unsigned slot, const struct pipe_image_view *view)
{
struct si_screen *screen = ctx->screen;
struct si_images_info *images = &ctx->images[shader];
struct si_descriptors *descs = si_image_descriptors(ctx, shader);
struct r600_resource *res;
@@ -634,25 +629,22 @@ static void si_set_shader_image(struct si_context *ctx,
si_sampler_view_add_buffer(ctx, &res->b.b,
RADEON_USAGE_READWRITE, false, true);
if (res->b.b.target == PIPE_BUFFER) {
if (view->access & PIPE_IMAGE_ACCESS_WRITE)
si_mark_image_range_valid(view);
si_make_buffer_descriptor(screen, res,
view->format,
- view->u.buf.first_element *
- util_format_get_blocksize(view->format),
- (view->u.buf.last_element -
- view->u.buf.first_element + 1) *
- util_format_get_blocksize(view->format),
+ view->u.buf.offset,
+ view->u.buf.size,
descs->list + slot * 8);
images->compressed_colortex_mask &= ~(1 << slot);
} else {
static const unsigned char swizzle[4] = { 0, 1, 2, 3 };
struct r600_texture *tex = (struct r600_texture *)res;
unsigned level = view->u.tex.level;
unsigned width, height, depth;
uint32_t *desc = descs->list + slot * 8;
bool uses_dcc = tex->dcc_offset &&
tex->surface.level[level].dcc_enabled;
diff --git a/src/gallium/drivers/softpipe/sp_image.c b/src/gallium/drivers/softpipe/sp_image.c
index 0be11cb..d5547e2 100644
--- a/src/gallium/drivers/softpipe/sp_image.c
+++ b/src/gallium/drivers/softpipe/sp_image.c
@@ -32,21 +32,21 @@
* first element for a buffer or layer/level for texture.
*/
static uint32_t
get_image_offset(const struct softpipe_resource *spr,
const struct pipe_image_view *iview,
enum pipe_format format, unsigned r_coord)
{
int base_layer = 0;
if (spr->base.target == PIPE_BUFFER)
- return iview->u.buf.first_element * util_format_get_blocksize(format);
+ return iview->u.buf.offset;
if (spr->base.target == PIPE_TEXTURE_1D_ARRAY ||
spr->base.target == PIPE_TEXTURE_2D_ARRAY ||
spr->base.target == PIPE_TEXTURE_CUBE_ARRAY ||
spr->base.target == PIPE_TEXTURE_CUBE ||
spr->base.target == PIPE_TEXTURE_3D)
base_layer = r_coord + iview->u.tex.first_layer;
return softpipe_get_tex_image_offset(spr, iview->u.tex.level, base_layer);
}
@@ -146,21 +146,21 @@ has_compat_target(unsigned pipe_target, unsigned tgsi_target)
static bool
get_dimensions(const struct pipe_image_view *iview,
const struct softpipe_resource *spr,
unsigned tgsi_tex_instr,
enum pipe_format pformat,
unsigned *width,
unsigned *height,
unsigned *depth)
{
if (tgsi_tex_instr == TGSI_TEXTURE_BUFFER) {
- *width = iview->u.buf.last_element - iview->u.buf.first_element + 1;
+ *width = iview->u.buf.size / util_format_get_blocksize(pformat);
*height = 1;
*depth = 1;
/*
* Bounds check the buffer size from the view
* and the buffer size from the underlying buffer.
*/
if (util_format_get_stride(pformat, *width) >
util_format_get_stride(spr->base.format, spr->base.width0))
return false;
} else {
@@ -745,21 +745,21 @@ sp_tgsi_get_dims(const struct tgsi_image *image,
int level;
if (params->unit >= PIPE_MAX_SHADER_IMAGES)
return;
iview = &sp_img->sp_iview[params->unit];
spr = (struct softpipe_resource *)iview->resource;
if (!spr)
return;
if (params->tgsi_tex_instr == TGSI_TEXTURE_BUFFER) {
- dims[0] = iview->u.buf.last_element - iview->u.buf.first_element + 1;
+ dims[0] = iview->u.buf.size / util_format_get_blocksize(iview->format);
dims[1] = dims[2] = dims[3] = 0;
return;
}
level = iview->u.tex.level;
dims[0] = u_minify(spr->base.width0, level);
switch (params->tgsi_tex_instr) {
case TGSI_TEXTURE_1D_ARRAY:
dims[1] = iview->u.tex.last_layer - iview->u.tex.first_layer + 1;
/* fallthrough */
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index d80037a..c5740d0 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -753,22 +753,22 @@ void trace_dump_image_view(const struct pipe_image_view *state)
trace_dump_struct_begin("pipe_image_view");
trace_dump_member(resource_ptr, state, resource);
trace_dump_member(uint, state, format);
trace_dump_member(uint, state, access);
trace_dump_member_begin("u");
trace_dump_struct_begin(""); /* anonymous */
if (state->resource->target == PIPE_BUFFER) {
trace_dump_member_begin("buf");
trace_dump_struct_begin(""); /* anonymous */
- trace_dump_member(uint, &state->u.buf, first_element);
- trace_dump_member(uint, &state->u.buf, last_element);
+ trace_dump_member(uint, &state->u.buf, offset);
+ trace_dump_member(uint, &state->u.buf, size);
trace_dump_struct_end(); /* anonymous */
trace_dump_member_end(); /* buf */
} else {
trace_dump_member_begin("tex");
trace_dump_struct_begin(""); /* anonymous */
trace_dump_member(uint, &state->u.tex, first_layer);
trace_dump_member(uint, &state->u.tex, last_layer);
trace_dump_member(uint, &state->u.tex, level);
trace_dump_struct_end(); /* anonymous */
trace_dump_member_end(); /* tex */
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 1fd6353..ebd0337 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -449,22 +449,22 @@ struct pipe_image_view
enum pipe_format format; /**< typed PIPE_FORMAT_x */
unsigned access; /**< PIPE_IMAGE_ACCESS_x */
union {
struct {
unsigned first_layer:16; /**< first layer to use for array textures */
unsigned last_layer:16; /**< last layer to use for array textures */
unsigned level:8; /**< mipmap level to use */
} tex;
struct {
- unsigned first_element;
- unsigned last_element;
+ unsigned offset; /**< offset in bytes */
+ unsigned size; /**< size of the accessible sub-range in bytes */
} buf;
} u;
};
/**
* Subregion of 1D/2D/3D image resource.
*/
struct pipe_box
{
diff --git a/src/mesa/state_tracker/st_atom_image.c b/src/mesa/state_tracker/st_atom_image.c
index e80fc14..4d76ac9 100644
--- a/src/mesa/state_tracker/st_atom_image.c
+++ b/src/mesa/state_tracker/st_atom_image.c
@@ -81,33 +81,27 @@ st_bind_images(struct st_context *st, struct gl_linked_shader *shader,
break;
case GL_READ_WRITE:
img->access = PIPE_IMAGE_ACCESS_READ_WRITE;
break;
default:
unreachable("bad gl_image_unit::Access");
}
if (stObj->pt->target == PIPE_BUFFER) {
unsigned base, size;
- unsigned f, n;
- const struct util_format_description *desc
- = util_format_description(img->format);
base = stObj->base.BufferOffset;
assert(base < stObj->pt->width0);
size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize);
- f = (base / (desc->block.bits / 8)) * desc->block.width;
- n = (size / (desc->block.bits / 8)) * desc->block.width;
- assert(n > 0);
- img->u.buf.first_element = f;
- img->u.buf.last_element = f + (n - 1);
+ 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;
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 8eb839d..3cfdf78 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -185,22 +185,23 @@ try_pbo_readpixels(struct st_context *st, struct st_renderbuffer *strb,
}
/* Set up destination image */
{
struct pipe_image_view image;
memset(&image, 0, sizeof(image));
image.resource = addr.buffer;
image.format = dst_format;
image.access = PIPE_IMAGE_ACCESS_WRITE;
- image.u.buf.first_element = addr.first_element;
- image.u.buf.last_element = addr.last_element;
+ image.u.buf.offset = addr.first_element * addr.bytes_per_pixel;
+ image.u.buf.size = (addr.last_element - addr.first_element + 1) *
+ addr.bytes_per_pixel;
cso_set_shader_images(cso, PIPE_SHADER_FRAGMENT, 0, 1, &image);
}
/* Set up no-attachment framebuffer */
memset(&fb, 0, sizeof(fb));
fb.width = surface->width;
fb.height = surface->height;
fb.samples = 1;
fb.layers = 1;
--
2.7.4
More information about the mesa-dev
mailing list