aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/state_tracker
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c35
-rw-r--r--mesalib/src/mesa/state_tracker/st_format.c10
-rw-r--r--mesalib/src/mesa/state_tracker/st_gen_mipmap.c95
3 files changed, 94 insertions, 46 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c
index c99eafbad..d6e67b7fb 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.c
+++ b/mesalib/src/mesa/state_tracker/st_draw.c
@@ -307,7 +307,8 @@ setup_interleaved_attribs(struct gl_context *ctx,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer *vbuffer,
struct pipe_vertex_element velements[],
- unsigned max_index)
+ unsigned max_index,
+ unsigned num_instances)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
@@ -336,9 +337,11 @@ setup_interleaved_attribs(struct gl_context *ctx,
pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
vbuffer->buffer_offset = pointer_to_offset(low_addr);
} else {
+ uint divisor = arrays[mesaAttr]->InstanceDivisor;
+ uint length = (divisor ? num_instances / divisor : max_index) + 1;
vbuffer->buffer =
pipe_user_buffer_create(pipe->screen, (void*)low_addr,
- stride * (max_index + 1),
+ stride * length,
PIPE_BIND_VERTEX_BUFFER);
vbuffer->buffer_offset = 0;
@@ -377,7 +380,8 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer vbuffer[],
struct pipe_vertex_element velements[],
- unsigned max_index)
+ unsigned max_index,
+ unsigned num_instances)
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
@@ -403,16 +407,18 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
else {
/* wrap user data */
if (arrays[mesaAttr]->Ptr) {
- vbuffer[attr].buffer =
+ uint divisor = arrays[mesaAttr]->InstanceDivisor;
+ uint length = (divisor ? num_instances / divisor : max_index) + 1;
+ vbuffer[attr].buffer =
pipe_user_buffer_create(pipe->screen,
(void *) arrays[mesaAttr]->Ptr,
- stride * (max_index + 1),
+ stride * length,
PIPE_BIND_VERTEX_BUFFER);
}
else {
/* no array, use ctx->Current.Attrib[] value */
uint bytes = sizeof(ctx->Current.Attrib[0]);
- vbuffer[attr].buffer =
+ vbuffer[attr].buffer =
pipe_user_buffer_create(pipe->screen,
(void *) ctx->Current.Attrib[mesaAttr],
bytes,
@@ -550,7 +556,8 @@ translate_prim(const struct gl_context *ctx, unsigned prim)
static void
st_validate_varrays(struct gl_context *ctx,
const struct gl_client_array **arrays,
- unsigned max_index)
+ unsigned max_index,
+ unsigned num_instances)
{
struct st_context *st = st_context(ctx);
const struct st_vertex_program *vp;
@@ -578,7 +585,7 @@ st_validate_varrays(struct gl_context *ctx,
*/
if (is_interleaved_arrays(vp, vpv, arrays)) {
setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, velements,
- max_index);
+ max_index, num_instances);
num_vbuffers = 1;
num_velements = vpv->num_inputs;
@@ -587,7 +594,7 @@ st_validate_varrays(struct gl_context *ctx,
}
else {
setup_non_interleaved_attribs(ctx, vp, vpv, arrays,
- vbuffer, velements, max_index);
+ vbuffer, velements, max_index, num_instances);
num_vbuffers = vpv->num_inputs;
num_velements = vpv->num_inputs;
}
@@ -624,7 +631,7 @@ st_draw_vbo(struct gl_context *ctx,
struct pipe_context *pipe = st->pipe;
struct pipe_index_buffer ibuffer;
struct pipe_draw_info info;
- unsigned i;
+ unsigned i, num_instances = 1;
GLboolean new_array = GL_TRUE;
/* Fix this (Bug 34378):
GLboolean new_array =
@@ -638,6 +645,10 @@ st_draw_vbo(struct gl_context *ctx,
if (!index_bounds_valid)
if (!vbo_all_varyings_in_vbos(arrays))
vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+
+ for (i = 0; i < nr_prims; i++) {
+ num_instances = MAX2(num_instances, prims[i].num_instances);
+ }
} else {
/* Get min/max index for non-indexed drawing. */
min_index = ~0;
@@ -646,7 +657,7 @@ st_draw_vbo(struct gl_context *ctx,
for (i = 0; i < nr_prims; i++) {
min_index = MIN2(min_index, prims[i].start);
max_index = MAX2(max_index, prims[i].start + prims[i].count - 1);
- max_index = MAX2(max_index, prims[i].num_instances);
+ num_instances = MAX2(num_instances, prims[i].num_instances);
}
}
@@ -667,7 +678,7 @@ st_draw_vbo(struct gl_context *ctx,
st_validate_state(st);
if (new_array) {
- st_validate_varrays(ctx, arrays, max_index);
+ st_validate_varrays(ctx, arrays, max_index, num_instances);
}
#if 0
diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c
index c58ec9267..22a1450cf 100644
--- a/mesalib/src/mesa/state_tracker/st_format.c
+++ b/mesalib/src/mesa/state_tracker/st_format.c
@@ -674,8 +674,6 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
}
return PIPE_FORMAT_NONE;
- case GL_COMPRESSED_RED:
- case GL_COMPRESSED_RG:
case GL_COMPRESSED_RGB:
/* can only sample from compressed formats */
if (bindings & ~PIPE_BIND_SAMPLER_VIEW)
@@ -871,10 +869,14 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
return PIPE_FORMAT_R16G16_UNORM;
return PIPE_FORMAT_NONE;
+ case GL_COMPRESSED_RED:
case GL_COMPRESSED_RED_RGTC1:
if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC1_UNORM, target,
sample_count, bindings, geom_flags))
return PIPE_FORMAT_RGTC1_UNORM;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R8_UNORM;
return PIPE_FORMAT_NONE;
case GL_COMPRESSED_SIGNED_RED_RGTC1:
@@ -883,10 +885,14 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
return PIPE_FORMAT_RGTC1_SNORM;
return PIPE_FORMAT_NONE;
+ case GL_COMPRESSED_RG:
case GL_COMPRESSED_RG_RGTC2:
if (screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM, target,
sample_count, bindings, geom_flags))
return PIPE_FORMAT_RGTC2_UNORM;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_R8G8_UNORM;
return PIPE_FORMAT_NONE;
case GL_COMPRESSED_SIGNED_RG_RGTC2:
diff --git a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c
index 4bf682808..a12a32e11 100644
--- a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c
@@ -103,52 +103,78 @@ st_render_mipmap(struct st_context *st,
* image with stride==width.
*/
static void
-decompress_image(enum pipe_format format,
- const uint8_t *src, uint8_t *dst,
+decompress_image(enum pipe_format format, int datatype,
+ const uint8_t *src, void *dst,
unsigned width, unsigned height, unsigned src_stride)
{
const struct util_format_description *desc = util_format_description(format);
const uint bw = util_format_get_blockwidth(format);
const uint bh = util_format_get_blockheight(format);
- const uint dst_stride = 4 * MAX2(width, bw);
-
- desc->unpack_rgba_8unorm(dst, dst_stride, src, src_stride, width, height);
-
- if (width < bw || height < bh) {
- /* We're decompressing an image smaller than the compression
- * block size. We don't want garbage pixel values in the region
- * outside (width x height) so replicate pixels from the (width
- * x height) region to fill out the (bw x bh) block size.
- */
- uint x, y;
- for (y = 0; y < bh; y++) {
- for (x = 0; x < bw; x++) {
- if (x >= width || y >= height) {
- uint p = (y * bw + x) * 4;
- dst[p + 0] = dst[0];
- dst[p + 1] = dst[1];
- dst[p + 2] = dst[2];
- dst[p + 3] = dst[3];
- }
- }
+ uint dst_stride = 4 * MAX2(width, bw);
+
+ if (datatype == GL_FLOAT) {
+ desc->unpack_rgba_float((float *)dst, dst_stride * sizeof(GLfloat), src, src_stride, width, height);
+ if (width < bw || height < bh) {
+ float *dst_p = (float *)dst;
+ /* We're decompressing an image smaller than the compression
+ * block size. We don't want garbage pixel values in the region
+ * outside (width x height) so replicate pixels from the (width
+ * x height) region to fill out the (bw x bh) block size.
+ */
+ uint x, y;
+ for (y = 0; y < bh; y++) {
+ for (x = 0; x < bw; x++) {
+ if (x >= width || y >= height) {
+ uint p = (y * bw + x) * 4;
+ dst_p[p + 0] = dst_p[0];
+ dst_p[p + 1] = dst_p[1];
+ dst_p[p + 2] = dst_p[2];
+ dst_p[p + 3] = dst_p[3];
+ }
+ }
+ }
+ }
+ } else {
+ desc->unpack_rgba_8unorm((uint8_t *)dst, dst_stride, src, src_stride, width, height);
+ if (width < bw || height < bh) {
+ uint8_t *dst_p = (uint8_t *)dst;
+ /* We're decompressing an image smaller than the compression
+ * block size. We don't want garbage pixel values in the region
+ * outside (width x height) so replicate pixels from the (width
+ * x height) region to fill out the (bw x bh) block size.
+ */
+ uint x, y;
+ for (y = 0; y < bh; y++) {
+ for (x = 0; x < bw; x++) {
+ if (x >= width || y >= height) {
+ uint p = (y * bw + x) * 4;
+ dst_p[p + 0] = dst_p[0];
+ dst_p[p + 1] = dst_p[1];
+ dst_p[p + 2] = dst_p[2];
+ dst_p[p + 3] = dst_p[3];
+ }
+ }
+ }
}
}
}
-
/**
* Helper function to compress an image. The source is a 32-bpp RGBA image
* with stride==width.
*/
static void
-compress_image(enum pipe_format format,
- const uint8_t *src, uint8_t *dst,
+compress_image(enum pipe_format format, int datatype,
+ const void *src, uint8_t *dst,
unsigned width, unsigned height, unsigned dst_stride)
{
const struct util_format_description *desc = util_format_description(format);
const uint src_stride = 4 * width;
- desc->pack_rgba_8unorm(dst, dst_stride, src, src_stride, width, height);
+ if (datatype == GL_FLOAT)
+ desc->pack_rgba_float(dst, dst_stride, (GLfloat *)src, src_stride * sizeof(GLfloat), width, height);
+ else
+ desc->pack_rgba_8unorm(dst, dst_stride, (uint8_t *)src, src_stride, width, height);
}
@@ -178,7 +204,12 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
_mesa_is_format_compressed(texObj->Image[face][baseLevel]->TexFormat);
if (compressed) {
- datatype = GL_UNSIGNED_BYTE;
+ if (texObj->Image[face][baseLevel]->TexFormat == MESA_FORMAT_SIGNED_RED_RGTC1 ||
+ texObj->Image[face][baseLevel]->TexFormat == MESA_FORMAT_SIGNED_RG_RGTC2)
+ datatype = GL_FLOAT;
+ else
+ datatype = GL_UNSIGNED_BYTE;
+
comps = 4;
}
else {
@@ -230,11 +261,11 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
assert(comps == 4);
- srcTemp = malloc(srcWidth2 * srcHeight2 * comps + 000);
- dstTemp = malloc(dstWidth2 * dstHeight2 * comps + 000);
+ srcTemp = malloc(srcWidth2 * srcHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1));
+ dstTemp = malloc(dstWidth2 * dstHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1));
/* decompress the src image: srcData -> srcTemp */
- decompress_image(format, srcData, srcTemp, srcWidth, srcHeight, srcTrans->stride);
+ decompress_image(format, datatype, srcData, srcTemp, srcWidth2, srcHeight2, srcTrans->stride);
_mesa_generate_mipmap_level(target, datatype, comps,
0 /*border*/,
@@ -246,7 +277,7 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
dstWidth2); /* stride in texels */
/* compress the new image: dstTemp -> dstData */
- compress_image(format, dstTemp, dstData, dstWidth, dstHeight, dstTrans->stride);
+ compress_image(format, datatype, dstTemp, dstData, dstWidth2, dstHeight2, dstTrans->stride);
free(srcTemp);
free(dstTemp);