gallium: change pipe_sampler_view::first_element/last_element -> offset/size

This is required by OpenGL. Our hardware supports this.

Example: Bind RGBA32F with offset = 4 bytes.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97305

Acked-by: Ilia Mirkin <imirkin@alum.mit.edu>
Acked-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
Marek Olšák 2016-08-12 02:33:41 +02:00
parent 1ac23a9359
commit 7cd256ce7e
24 changed files with 81 additions and 82 deletions

View file

@ -750,8 +750,8 @@ util_dump_sampler_view(FILE *stream, const struct pipe_sampler_view *state)
util_dump_member(stream, ptr, state, texture); util_dump_member(stream, ptr, state, texture);
if (state->target == PIPE_BUFFER) { if (state->target == PIPE_BUFFER) {
util_dump_member(stream, uint, state, u.buf.first_element); util_dump_member(stream, uint, state, u.buf.offset);
util_dump_member(stream, uint, state, u.buf.last_element); util_dump_member(stream, uint, state, u.buf.size);
} }
else { else {
util_dump_member(stream, uint, state, u.tex.first_layer); util_dump_member(stream, uint, state, u.tex.first_layer);

View file

@ -136,8 +136,8 @@ The integer capabilities:
PIPE_BUFFER. In other words, the pointer returned by transfer_map is PIPE_BUFFER. In other words, the pointer returned by transfer_map is
always aligned to this value. always aligned to this value.
* ``PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT``: Describes the required * ``PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT``: Describes the required
alignment for pipe_sampler_view::u.buf.first_element, in bytes. alignment for pipe_sampler_view::u.buf.offset, in bytes.
If a driver does not support first/last_element, it should return 0. If a driver does not support offset/size, it should return 0.
* ``PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY``: Whether the driver only * ``PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY``: Whether the driver only
supports R, RG, RGB and RGBA formats for PIPE_BUFFER sampler views. supports R, RG, RGB and RGBA formats for PIPE_BUFFER sampler views.
When this is the case it should be assumed that the swizzle parameters When this is the case it should be assumed that the swizzle parameters

View file

@ -206,8 +206,7 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
&dummy_view; &dummy_view;
struct fd_resource *rsc = fd_resource(view->base.texture); struct fd_resource *rsc = fd_resource(view->base.texture);
if (rsc && rsc->base.b.target == PIPE_BUFFER) { if (rsc && rsc->base.b.target == PIPE_BUFFER) {
OUT_RELOC(ring, rsc->bo, view->base.u.buf.first_element * OUT_RELOC(ring, rsc->bo, view->base.u.buf.offset, 0, 0);
util_format_get_blocksize(view->base.format), 0, 0);
j = 1; j = 1;
} else { } else {
unsigned start = fd_sampler_first_level(&view->base); unsigned start = fd_sampler_first_level(&view->base);

View file

@ -241,8 +241,7 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
lvl = 0; lvl = 0;
so->texconst1 = so->texconst1 =
A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) | A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) |
A3XX_TEX_CONST_1_WIDTH(cso->u.buf.last_element - A3XX_TEX_CONST_1_WIDTH(cso->u.buf.size / util_format_get_blocksize(cso->format)) |
cso->u.buf.first_element + 1) |
A3XX_TEX_CONST_1_HEIGHT(1); A3XX_TEX_CONST_1_HEIGHT(1);
} else { } else {
unsigned miplevels; unsigned miplevels;

View file

@ -249,8 +249,8 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
} }
if (cso->target == PIPE_BUFFER) { if (cso->target == PIPE_BUFFER) {
unsigned elements = cso->u.buf.last_element - unsigned elements = cso->u.buf.size / util_format_get_blocksize(cso->format);
cso->u.buf.first_element + 1;
lvl = 0; lvl = 0;
so->texconst1 = so->texconst1 =
A4XX_TEX_CONST_1_WIDTH(elements) | A4XX_TEX_CONST_1_WIDTH(elements) |
@ -258,8 +258,7 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
so->texconst2 = so->texconst2 =
A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) | A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
A4XX_TEX_CONST_2_PITCH(elements * rsc->cpp); A4XX_TEX_CONST_2_PITCH(elements * rsc->cpp);
so->offset = cso->u.buf.first_element * so->offset = cso->u.buf.offset;
util_format_get_blocksize(cso->format);
} else { } else {
unsigned miplevels; unsigned miplevels;

View file

@ -2015,9 +2015,8 @@ ilo_create_sampler_view(struct pipe_context *pipe,
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.vma = ilo_resource_get_vma(res); info.vma = ilo_resource_get_vma(res);
info.offset = templ->u.buf.first_element * info.struct_size; info.offset = templ->u.buf.offset;
info.size = (templ->u.buf.last_element - info.size = templ->u.buf.size;
templ->u.buf.first_element + 1) * info.struct_size;
info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER; info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
info.format = ilo_format_translate_color(dev, templ->format); info.format = ilo_format_translate_color(dev, templ->format);
info.format_size = util_format_get_blocksize(templ->format); info.format_size = util_format_get_blocksize(templ->format);

View file

@ -889,8 +889,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
} }
else { else {
/* /*
* For buffers, we don't have first_element, instead adjust * For buffers, we don't have "offset", instead adjust
* last_element (stored as width) plus the base pointer. * the size (stored as width) plus the base pointer.
*/ */
unsigned view_blocksize = util_format_get_blocksize(view->format); unsigned view_blocksize = util_format_get_blocksize(view->format);
/* probably don't really need to fill that out */ /* probably don't really need to fill that out */
@ -899,12 +899,10 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
jit_tex->img_stride[0] = 0; jit_tex->img_stride[0] = 0;
/* everything specified in number of elements here. */ /* everything specified in number of elements here. */
jit_tex->width = view->u.buf.last_element - view->u.buf.first_element + 1; jit_tex->width = view->u.buf.size / view_blocksize;
jit_tex->base = (uint8_t *)jit_tex->base + view->u.buf.first_element * jit_tex->base = (uint8_t *)jit_tex->base + view->u.buf.offset;
view_blocksize;
/* XXX Unsure if we need to sanitize parameters? */ /* XXX Unsure if we need to sanitize parameters? */
assert(view->u.buf.first_element <= view->u.buf.last_element); assert(view->u.buf.offset + view->u.buf.size <= res->width0);
assert(view->u.buf.last_element * view_blocksize < res->width0);
} }
} }
} }

