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_atom_sampler.c22
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_texture.c55
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c28
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_eglimage.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c48
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.h1
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c13
-rw-r--r--mesalib/src/mesa/state_tracker/st_format.c6
-rw-r--r--mesalib/src/mesa/state_tracker/st_gen_mipmap.c75
-rw-r--r--mesalib/src/mesa/state_tracker/st_gen_mipmap.h8
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp7
-rw-r--r--mesalib/src/mesa/state_tracker/st_texture.c115
-rw-r--r--mesalib/src/mesa/state_tracker/st_texture.h30
-rw-r--r--mesalib/src/mesa/state_tracker/st_vdpau.c11
15 files changed, 269 insertions, 154 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_atom_sampler.c b/mesalib/src/mesa/state_tracker/st_atom_sampler.c
index ec2bab20b..3929251f8 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_sampler.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_sampler.c
@@ -182,15 +182,27 @@ convert_sampler(struct st_context *st,
msamp->BorderColor.ui[3]) {
const struct st_texture_object *stobj = st_texture_object_const(texobj);
const GLboolean is_integer = texobj->_IsIntegerFormat;
+ const struct pipe_sampler_view *sv = NULL;
union pipe_color_union border_color;
+ GLuint i;
+
+ /* Just search for the first used view. We can do this because the
+ swizzle is per-texture, not per context. */
+ /* XXX: clean that up to not use the sampler view at all */
+ for (i = 0; i < stobj->num_sampler_views; ++i) {
+ if (stobj->sampler_views[i]) {
+ sv = stobj->sampler_views[i];
+ break;
+ }
+ }
- if (st->apply_texture_swizzle_to_border_color && stobj->sampler_view) {
+ if (st->apply_texture_swizzle_to_border_color && sv) {
const unsigned char swz[4] =
{
- stobj->sampler_view->swizzle_r,
- stobj->sampler_view->swizzle_g,
- stobj->sampler_view->swizzle_b,
- stobj->sampler_view->swizzle_a,
+ sv->swizzle_r,
+ sv->swizzle_g,
+ sv->swizzle_b,
+ sv->swizzle_a,
};
st_translate_color(&msamp->BorderColor,
diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c
index c9bffce4f..afc6d9dab 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c
@@ -200,9 +200,9 @@ get_texture_format_swizzle(const struct st_texture_object *stObj)
* \param stObj the st texture object,
*/
static boolean
-check_sampler_swizzle(const struct st_texture_object *stObj)
+check_sampler_swizzle(const struct st_texture_object *stObj,
+ struct pipe_sampler_view *sv)
{
- const struct pipe_sampler_view *sv = stObj->sampler_view;
unsigned swizzle = get_texture_format_swizzle(stObj);
return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
@@ -258,40 +258,47 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
static struct pipe_sampler_view *
-st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj,
- struct pipe_context *pipe,
+st_get_texture_sampler_view_from_stobj(struct st_context *st,
+ struct st_texture_object *stObj,
const struct gl_sampler_object *samp,
enum pipe_format format)
{
+ struct pipe_sampler_view **sv;
+
if (!stObj || !stObj->pt) {
return NULL;
}
- if (!stObj->sampler_view) {
- stObj->sampler_view =
- st_create_texture_sampler_view_from_stobj(pipe, stObj, samp, format);
+ sv = st_texture_get_sampler_view(st, stObj);
+
+ /* if sampler view has changed dereference it */
+ if (*sv) {
+ if (check_sampler_swizzle(stObj, *sv) ||
+ (format != (*sv)->format) ||
+ stObj->base.BaseLevel != (*sv)->u.tex.first_level) {
+ pipe_sampler_view_reference(sv, NULL);
+ }
+ }
+
+ if (!*sv) {
+ *sv = st_create_texture_sampler_view_from_stobj(st->pipe, stObj, samp, format);
- } else if (stObj->sampler_view->context != pipe) {
+ } else if ((*sv)->context != st->pipe) {
/* Recreate view in correct context, use existing view as template */
- /* XXX: This isn't optimal, we should try to use more than one view.
- Otherwise we create/destroy the view all the time
- */
- struct pipe_sampler_view *sv =
- pipe->create_sampler_view(pipe, stObj->pt, stObj->sampler_view);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
- stObj->sampler_view = sv;
+ struct pipe_sampler_view *new_sv =
+ st->pipe->create_sampler_view(st->pipe, stObj->pt, *sv);
+ pipe_sampler_view_reference(sv, NULL);
+ *sv = new_sv;
}
- return stObj->sampler_view;
+ return *sv;
}
-
static GLboolean
update_single_texture(struct st_context *st,
struct pipe_sampler_view **sampler_view,
GLuint texUnit)
{
- struct pipe_context *pipe = st->pipe;
struct gl_context *ctx = st->ctx;
const struct gl_sampler_object *samp;
struct gl_texture_object *texObj;
@@ -330,17 +337,7 @@ update_single_texture(struct st_context *st,
}
}
- /* if sampler view has changed dereference it */
- if (stObj->sampler_view) {
- if (check_sampler_swizzle(stObj) ||
- (view_format != stObj->sampler_view->format) ||
- stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) {
- pipe_sampler_view_release(pipe, &stObj->sampler_view);
- }
- }
-
- *sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe,
- samp,
+ *sampler_view = st_get_texture_sampler_view_from_stobj(st, stObj, samp,
view_format);
return GL_TRUE;
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
index 49c4b903e..02624617b 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -447,6 +447,33 @@ st_copy_buffer_subdata(struct gl_context *ctx,
srcObj->buffer, 0, &box);
}
+/**
+ * Called via glClearBufferSubData().
+ */
+static void
+st_clear_buffer_subdata(struct gl_context *ctx,
+ GLintptr offset, GLsizeiptr size,
+ const GLvoid *clearValue,
+ GLsizeiptr clearValueSize,
+ struct gl_buffer_object *bufObj)
+{
+ struct pipe_context *pipe = st_context(ctx)->pipe;
+ struct st_buffer_object *buf = st_buffer_object(bufObj);
+ static const char zeros[16] = {0};
+
+ if (!pipe->clear_buffer) {
+ _mesa_buffer_clear_subdata(ctx, offset, size,
+ clearValue, clearValueSize, bufObj);
+ return;
+ }
+
+ if (!clearValue)
+ clearValue = zeros;
+
+ pipe->clear_buffer(pipe, buf->buffer, offset, size,
+ clearValue, clearValueSize);
+}
+
/* TODO: if buffer wasn't created with appropriate usage flags, need
* to recreate it now and copy contents -- or possibly create a
@@ -476,6 +503,7 @@ st_init_bufferobject_functions(struct dd_function_table *functions)
functions->FlushMappedBufferRange = st_bufferobj_flush_mapped_range;
functions->UnmapBuffer = st_bufferobj_unmap;
functions->CopyBufferSubData = st_copy_buffer_subdata;
+ functions->ClearBufferSubData = st_clear_buffer_subdata;
/* For GL_APPLE_vertex_array_object */
functions->NewArrayObject = _mesa_new_vao;
diff --git a/mesalib/src/mesa/state_tracker/st_cb_eglimage.c b/mesalib/src/mesa/state_tracker/st_cb_eglimage.c
index 561967d6c..34eb80959 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_eglimage.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_eglimage.c
@@ -124,7 +124,7 @@ st_bind_surface(struct gl_context *ctx, GLenum target,
/* FIXME create a non-default sampler view from the pipe_surface? */
pipe_resource_reference(&stObj->pt, ps->texture);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ st_texture_release_all_sampler_views(stObj);
pipe_resource_reference(&stImage->pt, stObj->pt);
stObj->width0 = ps->width;
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index f0bf3745b..97bba8b7d 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -151,13 +151,11 @@ static void
st_DeleteTextureObject(struct gl_context *ctx,
struct gl_texture_object *texObj)
{
- struct st_context *st = st_context(ctx);
struct st_texture_object *stObj = st_texture_object(texObj);
- if (stObj->pt)
- pipe_resource_reference(&stObj->pt, NULL);
- if (stObj->sampler_view) {
- pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
- }
+
+ pipe_resource_reference(&stObj->pt, NULL);
+ st_texture_release_all_sampler_views(stObj);
+ st_texture_free_sampler_views(stObj);
_mesa_delete_texture_object(ctx, texObj);
}
@@ -177,6 +175,10 @@ st_FreeTextureImageBuffer(struct gl_context *ctx,
_mesa_align_free(stImage->TexData);
stImage->TexData = NULL;
+
+ free(stImage->transfer);
+ stImage->transfer = NULL;
+ stImage->num_transfers = 0;
}
@@ -192,6 +194,7 @@ st_MapTextureImage(struct gl_context *ctx,
struct st_texture_image *stImage = st_texture_image(texImage);
unsigned pipeMode;
GLubyte *map;
+ struct pipe_transfer *transfer;
pipeMode = 0x0;
if (mode & GL_MAP_READ_BIT)
@@ -201,10 +204,11 @@ st_MapTextureImage(struct gl_context *ctx,
if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
pipeMode |= PIPE_TRANSFER_DISCARD_RANGE;
- map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1);
+ map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1,
+ &transfer);
if (map) {
*mapOut = map;
- *rowStrideOut = stImage->transfer->stride;
+ *rowStrideOut = transfer->stride;
}
else {
*mapOut = NULL;
@@ -221,7 +225,7 @@ st_UnmapTextureImage(struct gl_context *ctx,
{
struct st_context *st = st_context(ctx);
struct st_texture_image *stImage = st_texture_image(texImage);
- st_texture_image_unmap(st, stImage);
+ st_texture_image_unmap(st, stImage, slice);
}
@@ -454,7 +458,7 @@ st_AllocTextureImageBuffer(struct gl_context *ctx,
/* The parent texture object does not have space for this image */
pipe_resource_reference(&stObj->pt, NULL);
- pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
+ st_texture_release_all_sampler_views(stObj);
if (!guess_and_alloc_texture(st, stObj, stImage)) {
/* Probably out of memory.
@@ -1146,6 +1150,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,
unsigned dst_width = width;
unsigned dst_height = height;
unsigned dst_depth = 1;
+ struct pipe_transfer *transfer;
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
@@ -1171,7 +1176,8 @@ fallback_copy_texsubimage(struct gl_context *ctx,
texDest = st_texture_image_map(st, stImage, transfer_usage,
destX, destY, slice,
- dst_width, dst_height, dst_depth);
+ dst_width, dst_height, dst_depth,
+ &transfer);
if (baseFormat == GL_DEPTH_COMPONENT ||
baseFormat == GL_DEPTH_STENCIL) {
@@ -1201,13 +1207,11 @@ fallback_copy_texsubimage(struct gl_context *ctx,
}
if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
- pipe_put_tile_z(stImage->transfer,
- texDest + row*stImage->transfer->layer_stride,
+ pipe_put_tile_z(transfer, texDest + row*transfer->layer_stride,
0, 0, width, 1, data);
}
else {
- pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1,
- data);
+ pipe_put_tile_z(transfer, texDest, 0, row, width, 1, data);
}
}
}
@@ -1233,10 +1237,10 @@ fallback_copy_texsubimage(struct gl_context *ctx,
}
if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
- dstRowStride = stImage->transfer->layer_stride;
+ dstRowStride = transfer->layer_stride;
}
else {
- dstRowStride = stImage->transfer->stride;
+ dstRowStride = transfer->stride;
}
/* get float/RGBA image from framebuffer */
@@ -1269,7 +1273,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,
free(tempSrc);
}
- st_texture_image_unmap(st, stImage);
+ st_texture_image_unmap(st, stImage, slice);
pipe->transfer_unmap(pipe, src_trans);
}
@@ -1487,13 +1491,13 @@ st_finalize_texture(struct gl_context *ctx,
if (!st_obj) {
pipe_resource_reference(&stObj->pt, NULL);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ st_texture_release_all_sampler_views(stObj);
return GL_TRUE;
}
if (st_obj->buffer != stObj->pt) {
pipe_resource_reference(&stObj->pt, st_obj->buffer);
- pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
+ st_texture_release_all_sampler_views(stObj);
stObj->width0 = stObj->pt->width0 / _mesa_get_format_bytes(tObj->_BufferObjectFormat);
stObj->height0 = 1;
stObj->depth0 = 1;
@@ -1514,7 +1518,7 @@ st_finalize_texture(struct gl_context *ctx,
firstImage->pt != stObj->pt &&
(!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
pipe_resource_reference(&stObj->pt, firstImage->pt);
- pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
+ st_texture_release_all_sampler_views(stObj);
}
/* If this texture comes from a window system, there is nothing else to do. */
@@ -1561,7 +1565,7 @@ st_finalize_texture(struct gl_context *ctx,
* gallium texture now. We'll make a new one below.
*/
pipe_resource_reference(&stObj->pt, NULL);
- pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
+ st_texture_release_all_sampler_views(stObj);
st->dirty.st |= ST_NEW_FRAMEBUFFER;
}
}
diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c
index 807a86fdf..c7f3ec6be 100644
--- a/mesalib/src/mesa/state_tracker/st_context.c
+++ b/mesalib/src/mesa/state_tracker/st_context.c
@@ -152,7 +152,6 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
st_init_bitmap(st);
st_init_clear(st);
st_init_draw( st );
- st_init_generate_mipmap(st);
/* Choose texture target for glDrawPixels, glBitmap, renderbuffers */
if (pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
@@ -254,7 +253,6 @@ static void st_destroy_context_priv( struct st_context *st )
st_destroy_atoms( st );
st_destroy_draw( st );
- st_destroy_generate_mipmap(st);
st_destroy_clear(st);
st_destroy_bitmap(st);
st_destroy_drawpix(st);
diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h
index 0e00dd4fa..361a24b1d 100644
--- a/mesalib/src/mesa/state_tracker/st_context.h
+++ b/mesalib/src/mesa/state_tracker/st_context.h
@@ -188,7 +188,6 @@ struct st_context
void *passthrough_fs; /**< simple pass-through frag shader */
enum pipe_texture_target internal_target;
- struct gen_mipmap_state *gen_mipmap;
struct cso_context *cso_context;
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index 18ddd4e47..059989342 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -275,6 +275,9 @@ void st_init_limits(struct st_context *st)
c->MaxProgramTexelOffset = screen->get_param(screen, PIPE_CAP_MAX_TEXEL_OFFSET);
c->MaxProgramTextureGatherComponents = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS);
+ c->MinProgramTextureGatherOffset = screen->get_param(screen, PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET);
+ c->MaxProgramTextureGatherOffset = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET);
+
c->UniformBooleanTrue = ~0;
c->MaxTransformFeedbackBuffers =
@@ -421,7 +424,8 @@ void st_init_extensions(struct st_context *st)
{ o(OES_standard_derivatives), PIPE_CAP_SM3 },
{ o(ARB_texture_cube_map_array), PIPE_CAP_CUBE_MAP_ARRAY },
- { o(ARB_texture_multisample), PIPE_CAP_TEXTURE_MULTISAMPLE }
+ { o(ARB_texture_multisample), PIPE_CAP_TEXTURE_MULTISAMPLE },
+ { o(ARB_texture_query_lod), PIPE_CAP_TEXTURE_QUERY_LOD }
};
/* Required: render target and sampler support */
@@ -728,6 +732,13 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.EXT_framebuffer_multisample_blit_scaled = GL_TRUE;
}
+ if (ctx->Const.MaxSamples == 0 && screen->get_param(screen, PIPE_CAP_FAKE_SW_MSAA)) {
+ ctx->Const.FakeSWMSAA = GL_TRUE;
+ ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE;
+ ctx->Extensions.EXT_framebuffer_multisample_blit_scaled = GL_TRUE;
+ ctx->Extensions.ARB_texture_multisample = GL_TRUE;
+ }
+
if (ctx->Const.MaxDualSourceDrawBuffers > 0 &&
!st->options.disable_blend_func_extended)
ctx->Extensions.ARB_blend_func_extended = GL_TRUE;
diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c
index cd6b46681..38d4ccfea 100644
--- a/mesalib/src/mesa/state_tracker/st_format.c
+++ b/mesalib/src/mesa/state_tracker/st_format.c
@@ -1750,6 +1750,12 @@ st_choose_matching_format(struct pipe_screen *screen, unsigned bind,
if (_mesa_get_format_color_encoding(mesa_format) == GL_SRGB) {
continue;
}
+ if (_mesa_get_format_bits(mesa_format, GL_TEXTURE_INTENSITY_SIZE) > 0) {
+ /* If `format` is GL_RED/GL_RED_INTEGER, then we might match some
+ * intensity formats, which we don't want.
+ */
+ continue;
+ }
if (_mesa_format_matches_format_and_type(mesa_format, format, type,
swapBytes)) {
diff --git a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c
index b615575b5..18cf504a7 100644
--- a/mesalib/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/mesalib/src/mesa/state_tracker/st_gen_mipmap.c
@@ -44,64 +44,6 @@
/**
- * one-time init for generate mipmap
- * XXX Note: there may be other times we need no-op/simple state like this.
- * In that case, some code refactoring would be good.
- */
-void
-st_init_generate_mipmap(struct st_context *st)
-{
- st->gen_mipmap = util_create_gen_mipmap(st->pipe, st->cso_context);
-}
-
-
-void
-st_destroy_generate_mipmap(struct st_context *st)
-{
- util_destroy_gen_mipmap(st->gen_mipmap);
- st->gen_mipmap = NULL;
-}
-
-
-/**
- * Generate mipmap levels using hardware rendering.
- * \return TRUE if successful, FALSE if not possible
- */
-static boolean
-st_render_mipmap(struct st_context *st,
- GLenum target,
- struct st_texture_object *stObj,
- uint baseLevel, uint lastLevel)
-{
- struct pipe_context *pipe = st->pipe;
- struct pipe_screen *screen = pipe->screen;
- struct pipe_sampler_view *psv;
- const uint face = _mesa_tex_target_to_face(target);
-
-#if 0
- assert(target != GL_TEXTURE_3D); /* implemented but untested */
-#endif
-
- /* check if we can render in the texture's format */
- /* XXX should probably kill this and always use util_gen_mipmap
- since this implements a sw fallback as well */
- if (!screen->is_format_supported(screen, stObj->pt->format,
- stObj->pt->target,
- 0, PIPE_BIND_RENDER_TARGET)) {
- return FALSE;
- }
-
- psv = st_create_texture_sampler_view(pipe, stObj->pt);
-
- util_gen_mipmap(st->gen_mipmap, psv, face, baseLevel, lastLevel,
- PIPE_TEX_FILTER_LINEAR);
-
- pipe_sampler_view_reference(&psv, NULL);
-
- return TRUE;
-}
-
-/**
* Compute the expected number of mipmap levels in the texture given
* the width/height/depth of the base image and the GL_TEXTURE_BASE_LEVEL/
* GL_TEXTURE_MAX_LEVEL settings. This will tell us how many mipmap
@@ -136,7 +78,7 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
struct st_texture_object *stObj = st_texture_object(texObj);
struct pipe_resource *pt = st_get_texobj_resource(texObj);
const uint baseLevel = texObj->BaseLevel;
- uint lastLevel;
+ uint lastLevel, first_layer, last_layer;
uint dstLevel;
if (!pt)
@@ -182,7 +124,7 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
/* release the old tex (will likely be freed too) */
pipe_resource_reference(&oldTex, NULL);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ st_texture_release_all_sampler_views(stObj);
}
else {
/* Make sure that the base texture image data is present in the
@@ -195,12 +137,19 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
assert(pt->last_level >= lastLevel);
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ first_layer = last_layer = _mesa_tex_target_to_face(target);
+ }
+ else {
+ first_layer = 0;
+ last_layer = util_max_layer(pt, baseLevel);
+ }
+
/* Try to generate the mipmap by rendering/texturing. If that fails,
* use the software fallback.
*/
- if (!st_render_mipmap(st, target, stObj, baseLevel, lastLevel)) {
- /* since the util code actually also has a fallback, should
- probably make it never fail and kill this */
+ if (!util_gen_mipmap(st->pipe, pt, pt->format, baseLevel, lastLevel,
+ first_layer, last_layer, PIPE_TEX_FILTER_LINEAR)) {
_mesa_generate_mipmap(ctx, target, texObj);
}
diff --git a/mesalib/src/mesa/state_tracker/st_gen_mipmap.h b/mesalib/src/mesa/state_tracker/st_gen_mipmap.h
index 64eb39723..4cc208951 100644
--- a/mesalib/src/mesa/state_tracker/st_gen_mipmap.h
+++ b/mesalib/src/mesa/state_tracker/st_gen_mipmap.h
@@ -34,14 +34,6 @@
struct gl_context;
struct gl_texture_object;
-struct st_context;
-
-extern void
-st_init_generate_mipmap(struct st_context *st);
-
-
-extern void
-st_destroy_generate_mipmap(struct st_context *st);
extern void
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index f019a55c2..edd0aa765 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2793,7 +2793,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
}
break;
case ir_lod:
- assert(!"Unexpected ir_lod opcode");
+ opcode = TGSI_OPCODE_LODQ;
break;
case ir_query_levels:
assert(!"Unexpected ir_query_levels opcode");
@@ -4513,6 +4513,7 @@ compile_tgsi_instruction(struct st_translate *t,
case TGSI_OPCODE_TXB2:
case TGSI_OPCODE_TXL2:
case TGSI_OPCODE_TG4:
+ case TGSI_OPCODE_LODQ:
src[num_src++] = t->samplers[inst->sampler];
for (i = 0; i < inst->tex_offset_num_offset; i++) {
texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i], i);
@@ -5356,8 +5357,8 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
- progress = do_common_optimization(ir, true, true,
- options->MaxUnrollIterations, options)
+ progress = do_common_optimization(ir, true, true, options,
+ ctx->Const.NativeIntegers)
|| progress;
progress = lower_if_to_cond_assign(ir, options->MaxIfDepth) || progress;
diff --git a/mesalib/src/mesa/state_tracker/st_texture.c b/mesalib/src/mesa/state_tracker/st_texture.c
index a3b345356..f664ef5f1 100644
--- a/mesalib/src/mesa/state_tracker/st_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_texture.c
@@ -40,6 +40,7 @@
#include "util/u_format.h"
#include "util/u_rect.h"
#include "util/u_math.h"
+#include "util/u_memory.h"
#define DBG if(0) printf
@@ -240,11 +241,13 @@ GLubyte *
st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
enum pipe_transfer_usage usage,
GLuint x, GLuint y, GLuint z,
- GLuint w, GLuint h, GLuint d)
+ GLuint w, GLuint h, GLuint d,
+ struct pipe_transfer **transfer)
{
struct st_texture_object *stObj =
st_texture_object(stImage->base.TexObject);
GLuint level;
+ void *map;
DBG("%s \n", __FUNCTION__);
@@ -256,22 +259,41 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
else
level = stImage->base.Level;
- return pipe_transfer_map_3d(st->pipe, stImage->pt, level, usage,
- x, y, z + stImage->base.Face,
- w, h, d, &stImage->transfer);
+ z += stImage->base.Face;
+
+ map = pipe_transfer_map_3d(st->pipe, stImage->pt, level, usage,
+ x, y, z, w, h, d, transfer);
+ if (map) {
+ /* Enlarge the transfer array if it's not large enough. */
+ if (z >= stImage->num_transfers) {
+ unsigned new_size = z + 1;
+
+ stImage->transfer = realloc(stImage->transfer,
+ new_size * sizeof(void*));
+ memset(&stImage->transfer[stImage->num_transfers], 0,
+ (new_size - stImage->num_transfers) * sizeof(void*));
+ stImage->num_transfers = new_size;
+ }
+
+ assert(!stImage->transfer[z]);
+ stImage->transfer[z] = *transfer;
+ }
+ return map;
}
void
st_texture_image_unmap(struct st_context *st,
- struct st_texture_image *stImage)
+ struct st_texture_image *stImage, unsigned slice)
{
struct pipe_context *pipe = st->pipe;
+ struct pipe_transfer **transfer =
+ &stImage->transfer[slice + stImage->base.Face];
DBG("%s\n", __FUNCTION__);
- pipe_transfer_unmap(pipe, stImage->transfer);
- stImage->transfer = NULL;
+ pipe_transfer_unmap(pipe, *transfer);
+ *transfer = NULL;
}
@@ -412,10 +434,85 @@ st_create_color_map_texture(struct gl_context *ctx)
return pt;
}
+/**
+ * Try to find a matching sampler view for the given context.
+ * If none is found an empty slot is initialized with a
+ * template and returned instead.
+ */
+struct pipe_sampler_view **
+st_texture_get_sampler_view(struct st_context *st,
+ struct st_texture_object *stObj)
+{
+ struct pipe_sampler_view **used = NULL, **free = NULL;
+ GLuint i;
+
+ for (i = 0; i < stObj->num_sampler_views; ++i) {
+ struct pipe_sampler_view **sv = &stObj->sampler_views[i];
+ /* Is the array entry used ? */
+ if (*sv) {
+ /* Yes, check if it's the right one */
+ if ((*sv)->context == st->pipe)
+ return sv;
+
+ /* Wasn't the right one, but remember it as template */
+ used = sv;
+ } else {
+ /* Found a free slot, remember that */
+ free = sv;
+ }
+ }
+
+ /* Couldn't find a slot for our context, create a new one */
+
+ if (!free) {
+ /* Haven't even found a free one, resize the array */
+ GLuint old_size = stObj->num_sampler_views * sizeof(void *);
+ GLuint new_size = old_size + sizeof(void *);
+ stObj->sampler_views = REALLOC(stObj->sampler_views, old_size, new_size);
+ free = &stObj->sampler_views[stObj->num_sampler_views++];
+ *free = NULL;
+ }
+
+ /* Add just any sampler view to be used as a template */
+ if (used)
+ pipe_sampler_view_reference(free, *used);
+
+ return free;
+}
+
void
st_texture_release_sampler_view(struct st_context *st,
struct st_texture_object *stObj)
{
- if (stObj->sampler_view && stObj->sampler_view->context == st->pipe)
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ GLuint i;
+
+ for (i = 0; i < stObj->num_sampler_views; ++i) {
+ struct pipe_sampler_view **sv = &stObj->sampler_views[i];
+
+ if (*sv && (*sv)->context == st->pipe) {
+ pipe_sampler_view_reference(sv, NULL);
+ break;
+ }
+ }
+}
+
+void
+st_texture_release_all_sampler_views(struct st_texture_object *stObj)
+{
+ GLuint i;
+
+ for (i = 0; i < stObj->num_sampler_views; ++i)
+ pipe_sampler_view_reference(&stObj->sampler_views[i], NULL);
+}
+
+
+void
+st_texture_free_sampler_views(struct st_texture_object *stObj)
+{
+ /* NOTE:
+ * We use FREE() here to match REALLOC() above. Both come from
+ * u_memory.h, not imports.h. If we mis-match MALLOC/FREE from
+ * those two headers we can trash the heap.
+ */
+ FREE(stObj->sampler_views);
}
diff --git a/mesalib/src/mesa/state_tracker/st_texture.h b/mesalib/src/mesa/state_tracker/st_texture.h
index b4a27a00a..affb56812 100644
--- a/mesalib/src/mesa/state_tracker/st_texture.h
+++ b/mesalib/src/mesa/state_tracker/st_texture.h
@@ -56,7 +56,11 @@ struct st_texture_image
*/
struct pipe_resource *pt;
- struct pipe_transfer *transfer;
+ /* List of transfers, allocated on demand.
+ * transfer[layer] is a mapping for that layer.
+ */
+ struct pipe_transfer **transfer;
+ unsigned num_transfers;
};
@@ -82,10 +86,13 @@ struct st_texture_object
*/
struct pipe_resource *pt;
- /* Default sampler view attached to this texture object. Created lazily
- * on first binding.
+ /* Number of views in sampler_views array */
+ GLuint num_sampler_views;
+
+ /* Array of sampler views (one per context) attached to this texture
+ * object. Created lazily on first binding in context.
*/
- struct pipe_sampler_view *sampler_view;
+ struct pipe_sampler_view **sampler_views;
/* True if this texture comes from the window system. Such a texture
* cannot be reallocated and the format can only be changed with a sampler
@@ -192,11 +199,12 @@ extern GLubyte *
st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
enum pipe_transfer_usage usage,
GLuint x, GLuint y, GLuint z,
- GLuint w, GLuint h, GLuint d);
+ GLuint w, GLuint h, GLuint d,
+ struct pipe_transfer **transfer);
extern void
st_texture_image_unmap(struct st_context *st,
- struct st_texture_image *stImage);
+ struct st_texture_image *stImage, unsigned slice);
/* Return pointers to each 2d slice within an image. Indexed by depth
@@ -227,8 +235,18 @@ st_texture_image_copy(struct pipe_context *pipe,
extern struct pipe_resource *
st_create_color_map_texture(struct gl_context *ctx);
+extern struct pipe_sampler_view **
+st_texture_get_sampler_view(struct st_context *st,
+ struct st_texture_object *stObj);
+
extern void
st_texture_release_sampler_view(struct st_context *st,
struct st_texture_object *stObj);
+extern void
+st_texture_release_all_sampler_views(struct st_texture_object *stObj);
+
+void
+st_texture_free_sampler_views(struct st_texture_object *stObj);
+
#endif
diff --git a/mesalib/src/mesa/state_tracker/st_vdpau.c b/mesalib/src/mesa/state_tracker/st_vdpau.c
index c5b4780ce..8c10cdaf3 100644
--- a/mesalib/src/mesa/state_tracker/st_vdpau.c
+++ b/mesalib/src/mesa/state_tracker/st_vdpau.c
@@ -63,7 +63,7 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access,
struct st_texture_image *stImage = st_texture_image(texImage);
struct pipe_resource *res;
- struct pipe_sampler_view *sv, templ;
+ struct pipe_sampler_view templ, **sampler_view;
mesa_format texFormat;
getProcAddr = ctx->vdpGetProcAddress;
@@ -83,6 +83,7 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access,
}
} else {
+ struct pipe_sampler_view *sv;
VdpVideoSurfaceGallium *f;
struct pipe_video_buffer *buffer;
@@ -138,7 +139,7 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access,
texFormat);
pipe_resource_reference(&stObj->pt, res);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ st_texture_release_all_sampler_views(stObj);
pipe_resource_reference(&stImage->pt, res);
u_sampler_view_default_template(&templ, res, res->format);
@@ -148,7 +149,9 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access,
templ.swizzle_g = GET_SWZ(stObj->base._Swizzle, 1);
templ.swizzle_b = GET_SWZ(stObj->base._Swizzle, 2);
templ.swizzle_a = GET_SWZ(stObj->base._Swizzle, 3);
- stObj->sampler_view = st->pipe->create_sampler_view(st->pipe, res, &templ);
+
+ sampler_view = st_texture_get_sampler_view(st, stObj);
+ *sampler_view = st->pipe->create_sampler_view(st->pipe, res, &templ);
stObj->width0 = res->width0;
stObj->height0 = res->height0;
@@ -169,7 +172,7 @@ st_vdpau_unmap_surface(struct gl_context *ctx, GLenum target, GLenum access,
struct st_texture_image *stImage = st_texture_image(texImage);
pipe_resource_reference(&stObj->pt, NULL);
- pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+ st_texture_release_all_sampler_views(stObj);
pipe_resource_reference(&stImage->pt, NULL);
_mesa_dirty_texobj(ctx, texObj);