diff options
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_texture.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_condrender.c | 20 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_drawpixels.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_fbo.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_readpixels.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_texture.c | 94 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_context.c | 39 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_context.h | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_extensions.c | 461 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_extensions.h | 16 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.c | 95 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.h | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 72 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_manager.c | 38 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_texture.c | 16 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_texture.h | 15 |
16 files changed, 609 insertions, 270 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c index 2e10bc3e2..03d05932a 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_texture.c +++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c @@ -338,7 +338,7 @@ update_single_texture(struct st_context *st, /* Determine the format of the texture sampler view */ if (texObj->Target == GL_TEXTURE_BUFFER) { view_format = - st_mesa_format_to_pipe_format(stObj->base._BufferObjectFormat); + st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat); } else { view_format = diff --git a/mesalib/src/mesa/state_tracker/st_cb_condrender.c b/mesalib/src/mesa/state_tracker/st_cb_condrender.c index 8776985f9..f02472aec 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_condrender.c +++ b/mesalib/src/mesa/state_tracker/st_cb_condrender.c @@ -55,6 +55,8 @@ st_BeginConditionalRender(struct gl_context *ctx, struct gl_query_object *q, struct st_query_object *stq = st_query_object(q); struct st_context *st = st_context(ctx); uint m; + /* Don't invert the condition for rendering by default */ + boolean inverted = FALSE; st_flush_bitmap_cache(st); @@ -71,12 +73,28 @@ st_BeginConditionalRender(struct gl_context *ctx, struct gl_query_object *q, case GL_QUERY_BY_REGION_NO_WAIT: m = PIPE_RENDER_COND_BY_REGION_NO_WAIT; break; + case GL_QUERY_WAIT_INVERTED: + m = PIPE_RENDER_COND_WAIT; + inverted = TRUE; + break; + case GL_QUERY_NO_WAIT_INVERTED: + m = PIPE_RENDER_COND_NO_WAIT; + inverted = TRUE; + break; + case GL_QUERY_BY_REGION_WAIT_INVERTED: + m = PIPE_RENDER_COND_BY_REGION_WAIT; + inverted = TRUE; + break; + case GL_QUERY_BY_REGION_NO_WAIT_INVERTED: + m = PIPE_RENDER_COND_BY_REGION_NO_WAIT; + inverted = TRUE; + break; default: assert(0 && "bad mode in st_BeginConditionalRender"); m = PIPE_RENDER_COND_WAIT; } - cso_set_render_condition(st->cso_context, stq->pq, FALSE, m); + cso_set_render_condition(st->cso_context, stq->pq, inverted, m); } diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index d13a17f50..5ae092b94 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -491,7 +491,7 @@ make_texture(struct st_context *st, /* Choose a pixel format for the temp texture which will hold the * image to draw. */ - pipeFormat = st_choose_matching_format(pipe->screen, PIPE_BIND_SAMPLER_VIEW, + pipeFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW, format, type, unpack->SwapBytes); if (pipeFormat == PIPE_FORMAT_NONE) { diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c index ce8d91514..7cfd3dade 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c @@ -588,7 +588,7 @@ st_validate_attachment(struct gl_context *ctx, if (!ctx->Extensions.EXT_framebuffer_sRGB && _mesa_get_format_color_encoding(texFormat) == GL_SRGB) { const mesa_format linearFormat = _mesa_get_srgb_format_linear(texFormat); - format = st_mesa_format_to_pipe_format(linearFormat); + format = st_mesa_format_to_pipe_format(st_context(ctx), linearFormat); } valid = screen->is_format_supported(screen, format, diff --git a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c index 3f7bbd973..d95a608d3 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c @@ -143,7 +143,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, /* Choose the destination format by finding the best match * for the format+type combo. */ - dst_format = st_choose_matching_format(screen, bind, format, type, + dst_format = st_choose_matching_format(st, bind, format, type, pack->SwapBytes); if (dst_format == PIPE_FORMAT_NONE) { goto fallback; diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index c4b2107ba..ad14bd939 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -37,6 +37,7 @@ #include "main/pbo.h" #include "main/pixeltransfer.h" #include "main/texcompress.h" +#include "main/texcompress_etc.h" #include "main/texgetimage.h" #include "main/teximage.h" #include "main/texobj.h" @@ -207,8 +208,32 @@ st_MapTextureImage(struct gl_context *ctx, map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1, &transfer); if (map) { - *mapOut = map; - *rowStrideOut = transfer->stride; + if (_mesa_is_format_etc2(texImage->TexFormat) || + (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)) { + /* ETC isn't supported by gallium and it's represented + * by uncompressed formats. Only write transfers with precompressed + * data are supported by ES3, which makes this really simple. + * + * Just create a temporary storage where the ETC texture will + * be stored. It will be decompressed in the Unmap function. + */ + unsigned z = transfer->box.z; + struct st_texture_image_transfer *itransfer = &stImage->transfer[z]; + + itransfer->temp_data = + malloc(_mesa_format_image_size(texImage->TexFormat, w, h, 1)); + itransfer->temp_stride = + _mesa_format_row_stride(texImage->TexFormat, w); + itransfer->map = map; + + *mapOut = itransfer->temp_data; + *rowStrideOut = itransfer->temp_stride; + } + else { + /* supported mapping */ + *mapOut = map; + *rowStrideOut = transfer->stride; + } } else { *mapOut = NULL; @@ -225,6 +250,35 @@ st_UnmapTextureImage(struct gl_context *ctx, { struct st_context *st = st_context(ctx); struct st_texture_image *stImage = st_texture_image(texImage); + + if (_mesa_is_format_etc2(texImage->TexFormat) || + (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)) { + /* Decompress the ETC texture to the mapped one. */ + unsigned z = slice + stImage->base.Face; + struct st_texture_image_transfer *itransfer = &stImage->transfer[z]; + struct pipe_transfer *transfer = itransfer->transfer; + + assert(z == transfer->box.z); + + if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) { + _mesa_etc1_unpack_rgba8888(itransfer->map, transfer->stride, + itransfer->temp_data, + itransfer->temp_stride, + transfer->box.width, transfer->box.height); + } + else { + _mesa_unpack_etc2_format(itransfer->map, transfer->stride, + itransfer->temp_data, itransfer->temp_stride, + transfer->box.width, transfer->box.height, + texImage->TexFormat); + } + + free(itransfer->temp_data); + itransfer->temp_data = NULL; + itransfer->temp_stride = 0; + itransfer->map = 0; + } + st_texture_image_unmap(st, stImage, slice); } @@ -398,7 +452,7 @@ guess_and_alloc_texture(struct st_context *st, stObj->height0 = height; stObj->depth0 = depth; - fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat); + fmt = st_mesa_format_to_pipe_format(st, stImage->base.TexFormat); bindings = default_bindings(st, fmt); @@ -449,7 +503,7 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, /* Look if the parent texture object has space for this image */ if (stObj->pt && level <= stObj->pt->last_level && - st_texture_match_image(stObj->pt, texImage)) { + st_texture_match_image(st, stObj->pt, texImage)) { /* this image will fit in the existing texture object's memory */ pipe_resource_reference(&stImage->pt, stObj->pt); return GL_TRUE; @@ -472,7 +526,7 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, } if (stObj->pt && - st_texture_match_image(stObj->pt, texImage)) { + st_texture_match_image(st, stObj->pt, texImage)) { /* The image will live in the object's mipmap memory */ pipe_resource_reference(&stImage->pt, stObj->pt); assert(stImage->pt); @@ -486,7 +540,7 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, * level. */ enum pipe_format format = - st_mesa_format_to_pipe_format(texImage->TexFormat); + st_mesa_format_to_pipe_format(st, texImage->TexFormat); GLuint bindings = default_bindings(st, format); GLuint ptWidth, ptHeight, ptDepth, ptLayers; @@ -613,6 +667,9 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims, unsigned bind; GLubyte *map; + assert(!_mesa_is_format_etc2(texImage->TexFormat) && + texImage->TexFormat != MESA_FORMAT_ETC1_RGB8); + if (!st->prefer_blit_based_texture_transfer) { goto fallback; } @@ -660,7 +717,7 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims, } /* Choose the source format. */ - src_format = st_choose_matching_format(screen, PIPE_BIND_SAMPLER_VIEW, + src_format = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW, format, type, unpack->SwapBytes); if (!src_format) { goto fallback; @@ -872,6 +929,9 @@ st_GetTexImage(struct gl_context * ctx, ubyte *map = NULL; boolean done = FALSE; + assert(!_mesa_is_format_etc2(texImage->TexFormat) && + texImage->TexFormat != MESA_FORMAT_ETC1_RGB8); + if (!st->prefer_blit_based_texture_transfer && !_mesa_is_format_compressed(texImage->TexFormat)) { /* Try to avoid the fallback if we're doing texture decompression here */ @@ -934,7 +994,7 @@ st_GetTexImage(struct gl_context * ctx, /* Choose the destination format by finding the best match * for the format+type combo. */ - dst_format = st_choose_matching_format(screen, bind, format, type, + dst_format = st_choose_matching_format(st, bind, format, type, ctx->Pack.SwapBytes); if (dst_format == PIPE_FORMAT_NONE) { @@ -956,6 +1016,7 @@ st_GetTexImage(struct gl_context * ctx, case PIPE_FORMAT_RGTC1_UNORM: case PIPE_FORMAT_RGTC2_UNORM: case PIPE_FORMAT_ETC1_RGB8: + case PIPE_FORMAT_BPTC_RGBA_UNORM: dst_glformat = GL_RGBA8; break; case PIPE_FORMAT_RGTC1_SNORM: @@ -964,7 +1025,12 @@ st_GetTexImage(struct gl_context * ctx, goto fallback; dst_glformat = GL_RGBA8_SNORM; break; - /* TODO: for BPTC_*FLOAT, set RGBA32F and check for ARB_texture_float */ + case PIPE_FORMAT_BPTC_RGB_FLOAT: + case PIPE_FORMAT_BPTC_RGB_UFLOAT: + if (!ctx->Extensions.ARB_texture_float) + goto fallback; + dst_glformat = GL_RGBA32F; + break; default: assert(0); goto fallback; @@ -1308,6 +1374,9 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, unsigned bind; GLint srcY0, srcY1; + assert(!_mesa_is_format_etc2(texImage->TexFormat) && + texImage->TexFormat != MESA_FORMAT_ETC1_RGB8); + if (!strb || !strb->surface || !stImage->pt) { debug_printf("%s: null strb or stImage\n", __FUNCTION__); return; @@ -1531,7 +1600,8 @@ st_finalize_texture(struct gl_context *ctx, } /* Find gallium format for the Mesa texture */ - firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat); + firstImageFormat = + st_mesa_format_to_pipe_format(st, firstImage->base.TexFormat); /* Find size of level=0 Gallium mipmap image, plus number of texture layers */ { @@ -1649,7 +1719,7 @@ st_AllocTextureStorage(struct gl_context *ctx, stObj->depth0 = depth; stObj->lastLevel = levels - 1; - fmt = st_mesa_format_to_pipe_format(texImage->TexFormat); + fmt = st_mesa_format_to_pipe_format(st, texImage->TexFormat); bindings = default_bindings(st, fmt); @@ -1728,7 +1798,7 @@ st_TestProxyTexImage(struct gl_context *ctx, GLenum target, memset(&pt, 0, sizeof(pt)); pt.target = gl_target_to_pipe(target); - pt.format = st_mesa_format_to_pipe_format(format); + pt.format = st_mesa_format_to_pipe_format(st, format); st_gl_texture_dims_to_pipe_dims(target, width, height, depth, diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c index c805a094b..09b615465 100644 --- a/mesalib/src/mesa/state_tracker/st_context.c +++ b/mesalib/src/mesa/state_tracker/st_context.c @@ -189,6 +189,9 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, st->has_stencil_export = screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT); st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3); + st->has_etc1 = screen->is_format_supported(screen, PIPE_FORMAT_ETC1_RGB8, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW); st->prefer_blit_based_texture_transfer = screen->get_param(screen, PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER); @@ -198,10 +201,40 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) & (PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 | PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600)); + st->has_time_elapsed = + screen->get_param(screen, PIPE_CAP_QUERY_TIME_ELAPSED); /* GL limits and extensions */ - st_init_limits(st); - st_init_extensions(st); + st_init_limits(st->pipe->screen, &ctx->Const, &ctx->Extensions); + st_init_extensions(st->pipe->screen, ctx->API, &ctx->Const, + &ctx->Extensions, &st->options, ctx->Mesa_DXTn); + + /* Enable shader-based fallbacks for ARB_color_buffer_float if needed. */ + if (screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_UNCLAMPED)) { + if (!screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_CLAMPED)) { + st->clamp_vert_color_in_shader = GL_TRUE; + } + + if (!screen->get_param(screen, PIPE_CAP_FRAGMENT_COLOR_CLAMPED)) { + st->clamp_frag_color_in_shader = GL_TRUE; + } + + /* For drivers which cannot do color clamping, it's better to just + * disable ARB_color_buffer_float in the core profile, because + * the clamping is deprecated there anyway. */ + if (ctx->API == API_OPENGL_CORE && + (st->clamp_frag_color_in_shader || st->clamp_vert_color_in_shader)) { + st->clamp_vert_color_in_shader = GL_FALSE; + st->clamp_frag_color_in_shader = GL_FALSE; + ctx->Extensions.ARB_color_buffer_float = GL_FALSE; + } + } + + /* called after _mesa_create_context/_mesa_init_point, fix default user + * settable max point size up + */ + st->ctx->Point.MaxSize = MAX2(ctx->Const.MaxPointSize, + ctx->Const.MaxPointSizeAA); _mesa_compute_version(ctx); @@ -241,7 +274,7 @@ struct st_context *st_create_context(gl_api api, struct pipe_context *pipe, * driver prefers DP4 or MUL/MAD for vertex transformation. */ if (debug_get_option_mesa_mvp_dp4()) - ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = GL_TRUE; + ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = GL_TRUE; return st_create_context_priv(ctx, pipe, options); } diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index 361a24b1d..6d572bd49 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -86,6 +86,7 @@ struct st_context boolean has_stencil_export; /**< can do shader stencil export? */ boolean has_time_elapsed; boolean has_shader_model3; + boolean has_etc1; boolean prefer_blit_based_texture_transfer; boolean needs_texcoord_semantic; diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 7ac484056..4110eb5dd 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -70,10 +70,9 @@ static int _clamp(int a, int min, int max) * Query driver to get implementation limits. * Note that we have to limit/clamp against Mesa's internal limits too. */ -void st_init_limits(struct st_context *st) +void st_init_limits(struct pipe_screen *screen, + struct gl_constants *c, struct gl_extensions *extensions) { - struct pipe_screen *screen = st->pipe->screen; - struct gl_constants *c = &st->ctx->Const; unsigned sh; boolean can_ubo = TRUE; @@ -124,10 +123,7 @@ void st_init_limits(struct st_context *st) c->MaxPointSizeAA = _maxf(1.0f, screen->get_paramf(screen, PIPE_CAPF_MAX_POINT_WIDTH_AA)); - /* called after _mesa_create_context/_mesa_init_point, fix default user - * settable max point size up - */ - st->ctx->Point.MaxSize = MAX2(c->MaxPointSize, c->MaxPointSizeAA); + /* these are not queryable. Note that GL basically mandates a 1.0 minimum * for non-aa sizes, but we can go down to 0.0 for aa points. */ @@ -158,15 +154,15 @@ void st_init_limits(struct st_context *st) switch (sh) { case PIPE_SHADER_FRAGMENT: pc = &c->Program[MESA_SHADER_FRAGMENT]; - options = &st->ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT]; + options = &c->ShaderCompilerOptions[MESA_SHADER_FRAGMENT]; break; case PIPE_SHADER_VERTEX: pc = &c->Program[MESA_SHADER_VERTEX]; - options = &st->ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX]; + options = &c->ShaderCompilerOptions[MESA_SHADER_VERTEX]; break; case PIPE_SHADER_GEOMETRY: pc = &c->Program[MESA_SHADER_GEOMETRY]; - options = &st->ctx->ShaderCompilerOptions[MESA_SHADER_GEOMETRY]; + options = &c->ShaderCompilerOptions[MESA_SHADER_GEOMETRY]; break; default: /* compute shader, etc. */ @@ -191,8 +187,7 @@ void st_init_limits(struct st_context *st) pc->MaxTemps = pc->MaxNativeTemps = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_TEMPS); pc->MaxAddressRegs = pc->MaxNativeAddressRegs = - _min(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_ADDRS), - MAX_PROGRAM_ADDRESS_REGS); + sh == PIPE_SHADER_VERTEX ? 1 : 0; pc->MaxParameters = pc->MaxNativeParameters = screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE) / sizeof(float[4]); @@ -300,7 +295,7 @@ void st_init_limits(struct st_context *st) screen->get_param(screen, PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS); if (can_ubo) { - st->ctx->Extensions.ARB_uniform_buffer_object = GL_TRUE; + extensions->ARB_uniform_buffer_object = GL_TRUE; c->UniformBufferOffsetAlignment = screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT); c->MaxCombinedUniformBlocks = c->MaxUniformBufferBindings = @@ -340,14 +335,15 @@ struct st_extension_format_mapping { * * target and bind_flags are passed to is_format_supported. */ -static void init_format_extensions(struct st_context *st, - const struct st_extension_format_mapping *mapping, - unsigned num_mappings, - enum pipe_texture_target target, - unsigned bind_flags) +static void +init_format_extensions(struct pipe_screen *screen, + struct gl_extensions *extensions, + const struct st_extension_format_mapping *mapping, + unsigned num_mappings, + enum pipe_texture_target target, + unsigned bind_flags) { - struct pipe_screen *screen = st->pipe->screen; - GLboolean *extensions = (GLboolean *) &st->ctx->Extensions; + GLboolean *extension_table = (GLboolean *) extensions; unsigned i; int j; int num_formats = Elements(mapping->format); @@ -371,10 +367,36 @@ static void init_format_extensions(struct st_context *st, /* Enable all extensions in the list. */ for (j = 0; j < num_ext && mapping[i].extension_offset[j]; j++) - extensions[mapping[i].extension_offset[j]] = GL_TRUE; + extension_table[mapping[i].extension_offset[j]] = GL_TRUE; } } + +/** + * Given a list of formats and bind flags, return the maximum number + * of samples supported by any of those formats. + */ +static unsigned +get_max_samples_for_formats(struct pipe_screen *screen, + unsigned num_formats, + enum pipe_format *formats, + unsigned max_samples, + unsigned bind) +{ + unsigned i, f; + + for (i = max_samples; i > 0; --i) { + for (f = 0; f < num_formats; f++) { + if (screen->is_format_supported(screen, formats[f], + PIPE_TEXTURE_2D, i, bind)) { + return i; + } + } + } + return 0; +} + + /** * Use pipe_screen::get_param() to query PIPE_CAP_ values to determine * which GL extensions are supported. @@ -382,12 +404,15 @@ static void init_format_extensions(struct st_context *st, * features or can be built on top of other gallium features. * Some fine tuning may still be needed. */ -void st_init_extensions(struct st_context *st) +void st_init_extensions(struct pipe_screen *screen, + gl_api api, + struct gl_constants *consts, + struct gl_extensions *extensions, + struct st_config_options *options, + boolean has_lib_dxtc) { - struct pipe_screen *screen = st->pipe->screen; - struct gl_context *ctx = st->ctx; int i, glsl_feature_level; - GLboolean *extensions = (GLboolean *) &ctx->Extensions; + GLboolean *extension_table = (GLboolean *) extensions; static const struct st_extension_cap_mapping cap_mapping[] = { { o(ARB_base_instance), PIPE_CAP_START_INSTANCE }, @@ -433,7 +458,9 @@ void st_init_extensions(struct st_context *st) { o(ARB_texture_multisample), PIPE_CAP_TEXTURE_MULTISAMPLE }, { o(ARB_texture_query_lod), PIPE_CAP_TEXTURE_QUERY_LOD }, { o(ARB_sample_shading), PIPE_CAP_SAMPLE_SHADING }, - { o(ARB_draw_indirect), PIPE_CAP_DRAW_INDIRECT } + { o(ARB_draw_indirect), PIPE_CAP_DRAW_INDIRECT }, + { o(ARB_derivative_control), PIPE_CAP_TGSI_FS_FINE_DERIVATIVE }, + { o(ARB_conditional_render_inverted), PIPE_CAP_CONDITIONAL_RENDER_INVERTED }, }; /* Required: render target and sampler support */ @@ -492,6 +519,12 @@ void st_init_extensions(struct st_context *st) PIPE_FORMAT_DXT3_RGBA, PIPE_FORMAT_DXT5_RGBA } }, + { { o(ARB_texture_compression_bptc) }, + { PIPE_FORMAT_BPTC_RGBA_UNORM, + PIPE_FORMAT_BPTC_SRGBA, + PIPE_FORMAT_BPTC_RGB_FLOAT, + PIPE_FORMAT_BPTC_RGB_UFLOAT } }, + { { o(EXT_texture_shared_exponent) }, { PIPE_FORMAT_R9G9B9E5_FLOAT } }, @@ -513,7 +546,9 @@ void st_init_extensions(struct st_context *st) GL_TRUE }, /* at least one format must be supported */ { { o(OES_compressed_ETC1_RGB8_texture) }, - { PIPE_FORMAT_ETC1_RGB8 } }, + { PIPE_FORMAT_ETC1_RGB8, + PIPE_FORMAT_R8G8B8A8_UNORM }, + GL_TRUE }, /* at least one format must be supported */ { { o(ARB_stencil_texturing) }, { PIPE_FORMAT_X24S8_UINT, @@ -547,256 +582,248 @@ void st_init_extensions(struct st_context *st) /* * Extensions that are supported by all Gallium drivers: */ - ctx->Extensions.ARB_ES2_compatibility = GL_TRUE; - ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE; - ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE; - ctx->Extensions.ARB_explicit_uniform_location = GL_TRUE; - ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; - ctx->Extensions.ARB_fragment_program = GL_TRUE; - ctx->Extensions.ARB_fragment_shader = GL_TRUE; - ctx->Extensions.ARB_half_float_vertex = GL_TRUE; - ctx->Extensions.ARB_internalformat_query = GL_TRUE; - ctx->Extensions.ARB_map_buffer_range = GL_TRUE; - ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */ - ctx->Extensions.ARB_texture_cube_map = GL_TRUE; - ctx->Extensions.ARB_texture_env_combine = GL_TRUE; - ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE; - ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE; - ctx->Extensions.ARB_vertex_program = GL_TRUE; - ctx->Extensions.ARB_vertex_shader = GL_TRUE; - - ctx->Extensions.EXT_blend_color = GL_TRUE; - ctx->Extensions.EXT_blend_func_separate = GL_TRUE; - ctx->Extensions.EXT_blend_minmax = GL_TRUE; - ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE; - ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE; - ctx->Extensions.EXT_point_parameters = GL_TRUE; - ctx->Extensions.EXT_provoking_vertex = GL_TRUE; - - ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE; - ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE; - - ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE; - - ctx->Extensions.MESA_pack_invert = GL_TRUE; - - ctx->Extensions.NV_fog_distance = GL_TRUE; - ctx->Extensions.NV_texture_env_combine4 = GL_TRUE; - ctx->Extensions.NV_texture_rectangle = GL_TRUE; - ctx->Extensions.NV_vdpau_interop = GL_TRUE; - - ctx->Extensions.OES_EGL_image = GL_TRUE; - ctx->Extensions.OES_EGL_image_external = GL_TRUE; - ctx->Extensions.OES_draw_texture = GL_TRUE; + extensions->ARB_ES2_compatibility = GL_TRUE; + extensions->ARB_draw_elements_base_vertex = GL_TRUE; + extensions->ARB_explicit_attrib_location = GL_TRUE; + extensions->ARB_explicit_uniform_location = GL_TRUE; + extensions->ARB_fragment_coord_conventions = GL_TRUE; + extensions->ARB_fragment_program = GL_TRUE; + extensions->ARB_fragment_shader = GL_TRUE; + extensions->ARB_half_float_vertex = GL_TRUE; + extensions->ARB_internalformat_query = GL_TRUE; + extensions->ARB_map_buffer_range = GL_TRUE; + extensions->ARB_texture_border_clamp = GL_TRUE; /* XXX temp */ + extensions->ARB_texture_cube_map = GL_TRUE; + extensions->ARB_texture_env_combine = GL_TRUE; + extensions->ARB_texture_env_crossbar = GL_TRUE; + extensions->ARB_texture_env_dot3 = GL_TRUE; + extensions->ARB_vertex_program = GL_TRUE; + extensions->ARB_vertex_shader = GL_TRUE; + + extensions->EXT_blend_color = GL_TRUE; + extensions->EXT_blend_func_separate = GL_TRUE; + extensions->EXT_blend_minmax = GL_TRUE; + extensions->EXT_gpu_program_parameters = GL_TRUE; + extensions->EXT_pixel_buffer_object = GL_TRUE; + extensions->EXT_point_parameters = GL_TRUE; + extensions->EXT_provoking_vertex = GL_TRUE; + + extensions->EXT_texture_env_dot3 = GL_TRUE; + extensions->EXT_vertex_array_bgra = GL_TRUE; + + extensions->ATI_texture_env_combine3 = GL_TRUE; + + extensions->MESA_pack_invert = GL_TRUE; + + extensions->NV_fog_distance = GL_TRUE; + extensions->NV_texture_env_combine4 = GL_TRUE; + extensions->NV_texture_rectangle = GL_TRUE; + extensions->NV_vdpau_interop = GL_TRUE; + + extensions->OES_EGL_image = GL_TRUE; + extensions->OES_EGL_image_external = GL_TRUE; + extensions->OES_draw_texture = GL_TRUE; /* Expose the extensions which directly correspond to gallium caps. */ for (i = 0; i < Elements(cap_mapping); i++) { if (screen->get_param(screen, cap_mapping[i].cap)) { - extensions[cap_mapping[i].extension_offset] = GL_TRUE; + extension_table[cap_mapping[i].extension_offset] = GL_TRUE; } } /* Expose the extensions which directly correspond to gallium formats. */ - init_format_extensions(st, rendertarget_mapping, + init_format_extensions(screen, extensions, rendertarget_mapping, Elements(rendertarget_mapping), PIPE_TEXTURE_2D, PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW); - init_format_extensions(st, depthstencil_mapping, + init_format_extensions(screen, extensions, depthstencil_mapping, Elements(depthstencil_mapping), PIPE_TEXTURE_2D, PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_SAMPLER_VIEW); - init_format_extensions(st, texture_mapping, Elements(texture_mapping), - PIPE_TEXTURE_2D, PIPE_BIND_SAMPLER_VIEW); - init_format_extensions(st, vertex_mapping, Elements(vertex_mapping), - PIPE_BUFFER, PIPE_BIND_VERTEX_BUFFER); + init_format_extensions(screen, extensions, texture_mapping, + Elements(texture_mapping), PIPE_TEXTURE_2D, + PIPE_BIND_SAMPLER_VIEW); + init_format_extensions(screen, extensions, vertex_mapping, + Elements(vertex_mapping), PIPE_BUFFER, + PIPE_BIND_VERTEX_BUFFER); /* Figure out GLSL support. */ glsl_feature_level = screen->get_param(screen, PIPE_CAP_GLSL_FEATURE_LEVEL); - ctx->Const.GLSLVersion = glsl_feature_level; + consts->GLSLVersion = glsl_feature_level; if (glsl_feature_level >= 330) - ctx->Const.GLSLVersion = 330; + consts->GLSLVersion = 330; - _mesa_override_glsl_version(st->ctx); + _mesa_override_glsl_version(consts); - if (st->options.force_glsl_version > 0 && - st->options.force_glsl_version <= ctx->Const.GLSLVersion) { - ctx->Const.ForceGLSLVersion = st->options.force_glsl_version; + if (options->force_glsl_version > 0 && + options->force_glsl_version <= consts->GLSLVersion) { + consts->ForceGLSLVersion = options->force_glsl_version; } + if (glsl_feature_level >= 400) + extensions->ARB_gpu_shader5 = GL_TRUE; + /* This extension needs full OpenGL 3.2, but we don't know if that's * supported at this point. Only check the GLSL version. */ - if (ctx->Const.GLSLVersion >= 150 && + if (consts->GLSLVersion >= 150 && screen->get_param(screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) { - ctx->Extensions.AMD_vertex_shader_layer = GL_TRUE; + extensions->AMD_vertex_shader_layer = GL_TRUE; } - if (ctx->Const.GLSLVersion >= 130) { - ctx->Const.NativeIntegers = GL_TRUE; - ctx->Const.MaxClipPlanes = 8; + if (consts->GLSLVersion >= 130) { + consts->NativeIntegers = GL_TRUE; + consts->MaxClipPlanes = 8; /* Extensions that either depend on GLSL 1.30 or are a subset thereof. */ - ctx->Extensions.ARB_conservative_depth = GL_TRUE; - ctx->Extensions.ARB_shading_language_packing = GL_TRUE; - ctx->Extensions.OES_depth_texture_cube_map = GL_TRUE; - ctx->Extensions.ARB_shading_language_420pack = GL_TRUE; - ctx->Extensions.ARB_texture_query_levels = GL_TRUE; - - if (!st->options.disable_shader_bit_encoding) { - ctx->Extensions.ARB_shader_bit_encoding = GL_TRUE; + extensions->ARB_conservative_depth = GL_TRUE; + extensions->ARB_shading_language_packing = GL_TRUE; + extensions->OES_depth_texture_cube_map = GL_TRUE; + extensions->ARB_shading_language_420pack = GL_TRUE; + extensions->ARB_texture_query_levels = GL_TRUE; + + if (!options->disable_shader_bit_encoding) { + extensions->ARB_shader_bit_encoding = GL_TRUE; } - ctx->Extensions.EXT_shader_integer_mix = GL_TRUE; + extensions->EXT_shader_integer_mix = GL_TRUE; } else { /* Optional integer support for GLSL 1.2. */ if (screen->get_shader_param(screen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS) && screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_INTEGERS)) { - ctx->Const.NativeIntegers = GL_TRUE; + consts->NativeIntegers = GL_TRUE; - ctx->Extensions.EXT_shader_integer_mix = GL_TRUE; + extensions->EXT_shader_integer_mix = GL_TRUE; } } /* Below are the cases which cannot be moved into tables easily. */ - if (!ctx->Mesa_DXTn && !st->options.force_s3tc_enable) { - ctx->Extensions.EXT_texture_compression_s3tc = GL_FALSE; - ctx->Extensions.ANGLE_texture_compression_dxt = GL_FALSE; + if (!has_lib_dxtc && !options->force_s3tc_enable) { + extensions->EXT_texture_compression_s3tc = GL_FALSE; + extensions->ANGLE_texture_compression_dxt = GL_FALSE; } if (screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { #if 0 /* XXX re-enable when GLSL compiler again supports geometry shaders */ - ctx->Extensions.ARB_geometry_shader4 = GL_TRUE; + extensions->ARB_geometry_shader4 = GL_TRUE; #endif } - ctx->Extensions.NV_primitive_restart = GL_TRUE; + extensions->NV_primitive_restart = GL_TRUE; if (!screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) { - ctx->Const.PrimitiveRestartInSoftware = GL_TRUE; + consts->PrimitiveRestartInSoftware = GL_TRUE; } /* ARB_color_buffer_float. */ if (screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_UNCLAMPED)) { - ctx->Extensions.ARB_color_buffer_float = GL_TRUE; - - if (!screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_CLAMPED)) { - st->clamp_vert_color_in_shader = TRUE; - } - - if (!screen->get_param(screen, PIPE_CAP_FRAGMENT_COLOR_CLAMPED)) { - st->clamp_frag_color_in_shader = TRUE; - } - - /* For drivers which cannot do color clamping, it's better to just - * disable ARB_color_buffer_float in the core profile, because - * the clamping is deprecated there anyway. */ - if (ctx->API == API_OPENGL_CORE && - (st->clamp_frag_color_in_shader || st->clamp_vert_color_in_shader)) { - st->clamp_vert_color_in_shader = GL_FALSE; - st->clamp_frag_color_in_shader = GL_FALSE; - ctx->Extensions.ARB_color_buffer_float = GL_FALSE; - } + extensions->ARB_color_buffer_float = GL_TRUE; } if (screen->fence_finish) { - ctx->Extensions.ARB_sync = GL_TRUE; + extensions->ARB_sync = GL_TRUE; } /* Maximum sample count. */ - for (i = 16; i > 0; --i) { - enum pipe_format pformat = st_choose_format(st, GL_RGBA, - GL_NONE, GL_NONE, - PIPE_TEXTURE_2D, i, - PIPE_BIND_RENDER_TARGET, FALSE); - if (pformat != PIPE_FORMAT_NONE) { - ctx->Const.MaxSamples = i; - ctx->Const.MaxColorTextureSamples = i; - break; - } + { + enum pipe_format color_formats[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_A8B8G8R8_UNORM, + }; + enum pipe_format depth_formats[] = { + PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_Z24X8_UNORM, + PIPE_FORMAT_X8Z24_UNORM, + PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_Z32_FLOAT + }; + enum pipe_format int_formats[] = { + PIPE_FORMAT_R8G8B8A8_SINT + }; + + consts->MaxSamples = + get_max_samples_for_formats(screen, Elements(color_formats), + color_formats, 16, + PIPE_BIND_RENDER_TARGET); + + consts->MaxColorTextureSamples = + get_max_samples_for_formats(screen, Elements(color_formats), + color_formats, consts->MaxSamples, + PIPE_BIND_SAMPLER_VIEW); + + consts->MaxDepthTextureSamples = + get_max_samples_for_formats(screen, Elements(depth_formats), + depth_formats, consts->MaxSamples, + PIPE_BIND_SAMPLER_VIEW); + + consts->MaxIntegerSamples = + get_max_samples_for_formats(screen, Elements(int_formats), + int_formats, consts->MaxSamples, + PIPE_BIND_SAMPLER_VIEW); } - for (i = ctx->Const.MaxSamples; i > 0; --i) { - enum pipe_format pformat = st_choose_format(st, GL_DEPTH_STENCIL, - GL_NONE, GL_NONE, - PIPE_TEXTURE_2D, i, - PIPE_BIND_DEPTH_STENCIL, FALSE); - if (pformat != PIPE_FORMAT_NONE) { - ctx->Const.MaxDepthTextureSamples = i; - break; - } - } - for (i = ctx->Const.MaxSamples; i > 0; --i) { - enum pipe_format pformat = st_choose_format(st, GL_RGBA_INTEGER, - GL_NONE, GL_NONE, - PIPE_TEXTURE_2D, i, - PIPE_BIND_RENDER_TARGET, FALSE); - if (pformat != PIPE_FORMAT_NONE) { - ctx->Const.MaxIntegerSamples = i; - break; - } - } - if (ctx->Const.MaxSamples == 1) { + if (consts->MaxSamples == 1) { /* one sample doesn't really make sense */ - ctx->Const.MaxSamples = 0; + consts->MaxSamples = 0; } - else if (ctx->Const.MaxSamples >= 2) { - ctx->Extensions.EXT_framebuffer_multisample = GL_TRUE; - ctx->Extensions.EXT_framebuffer_multisample_blit_scaled = GL_TRUE; + else if (consts->MaxSamples >= 2) { + extensions->EXT_framebuffer_multisample = GL_TRUE; + 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 (consts->MaxSamples == 0 && screen->get_param(screen, PIPE_CAP_FAKE_SW_MSAA)) { + consts->FakeSWMSAA = GL_TRUE; + extensions->EXT_framebuffer_multisample = GL_TRUE; + extensions->EXT_framebuffer_multisample_blit_scaled = GL_TRUE; + 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; + if (consts->MaxDualSourceDrawBuffers > 0 && + !options->disable_blend_func_extended) + extensions->ARB_blend_func_extended = GL_TRUE; - st->has_time_elapsed = - screen->get_param(screen, PIPE_CAP_QUERY_TIME_ELAPSED); - - if (st->has_time_elapsed || - ctx->Extensions.ARB_timer_query) { - ctx->Extensions.EXT_timer_query = GL_TRUE; + if (screen->get_param(screen, PIPE_CAP_QUERY_TIME_ELAPSED) || + extensions->ARB_timer_query) { + extensions->EXT_timer_query = GL_TRUE; } - if (ctx->Extensions.ARB_transform_feedback2 && - ctx->Extensions.ARB_draw_instanced) { - ctx->Extensions.ARB_transform_feedback_instanced = GL_TRUE; + if (extensions->ARB_transform_feedback2 && + extensions->ARB_draw_instanced) { + extensions->ARB_transform_feedback_instanced = GL_TRUE; } - if (st->options.force_glsl_extensions_warn) - ctx->Const.ForceGLSLExtensionsWarn = 1; + if (options->force_glsl_extensions_warn) + consts->ForceGLSLExtensionsWarn = 1; - if (st->options.disable_glsl_line_continuations) - ctx->Const.DisableGLSLLineContinuations = 1; + if (options->disable_glsl_line_continuations) + consts->DisableGLSLLineContinuations = 1; - if (st->options.allow_glsl_extension_directive_midshader) - ctx->Const.AllowGLSLExtensionDirectiveMidShader = GL_TRUE; + if (options->allow_glsl_extension_directive_midshader) + consts->AllowGLSLExtensionDirectiveMidShader = GL_TRUE; - ctx->Const.MinMapBufferAlignment = + consts->MinMapBufferAlignment = screen->get_param(screen, PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT); if (screen->get_param(screen, PIPE_CAP_TEXTURE_BUFFER_OBJECTS)) { - ctx->Extensions.ARB_texture_buffer_object = GL_TRUE; + extensions->ARB_texture_buffer_object = GL_TRUE; - ctx->Const.MaxTextureBufferSize = + consts->MaxTextureBufferSize = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE), (1u << 31) - 1); - ctx->Const.TextureBufferOffsetAlignment = + consts->TextureBufferOffsetAlignment = screen->get_param(screen, PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT); - if (ctx->Const.TextureBufferOffsetAlignment) - ctx->Extensions.ARB_texture_buffer_range = GL_TRUE; + if (consts->TextureBufferOffsetAlignment) + extensions->ARB_texture_buffer_range = GL_TRUE; - init_format_extensions(st, tbo_rgb32, Elements(tbo_rgb32), - PIPE_BUFFER, PIPE_BIND_SAMPLER_VIEW); + init_format_extensions(screen, extensions, tbo_rgb32, + Elements(tbo_rgb32), PIPE_BUFFER, + PIPE_BIND_SAMPLER_VIEW); } if (screen->get_param(screen, PIPE_CAP_MIXED_FRAMEBUFFER_SIZES)) { - ctx->Extensions.ARB_framebuffer_object = GL_TRUE; + extensions->ARB_framebuffer_object = GL_TRUE; } /* Unpacking a varying in the fragment shader costs 1 texture indirection. @@ -809,21 +836,49 @@ void st_init_extensions(struct st_context *st) /* We can't disable varying packing if transform feedback is available, * because transform feedback code assumes a packed varying layout. */ - if (!ctx->Extensions.EXT_transform_feedback) - ctx->Const.DisableVaryingPacking = GL_TRUE; + if (!extensions->EXT_transform_feedback) + consts->DisableVaryingPacking = GL_TRUE; } - if (ctx->API == API_OPENGL_CORE) { - ctx->Const.MaxViewports = screen->get_param(screen, PIPE_CAP_MAX_VIEWPORTS); - if (ctx->Const.MaxViewports >= 16) { - ctx->Const.ViewportBounds.Min = -16384.0; - ctx->Const.ViewportBounds.Max = 16384.0; - ctx->Extensions.ARB_viewport_array = GL_TRUE; - ctx->Extensions.ARB_fragment_layer_viewport = GL_TRUE; - if (ctx->Extensions.AMD_vertex_shader_layer) - ctx->Extensions.AMD_vertex_shader_viewport_index = GL_TRUE; + if (api == API_OPENGL_CORE) { + consts->MaxViewports = screen->get_param(screen, PIPE_CAP_MAX_VIEWPORTS); + if (consts->MaxViewports >= 16) { + consts->ViewportBounds.Min = -16384.0; + consts->ViewportBounds.Max = 16384.0; + extensions->ARB_viewport_array = GL_TRUE; + extensions->ARB_fragment_layer_viewport = GL_TRUE; + if (extensions->AMD_vertex_shader_layer) + extensions->AMD_vertex_shader_viewport_index = GL_TRUE; } } - if (ctx->Const.MaxProgramTextureGatherComponents > 0) - ctx->Extensions.ARB_texture_gather = GL_TRUE; + if (consts->MaxProgramTextureGatherComponents > 0) + extensions->ARB_texture_gather = GL_TRUE; + + /* GL_ARB_ES3_compatibility. + * + * Assume that ES3 is supported if GLSL 3.30 is supported. + * (OpenGL 3.3 is a requirement for that extension.) + */ + if (consts->GLSLVersion >= 330 && + /* Requirements for ETC2 emulation. */ + screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW) && + screen->is_format_supported(screen, PIPE_FORMAT_B8G8R8A8_SRGB, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW) && + screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW) && + screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW) && + screen->is_format_supported(screen, PIPE_FORMAT_R16_SNORM, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW) && + screen->is_format_supported(screen, PIPE_FORMAT_R16G16_SNORM, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW)) { + extensions->ARB_ES3_compatibility = GL_TRUE; + } } diff --git a/mesalib/src/mesa/state_tracker/st_extensions.h b/mesalib/src/mesa/state_tracker/st_extensions.h index d098ed074..8d2724d67 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.h +++ b/mesalib/src/mesa/state_tracker/st_extensions.h @@ -31,10 +31,18 @@ struct st_context; - -extern void st_init_limits(struct st_context *st); - -extern void st_init_extensions(struct st_context *st); +struct pipe_screen; + +extern void st_init_limits(struct pipe_screen *screen, + struct gl_constants *c, + struct gl_extensions *extensions); + +extern void st_init_extensions(struct pipe_screen *screen, + gl_api api, + struct gl_constants *consts, + struct gl_extensions *extensions, + struct st_config_options *options, + boolean has_lib_dxtc); #endif /* ST_EXTENSIONS_H */ diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 409079bd4..b5e03b0f8 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -54,7 +54,7 @@ * Translate Mesa format to Gallium format. */ enum pipe_format -st_mesa_format_to_pipe_format(mesa_format mesaFormat) +st_mesa_format_to_pipe_format(struct st_context *st, mesa_format mesaFormat) { switch (mesaFormat) { case MESA_FORMAT_A8B8G8R8_UNORM: @@ -323,8 +323,19 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat) case MESA_FORMAT_LA_LATC2_SNORM: return PIPE_FORMAT_LATC2_SNORM; + /* The destination RGBA format mustn't be changed, because it's also + * a destination format of the unpack/decompression function. */ case MESA_FORMAT_ETC1_RGB8: - return PIPE_FORMAT_ETC1_RGB8; + return st->has_etc1 ? PIPE_FORMAT_ETC1_RGB8 : PIPE_FORMAT_R8G8B8A8_UNORM; + + case MESA_FORMAT_BPTC_RGBA_UNORM: + return PIPE_FORMAT_BPTC_RGBA_UNORM; + case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM: + return PIPE_FORMAT_BPTC_SRGBA; + case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT: + return PIPE_FORMAT_BPTC_RGB_FLOAT; + case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT: + return PIPE_FORMAT_BPTC_RGB_UFLOAT; /* signed normalized formats */ case MESA_FORMAT_R_SNORM8: @@ -402,6 +413,26 @@ st_mesa_format_to_pipe_format(mesa_format mesaFormat) case MESA_FORMAT_B8G8R8X8_SRGB: return PIPE_FORMAT_B8G8R8X8_SRGB; + /* ETC2 formats are emulated as uncompressed ones. + * The destination formats mustn't be changed, because they are also + * destination formats of the unpack/decompression function. */ + case MESA_FORMAT_ETC2_RGB8: + case MESA_FORMAT_ETC2_RGBA8_EAC: + case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: + return PIPE_FORMAT_R8G8B8A8_UNORM; + case MESA_FORMAT_ETC2_SRGB8: + case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: + case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + return PIPE_FORMAT_B8G8R8A8_SRGB; + case MESA_FORMAT_ETC2_R11_EAC: + return PIPE_FORMAT_R16_UNORM; + case MESA_FORMAT_ETC2_RG11_EAC: + return PIPE_FORMAT_R16G16_UNORM; + case MESA_FORMAT_ETC2_SIGNED_R11_EAC: + return PIPE_FORMAT_R16_SNORM; + case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: + return PIPE_FORMAT_R16G16_SNORM; + default: return PIPE_FORMAT_NONE; } @@ -685,6 +716,15 @@ st_pipe_format_to_mesa_format(enum pipe_format format) case PIPE_FORMAT_ETC1_RGB8: return MESA_FORMAT_ETC1_RGB8; + case PIPE_FORMAT_BPTC_RGBA_UNORM: + return MESA_FORMAT_BPTC_RGBA_UNORM; + case PIPE_FORMAT_BPTC_SRGBA: + return MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM; + case PIPE_FORMAT_BPTC_RGB_FLOAT: + return MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT; + case PIPE_FORMAT_BPTC_RGB_UFLOAT: + return MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT; + /* signed normalized formats */ case PIPE_FORMAT_R8_SNORM: return MESA_FORMAT_R_SNORM8; @@ -775,13 +815,21 @@ st_pipe_format_to_mesa_format(enum pipe_format format) * Mesa formats to Gallium formats and back again. */ static void -test_format_conversion(void) +test_format_conversion(struct st_context *st) { GLuint i; /* test all Mesa formats */ for (i = 1; i < MESA_FORMAT_COUNT; i++) { - enum pipe_format pf = st_mesa_format_to_pipe_format(i); + enum pipe_format pf; + + /* ETC formats are translated differently, skip them. */ + if (_mesa_is_format_etc2(i)) + continue; + if (i == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1) + continue; + + pf = st_mesa_format_to_pipe_format(st, i); if (pf != PIPE_FORMAT_NONE) { mesa_format mf = st_pipe_format_to_mesa_format(pf); assert(mf == i); @@ -791,8 +839,13 @@ test_format_conversion(void) /* Test all Gallium formats */ for (i = 1; i < PIPE_FORMAT_COUNT; i++) { mesa_format mf = st_pipe_format_to_mesa_format(i); + + /* ETC formats are translated differently, skip them. */ + if (i == PIPE_FORMAT_ETC1_RGB8 && !st->has_etc1) + continue; + if (mf != MESA_FORMAT_NONE) { - enum pipe_format pf = st_mesa_format_to_pipe_format(mf); + enum pipe_format pf = st_mesa_format_to_pipe_format(st, mf); assert(pf == i); } } @@ -1238,6 +1291,24 @@ static const struct format_mapping format_map[] = { { PIPE_FORMAT_ETC1_RGB8, 0 } }, + /* BPTC */ + { + { GL_COMPRESSED_RGBA_BPTC_UNORM, 0 }, + { PIPE_FORMAT_BPTC_RGBA_UNORM, 0 }, + }, + { + { GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, 0 }, + { PIPE_FORMAT_BPTC_SRGBA, 0 }, + }, + { + { GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, 0 }, + { PIPE_FORMAT_BPTC_RGB_FLOAT, 0 }, + }, + { + { GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, 0 }, + { PIPE_FORMAT_BPTC_RGB_UFLOAT, 0 }, + }, + /* signed/unsigned integer formats. */ { @@ -1680,7 +1751,7 @@ st_choose_format(struct st_context *st, GLenum internalFormat, { static boolean firstCall = TRUE; if (firstCall) { - test_format_conversion(); + test_format_conversion(st); firstCall = FALSE; } } @@ -1746,9 +1817,10 @@ st_choose_renderbuffer_format(struct st_context *st, * If no format is supported, return PIPE_FORMAT_NONE. */ enum pipe_format -st_choose_matching_format(struct pipe_screen *screen, unsigned bind, +st_choose_matching_format(struct st_context *st, unsigned bind, GLenum format, GLenum type, GLboolean swapBytes) { + struct pipe_screen *screen = st->pipe->screen; mesa_format mesa_format; for (mesa_format = 1; mesa_format < MESA_FORMAT_COUNT; mesa_format++) { @@ -1764,7 +1836,8 @@ st_choose_matching_format(struct pipe_screen *screen, unsigned bind, if (_mesa_format_matches_format_and_type(mesa_format, format, type, swapBytes)) { - enum pipe_format format = st_mesa_format_to_pipe_format(mesa_format); + enum pipe_format format = + st_mesa_format_to_pipe_format(st, mesa_format); if (format && screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, @@ -1834,16 +1907,14 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target, * with the "format". */ if (iformat == baseFormat && iformat == basePackFormat) { - pFormat = st_choose_matching_format(st->pipe->screen, bindings, - format, type, + pFormat = st_choose_matching_format(st, bindings, format, type, ctx->Unpack.SwapBytes); if (pFormat != PIPE_FORMAT_NONE) return st_pipe_format_to_mesa_format(pFormat); /* try choosing format again, this time without render target bindings */ - pFormat = st_choose_matching_format(st->pipe->screen, - PIPE_BIND_SAMPLER_VIEW, + pFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW, format, type, ctx->Unpack.SwapBytes); if (pFormat != PIPE_FORMAT_NONE) diff --git a/mesalib/src/mesa/state_tracker/st_format.h b/mesalib/src/mesa/state_tracker/st_format.h index ce1e2306d..90e00e8eb 100644 --- a/mesalib/src/mesa/state_tracker/st_format.h +++ b/mesalib/src/mesa/state_tracker/st_format.h @@ -41,7 +41,7 @@ struct pipe_screen; extern enum pipe_format -st_mesa_format_to_pipe_format(mesa_format mesaFormat); +st_mesa_format_to_pipe_format(struct st_context *st, mesa_format mesaFormat); extern mesa_format st_pipe_format_to_mesa_format(enum pipe_format pipeFormat); @@ -58,7 +58,7 @@ st_choose_renderbuffer_format(struct st_context *st, GLenum internalFormat, unsigned sample_count); extern enum pipe_format -st_choose_matching_format(struct pipe_screen *screen, unsigned bind, +st_choose_matching_format(struct st_context *st, unsigned bind, GLenum format, GLenum type, GLboolean swapBytes); extern mesa_format 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 0290553c6..84bdc4f06 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -245,7 +245,8 @@ public: ir_instruction *ir; GLboolean cond_update; bool saturate; - int sampler; /**< sampler index */ + st_src_reg sampler; /**< sampler register */ + int sampler_array_size; /**< 1-based size of sampler array, 1 if not array */ int tex_target; /**< One of TEXTURE_*_INDEX */ GLboolean tex_shadow; @@ -476,6 +477,7 @@ static st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_T static st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 0); static st_dst_reg address_reg2 = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 1); +static st_dst_reg sampler_reladdr = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 2); static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); @@ -1460,9 +1462,15 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) break; case ir_unop_dFdx: + case ir_unop_dFdx_coarse: emit(ir, TGSI_OPCODE_DDX, result_dst, op[0]); break; + case ir_unop_dFdx_fine: + emit(ir, TGSI_OPCODE_DDX_FINE, result_dst, op[0]); + break; case ir_unop_dFdy: + case ir_unop_dFdy_coarse: + case ir_unop_dFdy_fine: { /* The X component contains 1 or -1 depending on whether the framebuffer * is a FBO or the window system buffer, respectively. @@ -1483,7 +1491,8 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) st_src_reg temp = get_temp(glsl_type::vec4_type); emit(ir, TGSI_OPCODE_MUL, st_dst_reg(temp), transform_y, op[0]); - emit(ir, TGSI_OPCODE_DDY, result_dst, temp); + emit(ir, ir->operation == ir_unop_dFdy_fine ? + TGSI_OPCODE_DDY_FINE : TGSI_OPCODE_DDY, result_dst, temp); break; } @@ -2799,6 +2808,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) glsl_to_tgsi_instruction *inst = NULL; unsigned opcode = TGSI_OPCODE_NOP; const glsl_type *sampler_type = ir->sampler->type; + ir_rvalue *sampler_index = + _mesa_get_sampler_array_nonconst_index(ir->sampler); bool is_cube_array = false; unsigned i; @@ -3016,6 +3027,11 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) coord_dst.writemask = WRITEMASK_XYZW; } + if (sampler_index) { + sampler_index->accept(this); + emit_arl(ir, sampler_reladdr, this->result); + } + if (opcode == TGSI_OPCODE_TXD) inst = emit(ir, opcode, result_dst, coord, dx, dy); else if (opcode == TGSI_OPCODE_TXQ) { @@ -3045,9 +3061,17 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) if (ir->shadow_comparitor) inst->tex_shadow = GL_TRUE; - inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, - this->shader_program, - this->prog); + inst->sampler.index = _mesa_get_sampler_uniform_value(ir->sampler, + this->shader_program, + this->prog); + if (sampler_index) { + inst->sampler.reladdr = ralloc(mem_ctx, st_src_reg); + memcpy(inst->sampler.reladdr, &sampler_reladdr, sizeof(sampler_reladdr)); + inst->sampler_array_size = + ir->sampler->as_dereference_array()->array->type->array_size(); + } else { + inst->sampler_array_size = 1; + } if (ir->offset) { for (i = 0; i < MAX_GLSL_TEXTURE_OFFSET && offset[i].file != PROGRAM_UNDEFINED; i++) @@ -3215,10 +3239,12 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog) foreach_in_list(glsl_to_tgsi_instruction, inst, &v->instructions) { if (is_tex_instruction(inst->op)) { - v->samplers_used |= 1 << inst->sampler; + for (int i = 0; i < inst->sampler_array_size; i++) { + v->samplers_used |= 1 << (inst->sampler.index + i); - if (inst->tex_shadow) { - prog->ShadowSamplers |= 1 << inst->sampler; + if (inst->tex_shadow) { + prog->ShadowSamplers |= 1 << (inst->sampler.index + i); + } } } } @@ -3952,7 +3978,7 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp, src0 = v->get_temp(glsl_type::vec4_type); dst0 = st_dst_reg(src0); inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord); - inst->sampler = 0; + inst->sampler_array_size = 1; inst->tex_target = TEXTURE_2D_INDEX; prog->InputsRead |= VARYING_BIT_TEX0; @@ -3991,14 +4017,16 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp, /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */ temp_dst.writemask = WRITEMASK_XY; /* write R,G */ inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0); - inst->sampler = 1; + inst->sampler.index = 1; + inst->sampler_array_size = 1; inst->tex_target = TEXTURE_2D_INDEX; /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */ src0.swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W); temp_dst.writemask = WRITEMASK_ZW; /* write B,A */ inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0); - inst->sampler = 1; + inst->sampler.index = 1; + inst->sampler_array_size = 1; inst->tex_target = TEXTURE_2D_INDEX; prog->SamplersUsed |= (1 << 1); /* mark sampler 1 as used */ @@ -4079,7 +4107,8 @@ get_bitmap_visitor(struct st_fragment_program *fp, src0 = v->get_temp(glsl_type::vec4_type); dst0 = st_dst_reg(src0); inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord); - inst->sampler = samplerIndex; + inst->sampler.index = samplerIndex; + inst->sampler_array_size = 1; inst->tex_target = TEXTURE_2D_INDEX; prog->InputsRead |= VARYING_BIT_TEX0; @@ -4135,7 +4164,7 @@ struct st_translate { struct ureg_src *immediates; struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS]; struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS]; - struct ureg_dst address[2]; + struct ureg_dst address[3]; struct ureg_src samplers[PIPE_MAX_SAMPLERS]; struct ureg_src systemValues[SYSTEM_VALUE_MAX]; struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET]; @@ -4546,7 +4575,11 @@ compile_tgsi_instruction(struct st_translate *t, case TGSI_OPCODE_TXL2: case TGSI_OPCODE_TG4: case TGSI_OPCODE_LODQ: - src[num_src++] = t->samplers[inst->sampler]; + src[num_src] = t->samplers[inst->sampler.index]; + if (inst->sampler.reladdr) + src[num_src] = + ureg_src_indirect(src[num_src], ureg_src(t->address[2])); + num_src++; for (i = 0; i < inst->tex_offset_num_offset; i++) { texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i], i); } @@ -4977,10 +5010,9 @@ st_translate_program( /* Declare address register. */ if (program->num_address_regs > 0) { - assert(program->num_address_regs <= 2); - t->address[0] = ureg_DECL_address(ureg); - if (program->num_address_regs == 2) - t->address[1] = ureg_DECL_address(ureg); + assert(program->num_address_regs <= 3); + for (int i = 0; i < program->num_address_regs; i++) + t->address[i] = ureg_DECL_address(ureg); } /* Declare misc input registers @@ -5176,7 +5208,7 @@ get_mesa_program(struct gl_context *ctx, GLenum target = _mesa_shader_stage_to_program(shader->Stage); bool progress; struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader->Type)]; + &ctx->Const.ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader->Type)]; struct pipe_screen *pscreen = ctx->st->pipe->screen; unsigned ptarget = shader_stage_to_ptarget(shader->Stage); @@ -5365,7 +5397,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) bool progress; exec_list *ir = prog->_LinkedShaders[i]->ir; const struct gl_shader_compiler_options *options = - &ctx->ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(prog->_LinkedShaders[i]->Type)]; + &ctx->Const.ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(prog->_LinkedShaders[i]->Type)]; /* If there are forms of indirect addressing that the driver * cannot handle, perform the lowering pass. diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index 706af7fd1..7bc33268e 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -26,6 +26,7 @@ */ #include "main/mtypes.h" +#include "main/extensions.h" #include "main/context.h" #include "main/texobj.h" #include "main/teximage.h" @@ -38,6 +39,7 @@ #include "st_texture.h" #include "st_context.h" +#include "st_extensions.h" #include "st_format.h" #include "st_cb_fbo.h" #include "st_cb_flush.h" @@ -910,6 +912,41 @@ st_manager_add_color_renderbuffer(struct st_context *st, return TRUE; } +static unsigned get_version(struct pipe_screen *screen, + struct st_config_options *options, gl_api api) +{ + struct gl_constants consts = {0}; + struct gl_extensions extensions = {0}; + GLuint version; + + if ((api == API_OPENGL_COMPAT || api == API_OPENGL_CORE) && + _mesa_override_gl_version_contextless(&consts, &api, &version)) { + return version; + } + + _mesa_init_constants(&consts, api); + _mesa_init_extensions(&extensions); + + st_init_limits(screen, &consts, &extensions); + st_init_extensions(screen, api, &consts, &extensions, options, GL_TRUE); + + return _mesa_get_version(&extensions, &consts, api); +} + +static void +st_api_query_versions(struct st_api *stapi, struct st_manager *sm, + struct st_config_options *options, + int *gl_core_version, + int *gl_compat_version, + int *gl_es1_version, + int *gl_es2_version) +{ + *gl_core_version = get_version(sm->screen, options, API_OPENGL_CORE); + *gl_compat_version = get_version(sm->screen, options, API_OPENGL_COMPAT); + *gl_es1_version = get_version(sm->screen, options, API_OPENGLES); + *gl_es2_version = get_version(sm->screen, options, API_OPENGLES2); +} + static const struct st_api st_gl_api = { "Mesa " PACKAGE_VERSION, ST_API_OPENGL, @@ -920,6 +957,7 @@ static const struct st_api st_gl_api = { 0, ST_API_FEATURE_MS_VISUALS_MASK, st_api_destroy, + st_api_query_versions, st_api_get_proc_address, st_api_create_context, st_api_make_current, diff --git a/mesalib/src/mesa/state_tracker/st_texture.c b/mesalib/src/mesa/state_tracker/st_texture.c index c14882142..af9b7675f 100644 --- a/mesalib/src/mesa/state_tracker/st_texture.c +++ b/mesalib/src/mesa/state_tracker/st_texture.c @@ -197,7 +197,8 @@ st_gl_texture_dims_to_pipe_dims(GLenum texture, * Check if a texture image can be pulled into a unified mipmap texture. */ GLboolean -st_texture_match_image(const struct pipe_resource *pt, +st_texture_match_image(struct st_context *st, + const struct pipe_resource *pt, const struct gl_texture_image *image) { GLuint ptWidth, ptHeight, ptDepth, ptLayers; @@ -209,7 +210,7 @@ st_texture_match_image(const struct pipe_resource *pt, /* Check if this image's format matches the established texture's format. */ - if (st_mesa_format_to_pipe_format(image->TexFormat) != pt->format) + if (st_mesa_format_to_pipe_format(st, image->TexFormat) != pt->format) return GL_FALSE; st_gl_texture_dims_to_pipe_dims(image->TexObject->Target, @@ -269,14 +270,15 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, unsigned new_size = z + 1; stImage->transfer = realloc(stImage->transfer, - new_size * sizeof(void*)); + new_size * sizeof(struct st_texture_image_transfer)); memset(&stImage->transfer[stImage->num_transfers], 0, - (new_size - stImage->num_transfers) * sizeof(void*)); + (new_size - stImage->num_transfers) * + sizeof(struct st_texture_image_transfer)); stImage->num_transfers = new_size; } - assert(!stImage->transfer[z]); - stImage->transfer[z] = *transfer; + assert(!stImage->transfer[z].transfer); + stImage->transfer[z].transfer = *transfer; } return map; } @@ -288,7 +290,7 @@ st_texture_image_unmap(struct st_context *st, { struct pipe_context *pipe = st->pipe; struct pipe_transfer **transfer = - &stImage->transfer[slice + stImage->base.Face]; + &stImage->transfer[slice + stImage->base.Face].transfer; DBG("%s\n", __FUNCTION__); diff --git a/mesalib/src/mesa/state_tracker/st_texture.h b/mesalib/src/mesa/state_tracker/st_texture.h index affb56812..ce1cf8b0a 100644 --- a/mesalib/src/mesa/state_tracker/st_texture.h +++ b/mesalib/src/mesa/state_tracker/st_texture.h @@ -38,6 +38,16 @@ struct pipe_resource; +struct st_texture_image_transfer { + struct pipe_transfer *transfer; + + /* For ETC fallback. */ + GLubyte *temp_data; /**< Temporary ETC texture storage. */ + unsigned temp_stride; /**< Stride of the ETC texture storage. */ + GLubyte *map; /**< Saved map pointer of the uncompressed transfer. */ +}; + + /** * Subclass of gl_texure_image. */ @@ -59,7 +69,7 @@ struct st_texture_image /* List of transfers, allocated on demand. * transfer[layer] is a mapping for that layer. */ - struct pipe_transfer **transfer; + struct st_texture_image_transfer *transfer; unsigned num_transfers; }; @@ -189,7 +199,8 @@ st_gl_texture_dims_to_pipe_dims(GLenum texture, /* Check if an image fits into an existing texture object. */ extern GLboolean -st_texture_match_image(const struct pipe_resource *pt, +st_texture_match_image(struct st_context *st, + const struct pipe_resource *pt, const struct gl_texture_image *image); /* Return a pointer to an image within a texture. Return image stride as |