View file

@ -308,11 +308,9 @@ prepare_shader_sampling(
img_stride[0] = 0; img_stride[0] = 0;
/* everything specified in number of elements here. */ /* everything specified in number of elements here. */
width0 = view->u.buf.last_element - view->u.buf.first_element + 1; width0 = view->u.buf.size / view_blocksize;
addr = (uint8_t *)addr + view->u.buf.first_element * addr = (uint8_t *)addr + view->u.buf.offset;
view_blocksize; assert(view->u.buf.offset + view->u.buf.size <= res->width0);
assert(view->u.buf.first_element <= view->u.buf.last_element);
assert(view->u.buf.last_element * view_blocksize < res->width0);
} }
} }
else { else {

View file

@ -131,11 +131,11 @@ nv50_create_texture_view(struct pipe_context *pipe,
if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) { if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
if (target == PIPE_BUFFER) { if (target == PIPE_BUFFER) {
addr += view->pipe.u.buf.first_element * desc->block.bits / 8; addr += view->pipe.u.buf.offset;
tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_ONE_D_BUFFER; tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_ONE_D_BUFFER;
tic[3] = 0; tic[3] = 0;
tic[4] = /* width */ tic[4] = /* width */
view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1; view->pipe.u.buf.size / (desc->block.bits / 8);
tic[5] = 0; tic[5] = 0;
} else { } else {
tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_TWO_D_NO_MIPMAP; tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_TWO_D_NO_MIPMAP;
@ -224,8 +224,7 @@ nv50_update_tic(struct nv50_context *nv50, struct nv50_tic_entry *tic,
uint64_t address = res->address; uint64_t address = res->address;
if (res->base.target != PIPE_BUFFER) if (res->base.target != PIPE_BUFFER)
return; return;
address += tic->pipe.u.buf.first_element * address += tic->pipe.u.buf.offset;
util_format_get_blocksize(tic->pipe.format);
if (tic->tic[1] == (uint32_t)address && if (tic->tic[1] == (uint32_t)address &&
(tic->tic[2] & 0xff) == address >> 32) (tic->tic[2] & 0xff) == address >> 32)
return; return;

View file

@ -132,9 +132,9 @@ gm107_create_texture_view(struct pipe_context *pipe,
if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) { if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
if (texture->target == PIPE_BUFFER) { if (texture->target == PIPE_BUFFER) {
assert(!(tic[5] & GM107_TIC2_5_NORMALIZED_COORDS)); assert(!(tic[5] & GM107_TIC2_5_NORMALIZED_COORDS));
width = view->pipe.u.buf.last_element - view->pipe.u.buf.first_element; width = view->pipe.u.buf.size / (desc->block.bits / 8) - 1;
address += address +=
view->pipe.u.buf.first_element * desc->block.bits / 8; view->pipe.u.buf.offset;
tic[2] = GM107_TIC2_2_HEADER_VERSION_ONE_D_BUFFER; tic[2] = GM107_TIC2_2_HEADER_VERSION_ONE_D_BUFFER;
tic[3] |= width >> 16; tic[3] |= width >> 16;
tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_BUFFER; tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_BUFFER;
@ -259,8 +259,11 @@ gm107_create_texture_view_from_image(struct pipe_context *pipe,
templ.swizzle_a = PIPE_SWIZZLE_W; templ.swizzle_a = PIPE_SWIZZLE_W;
if (target == PIPE_BUFFER) { if (target == PIPE_BUFFER) {
templ.u.buf.first_element = view->u.buf.first_element; templ.u.buf.offset = view->u.buf.first_element *
templ.u.buf.last_element = view->u.buf.last_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);
} else { } else {
templ.u.tex.first_layer = view->u.tex.first_layer; templ.u.tex.first_layer = view->u.tex.first_layer;
templ.u.tex.last_layer = view->u.tex.last_layer; templ.u.tex.last_layer = view->u.tex.last_layer;
@ -344,11 +347,11 @@ gf100_create_texture_view(struct pipe_context *pipe,
if (texture->target == PIPE_BUFFER) { if (texture->target == PIPE_BUFFER) {
assert(!(tic[2] & G80_TIC_2_NORMALIZED_COORDS)); assert(!(tic[2] & G80_TIC_2_NORMALIZED_COORDS));
address += address +=
view->pipe.u.buf.first_element * desc->block.bits / 8; view->pipe.u.buf.offset;
tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_ONE_D_BUFFER; tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_ONE_D_BUFFER;
tic[3] = 0; tic[3] = 0;
tic[4] = /* width */ tic[4] = /* width */
view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1; view->pipe.u.buf.size / (desc->block.bits / 8);
tic[5] = 0; tic[5] = 0;
} else { } else {
/* must be 2D texture without mip maps */ /* must be 2D texture without mip maps */
@ -456,8 +459,7 @@ nvc0_update_tic(struct nvc0_context *nvc0, struct nv50_tic_entry *tic,
uint64_t address = res->address; uint64_t address = res->address;
if (res->base.target != PIPE_BUFFER) if (res->base.target != PIPE_BUFFER)
return; return;
address += tic->pipe.u.buf.first_element * address += tic->pipe.u.buf.offset;
util_format_get_blocksize(tic->pipe.format);
if (tic->tic[1] == (uint32_t)address && if (tic->tic[1] == (uint32_t)address &&
(tic->tic[2] & 0xff) == address >> 32) (tic->tic[2] & 0xff) == address >> 32)
return; return;

View file

@ -613,8 +613,8 @@ texture_buffer_sampler_view(struct r600_context *rctx,
unsigned swizzle_res; unsigned swizzle_res;
unsigned char swizzle[4]; unsigned char swizzle[4];
const struct util_format_description *desc; const struct util_format_description *desc;
unsigned offset = view->base.u.buf.first_element * stride; unsigned offset = view->base.u.buf.offset;
unsigned size = (view->base.u.buf.last_element - view->base.u.buf.first_element + 1) * stride; unsigned size = view->base.u.buf.size;
swizzle[0] = view->base.swizzle_r; swizzle[0] = view->base.swizzle_r;
swizzle[1] = view->base.swizzle_g; swizzle[1] = view->base.swizzle_g;

View file

@ -631,8 +631,8 @@ texture_buffer_sampler_view(struct r600_pipe_sampler_view *view,
struct r600_texture *tmp = (struct r600_texture*)view->base.texture; struct r600_texture *tmp = (struct r600_texture*)view->base.texture;
int stride = util_format_get_blocksize(view->base.format); int stride = util_format_get_blocksize(view->base.format);
unsigned format, num_format, format_comp, endian; unsigned format, num_format, format_comp, endian;
uint64_t offset = view->base.u.buf.first_element * stride; uint64_t offset = view->base.u.buf.offset;
unsigned size = (view->base.u.buf.last_element - view->base.u.buf.first_element + 1) * stride; unsigned size = view->base.u.buf.size;
r600_vertex_data_type(view->base.format, r600_vertex_data_type(view->base.format,
&format, &num_format, &format_comp, &format, &num_format, &format_comp,

View file

@ -2831,8 +2831,7 @@ static void r600_invalidate_buffer(struct pipe_context *ctx, struct pipe_resourc
/* Texture buffer objects - update the virtual addresses in descriptors. */ /* Texture buffer objects - update the virtual addresses in descriptors. */
LIST_FOR_EACH_ENTRY(view, &rctx->b.texture_buffers, list) { LIST_FOR_EACH_ENTRY(view, &rctx->b.texture_buffers, list) {
if (view->base.texture == &rbuffer->b.b) { if (view->base.texture == &rbuffer->b.b) {
unsigned stride = util_format_get_blocksize(view->base.format); uint64_t offset = view->base.u.buf.offset;
uint64_t offset = (uint64_t)view->base.u.buf.first_element * stride;
uint64_t va = rbuffer->gpu_address + offset; uint64_t va = rbuffer->gpu_address + offset;
view->tex_resource_words[0] = va; view->tex_resource_words[0] = va;

View file

@ -641,8 +641,11 @@ static void si_set_shader_image(struct si_context *ctx,
si_make_buffer_descriptor(screen, res, si_make_buffer_descriptor(screen, res,
view->format, view->format,
view->u.buf.first_element, view->u.buf.first_element *
view->u.buf.last_element, util_format_get_blocksize(view->format),
(view->u.buf.last_element -
view->u.buf.first_element + 1) *
util_format_get_blocksize(view->format),
descs->list + slot * 8); descs->list + slot * 8);
images->compressed_colortex_mask &= ~(1 << slot); images->compressed_colortex_mask &= ~(1 << slot);
} else { } else {

View file

@ -2644,7 +2644,7 @@ static void si_set_min_samples(struct pipe_context *ctx, unsigned min_samples)
void void
si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf, si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf,
enum pipe_format format, enum pipe_format format,
unsigned first_element, unsigned last_element, unsigned offset, unsigned size,
uint32_t *state) uint32_t *state)
{ {
const struct util_format_description *desc; const struct util_format_description *desc;
@ -2657,11 +2657,11 @@ si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf,
desc = util_format_description(format); desc = util_format_description(format);
first_non_void = util_format_get_first_non_void_channel(format); first_non_void = util_format_get_first_non_void_channel(format);
stride = desc->block.bits / 8; stride = desc->block.bits / 8;
va = buf->gpu_address + first_element * stride; va = buf->gpu_address + offset;
num_format = si_translate_buffer_numformat(&screen->b.b, desc, first_non_void); num_format = si_translate_buffer_numformat(&screen->b.b, desc, first_non_void);
data_format = si_translate_buffer_dataformat(&screen->b.b, desc, first_non_void); data_format = si_translate_buffer_dataformat(&screen->b.b, desc, first_non_void);
num_records = last_element + 1 - first_element; num_records = size / stride;
num_records = MIN2(num_records, buf->b.b.width0 / stride); num_records = MIN2(num_records, buf->b.b.width0 / stride);
if (screen->b.chip_class >= VI) if (screen->b.chip_class >= VI)
@ -2960,8 +2960,8 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
si_make_buffer_descriptor(sctx->screen, si_make_buffer_descriptor(sctx->screen,
(struct r600_resource *)texture, (struct r600_resource *)texture,
state->format, state->format,
state->u.buf.first_element, state->u.buf.offset,
state->u.buf.last_element, state->u.buf.size,
view->state); view->state);
LIST_ADDTAIL(&view->list, &sctx->b.texture_buffers); LIST_ADDTAIL(&view->list, &sctx->b.texture_buffers);

View file

@ -313,7 +313,7 @@ void si_init_screen_state_functions(struct si_screen *sscreen);
void void
si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf, si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf,
enum pipe_format format, enum pipe_format format,
unsigned first_element, unsigned last_element, unsigned offset, unsigned size,
uint32_t *state); uint32_t *state);
void void
si_make_texture_descriptor(struct si_screen *screen, si_make_texture_descriptor(struct si_screen *screen,

View file

@ -240,11 +240,9 @@ prepare_shader_sampling(
img_stride[0] = 0; img_stride[0] = 0;
/* everything specified in number of elements here. */ /* everything specified in number of elements here. */
width0 = view->u.buf.last_element - view->u.buf.first_element + 1; width0 = view->u.buf.size / view_blocksize;
addr = (uint8_t *)addr + view->u.buf.first_element * addr = (uint8_t *)addr + view->u.buf.offset;
view_blocksize; assert(view->u.buf.offset + view->u.buf.size <= res->width0);
assert(view->u.buf.first_element <= view->u.buf.last_element);
assert(view->u.buf.last_element * view_blocksize < res->width0);
} }
} }
else { else {

View file

@ -3192,7 +3192,7 @@ sp_get_dims(const struct sp_sampler_view *sp_sview,
const struct pipe_resource *texture = view->texture; const struct pipe_resource *texture = view->texture;
if (view->target == PIPE_BUFFER) { if (view->target == PIPE_BUFFER) {
dims[0] = (view->u.buf.last_element - view->u.buf.first_element) + 1; dims[0] = view->u.buf.size / util_format_get_blocksize(view->format);
/* the other values are undefined, but let's avoid potential valgrind /* the other values are undefined, but let's avoid potential valgrind
* warnings. * warnings.
*/ */
@ -3264,17 +3264,22 @@ sp_get_texels(const struct sp_sampler_view *sp_sview,
const int width = u_minify(texture->width0, level); const int width = u_minify(texture->width0, level);
const int height = u_minify(texture->height0, level); const int height = u_minify(texture->height0, level);
const int depth = u_minify(texture->depth0, level); const int depth = u_minify(texture->depth0, level);
unsigned elem_size, first_element, last_element;
addr.value = 0; addr.value = 0;
addr.bits.level = level; addr.bits.level = level;
switch (sp_sview->base.target) { switch (sp_sview->base.target) {
case PIPE_BUFFER: case PIPE_BUFFER:
elem_size = util_format_get_blocksize(sp_sview->base.format);
first_element = sp_sview->base.u.buf.offset / elem_size;
last_element = (sp_sview->base.u.buf.offset +
sp_sview->base.u.buf.size) / elem_size - 1;
for (j = 0; j < TGSI_QUAD_SIZE; j++) { for (j = 0; j < TGSI_QUAD_SIZE; j++) {
const int x = CLAMP(v_i[j] + offset[0] + const int x = CLAMP(v_i[j] + offset[0] +
sp_sview->base.u.buf.first_element, first_element,
sp_sview->base.u.buf.first_element, first_element,
sp_sview->base.u.buf.last_element); last_element);
tx = get_texel_2d_no_border(sp_sview, addr, x, 0); tx = get_texel_2d_no_border(sp_sview, addr, x, 0);
for (c = 0; c < 4; c++) { for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c]; rgba[c][j] = tx[c];

View file

@ -30,6 +30,7 @@
#include "pipe/p_defines.h" #include "pipe/p_defines.h"
#include "util/u_bitmask.h" #include "util/u_bitmask.h"
#include "util/u_format.h"
#include "util/u_inlines.h" #include "util/u_inlines.h"
#include "util/u_math.h" #include "util/u_math.h"
#include "util/u_memory.h" #include "util/u_memory.h"
@ -125,9 +126,10 @@ svga_validate_pipe_sampler_view(struct svga_context *svga,
format = svga_sampler_format(format); format = svga_sampler_format(format);
if (texture->target == PIPE_BUFFER) { if (texture->target == PIPE_BUFFER) {
viewDesc.buffer.firstElement = sv->base.u.buf.first_element; unsigned elem_size = util_format_get_blocksize(sv->base.format);
viewDesc.buffer.numElements = (sv->base.u.buf.last_element -
sv->base.u.buf.first_element + 1); viewDesc.buffer.firstElement = sv->base.u.buf.offset / elem_size;
viewDesc.buffer.numElements = sv->base.u.buf.size / elem_size;
} }
else { else {
viewDesc.tex.mostDetailedMip = sv->base.u.tex.first_level; viewDesc.tex.mostDetailedMip = sv->base.u.tex.first_level;

View file

@ -543,8 +543,8 @@ void trace_dump_sampler_view_template(const struct pipe_sampler_view *state,
if (target == PIPE_BUFFER) { if (target == PIPE_BUFFER) {
trace_dump_member_begin("buf"); trace_dump_member_begin("buf");
trace_dump_struct_begin(""); /* anonymous */ trace_dump_struct_begin(""); /* anonymous */
trace_dump_member(uint, &state->u.buf, first_element); trace_dump_member(uint, &state->u.buf, offset);
trace_dump_member(uint, &state->u.buf, last_element); trace_dump_member(uint, &state->u.buf, size);
trace_dump_struct_end(); /* anonymous */ trace_dump_struct_end(); /* anonymous */
trace_dump_member_end(); /* buf */ trace_dump_member_end(); /* buf */
} else { } else {

View file

@ -22,6 +22,7 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include "util/u_format.h"
#include "util/u_memory.h" #include "util/u_memory.h"
#include "util/u_math.h" #include "util/u_math.h"
#include "pipe/p_state.h" #include "pipe/p_state.h"
@ -562,14 +563,16 @@ int virgl_encode_sampler_view(struct virgl_context *ctx,
struct virgl_resource *res, struct virgl_resource *res,
const struct pipe_sampler_view *state) const struct pipe_sampler_view *state)
{ {
unsigned elem_size = util_format_get_blocksize(state->format);
uint32_t tmp; uint32_t tmp;
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_SAMPLER_VIEW, VIRGL_OBJ_SAMPLER_VIEW_SIZE)); virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_SAMPLER_VIEW, VIRGL_OBJ_SAMPLER_VIEW_SIZE));
virgl_encoder_write_dword(ctx->cbuf, handle); virgl_encoder_write_dword(ctx->cbuf, handle);
virgl_encoder_write_res(ctx, res); virgl_encoder_write_res(ctx, res);
virgl_encoder_write_dword(ctx->cbuf, state->format); virgl_encoder_write_dword(ctx->cbuf, state->format);
if (res->u.b.target == PIPE_BUFFER) { if (res->u.b.target == PIPE_BUFFER) {
virgl_encoder_write_dword(ctx->cbuf, state->u.buf.first_element); virgl_encoder_write_dword(ctx->cbuf, state->u.buf.offset / elem_size);
virgl_encoder_write_dword(ctx->cbuf, state->u.buf.last_element); virgl_encoder_write_dword(ctx->cbuf, (state->u.buf.offset + state->u.buf.size) / elem_size - 1);
} else { } else {
virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_layer | state->u.tex.last_layer << 16); virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_layer | state->u.tex.last_layer << 16);
virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_level | state->u.tex.last_level << 8); virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_level | state->u.tex.last_level << 8);

View file

@ -428,8 +428,8 @@ struct pipe_sampler_view
unsigned last_level:8; /**< last mipmap level to use */ unsigned last_level:8; /**< last mipmap level to use */
} tex; } tex;
struct { struct {
unsigned first_element; unsigned offset; /**< offset in bytes */
unsigned last_element; unsigned size; /**< size of the readable sub-range in bytes */
} buf; } buf;
} u; } u;
unsigned swizzle_r:3; /**< PIPE_SWIZZLE_x for red component */ unsigned swizzle_r:3; /**< PIPE_SWIZZLE_x for red component */

View file

@ -279,21 +279,16 @@ st_create_texture_sampler_view_from_stobj(struct st_context *st,
if (stObj->pt->target == PIPE_BUFFER) { if (stObj->pt->target == PIPE_BUFFER) {
unsigned base, size; unsigned base, size;
unsigned f, n;
const struct util_format_description *desc
= util_format_description(templ.format);
base = stObj->base.BufferOffset; base = stObj->base.BufferOffset;
if (base >= stObj->pt->width0) if (base >= stObj->pt->width0)
return NULL; return NULL;
size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize); size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize);
if (!size)
f = (base / (desc->block.bits / 8)) * desc->block.width;
n = (size / (desc->block.bits / 8)) * desc->block.width;
if (!n)
return NULL; return NULL;
templ.u.buf.first_element = f;
templ.u.buf.last_element = f + (n - 1); templ.u.buf.offset = base;
templ.u.buf.size = size;
} else { } else {
templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel; templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
templ.u.tex.last_level = last_level(stObj); templ.u.tex.last_level = last_level(stObj);

View file

@ -1163,8 +1163,9 @@ try_pbo_upload_common(struct gl_context *ctx,
memset(&templ, 0, sizeof(templ)); memset(&templ, 0, sizeof(templ));
templ.target = PIPE_BUFFER; templ.target = PIPE_BUFFER;
templ.format = src_format; templ.format = src_format;
templ.u.buf.first_element = addr->first_element; templ.u.buf.offset = addr->first_element * addr->bytes_per_pixel;
templ.u.buf.last_element = addr->last_element; templ.u.buf.size = (addr->last_element - addr->first_element + 1) *
addr->bytes_per_pixel;
templ.swizzle_r = PIPE_SWIZZLE_X; templ.swizzle_r = PIPE_SWIZZLE_X;
templ.swizzle_g = PIPE_SWIZZLE_Y; templ.swizzle_g = PIPE_SWIZZLE_Y;
templ.swizzle_b = PIPE_SWIZZLE_Z; templ.swizzle_b = PIPE_SWIZZLE_Z;