diff options
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_sampler.c | 22 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_texture.c | 55 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c | 28 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_eglimage.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_texture.c | 48 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_context.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_context.h | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_extensions.c | 13 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_gen_mipmap.c | 75 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_gen_mipmap.h | 8 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 7 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_texture.c | 115 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_texture.h | 30 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_vdpau.c | 11 |
14 files changed, 263 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_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); |