From: Dave Airlie <airl...@redhat.com> This adds support to the mesa state tracker for ARB_texture_multisample.
hardware doesn't seem to use a different texture instructions, so I don't think we need to create one for TGSI at this time. Thanks to Marek for fixes to sample number picking. Signed-off-by: Dave Airlie <airl...@redhat.com> --- src/mesa/state_tracker/st_atom_framebuffer.c | 1 + src/mesa/state_tracker/st_atom_msaa.c | 2 ++ src/mesa/state_tracker/st_cb_bitmap.c | 4 +-- src/mesa/state_tracker/st_cb_drawpixels.c | 2 +- src/mesa/state_tracker/st_cb_fbo.c | 2 +- src/mesa/state_tracker/st_cb_texture.c | 41 ++++++++++++++++++++++++---- src/mesa/state_tracker/st_extensions.c | 7 +++++ src/mesa/state_tracker/st_gen_mipmap.c | 1 + src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 17 ++++++++++-- src/mesa/state_tracker/st_mesa_to_tgsi.c | 2 ++ src/mesa/state_tracker/st_texture.c | 8 +++++- src/mesa/state_tracker/st_texture.h | 1 + 12 files changed, 74 insertions(+), 14 deletions(-) diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 3df8691..c752640 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -59,6 +59,7 @@ update_renderbuffer_surface(struct st_context *st, enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : util_format_linear(resource->format); if (!strb->surface || + strb->surface->texture->nr_samples != strb->Base.NumSamples || strb->surface->format != format || strb->surface->texture != resource || strb->surface->width != rtt_width || diff --git a/src/mesa/state_tracker/st_atom_msaa.c b/src/mesa/state_tracker/st_atom_msaa.c index 9baa4fc..b749a17 100644 --- a/src/mesa/state_tracker/st_atom_msaa.c +++ b/src/mesa/state_tracker/st_atom_msaa.c @@ -63,6 +63,8 @@ static void update_sample_mask( struct st_context *st ) sample_mask = ~sample_mask; } /* TODO merge with app-supplied sample mask */ + if (st->ctx->Multisample.SampleMask) + sample_mask = st->ctx->Multisample.SampleMaskValue; } /* mask off unused bits or don't care? */ diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 36fffe9..d7a95e2 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -299,7 +299,7 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height, * Create texture to hold bitmap pattern. */ pt = st_texture_create(st, st->internal_target, st->bitmap.tex_format, - 0, width, height, 1, 1, + 0, width, height, 1, 1, 0, PIPE_BIND_SAMPLER_VIEW); if (!pt) { _mesa_unmap_pbo_source(ctx, unpack); @@ -568,7 +568,7 @@ reset_cache(struct st_context *st) cache->texture = st_texture_create(st, PIPE_TEXTURE_2D, st->bitmap.tex_format, 0, BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT, - 1, 1, + 1, 1, 0, PIPE_BIND_SAMPLER_VIEW); } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index e282bf9..e609eb5 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -463,7 +463,7 @@ alloc_texture(struct st_context *st, GLsizei width, GLsizei height, struct pipe_resource *pt; pt = st_texture_create(st, st->internal_target, texFormat, 0, - width, height, 1, 1, PIPE_BIND_SAMPLER_VIEW); + width, height, 1, 1, 0, PIPE_BIND_SAMPLER_VIEW); return pt; } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 72bc960..cf3e27f 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -430,7 +430,7 @@ st_render_texture(struct gl_context *ctx, strb->rtt_level = att->TextureLevel; strb->rtt_face = att->CubeMapFace; strb->rtt_slice = att->Zoffset; - + rb->NumSamples = texImage->NumSamples; rb->Width = texImage->Width2; rb->Height = texImage->Height2; rb->_BaseFormat = texImage->_BaseFormat; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index c922a31..385bac6 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -78,6 +78,8 @@ gl_target_to_pipe(GLenum target) case GL_TEXTURE_2D: case GL_PROXY_TEXTURE_2D: case GL_TEXTURE_EXTERNAL_OES: + case GL_TEXTURE_2D_MULTISAMPLE: + case GL_PROXY_TEXTURE_2D_MULTISAMPLE: return PIPE_TEXTURE_2D; case GL_TEXTURE_RECTANGLE_NV: case GL_PROXY_TEXTURE_RECTANGLE_NV: @@ -99,6 +101,8 @@ gl_target_to_pipe(GLenum target) return PIPE_TEXTURE_1D_ARRAY; case GL_TEXTURE_2D_ARRAY_EXT: case GL_PROXY_TEXTURE_2D_ARRAY_EXT: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: return PIPE_TEXTURE_2D_ARRAY; case GL_TEXTURE_BUFFER: return PIPE_BUFFER; @@ -408,7 +412,7 @@ guess_and_alloc_texture(struct st_context *st, ptWidth, ptHeight, ptDepth, - ptLayers, + ptLayers, 0, bindings); stObj->lastLevel = lastLevel; @@ -496,7 +500,7 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, ptWidth, ptHeight, ptDepth, - ptLayers, + ptLayers, 0, bindings); return stImage->pt != NULL; } @@ -1484,7 +1488,7 @@ st_finalize_texture(struct gl_context *ctx, GLuint face; struct st_texture_image *firstImage; enum pipe_format firstImageFormat; - GLuint ptWidth, ptHeight, ptDepth, ptLayers; + GLuint ptWidth, ptHeight, ptDepth, ptLayers, ptNumSamples; if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) { /* The texture is complete and we know exactly how many mipmap levels @@ -1548,6 +1552,7 @@ st_finalize_texture(struct gl_context *ctx, /* convert GL dims to Gallium dims */ st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth, &ptWidth, &ptHeight, &ptDepth, &ptLayers); + ptNumSamples = firstImage->base.NumSamples; } /* If we already have a gallium texture, check that it matches the texture @@ -1560,6 +1565,7 @@ st_finalize_texture(struct gl_context *ctx, stObj->pt->width0 != ptWidth || stObj->pt->height0 != ptHeight || stObj->pt->depth0 != ptDepth || + stObj->pt->nr_samples != ptNumSamples || stObj->pt->array_size != ptLayers) { /* The gallium texture does not match the Mesa texture so delete the @@ -1583,7 +1589,7 @@ st_finalize_texture(struct gl_context *ctx, ptWidth, ptHeight, ptDepth, - ptLayers, + ptLayers, ptNumSamples, bindings); if (!stObj->pt) { @@ -1629,11 +1635,14 @@ st_AllocTextureStorage(struct gl_context *ctx, GLsizei height, GLsizei depth) { const GLuint numFaces = _mesa_num_tex_faces(texObj->Target); + struct gl_texture_image *texImage = texObj->Image[0][0]; struct st_context *st = st_context(ctx); struct st_texture_object *stObj = st_texture_object(texObj); + struct pipe_screen *screen = st->pipe->screen; GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings; enum pipe_format fmt; GLint level; + int num_samples = texImage->NumSamples; assert(levels > 0); @@ -1643,10 +1652,30 @@ st_AllocTextureStorage(struct gl_context *ctx, stObj->depth0 = depth; stObj->lastLevel = levels - 1; - fmt = st_mesa_format_to_pipe_format(texObj->Image[0][0]->TexFormat); + fmt = st_mesa_format_to_pipe_format(texImage->TexFormat); bindings = default_bindings(st, fmt); + /* Raise the sample count if the requested one is unsupported. */ + if (num_samples > 1) { + boolean found = FALSE; + + for (; num_samples <= ctx->Const.MaxSamples; num_samples++) { + if (screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, + num_samples, + PIPE_BIND_SAMPLER_VIEW)) { + /* Update the sample count in gl_texture_image as well. */ + texImage->NumSamples = num_samples; + found = TRUE; + break; + } + } + + if (!found) { + return GL_FALSE; + } + } + st_gl_texture_dims_to_pipe_dims(texObj->Target, width, height, depth, &ptWidth, &ptHeight, &ptDepth, &ptLayers); @@ -1658,7 +1687,7 @@ st_AllocTextureStorage(struct gl_context *ctx, ptWidth, ptHeight, ptDepth, - ptLayers, + ptLayers, num_samples, bindings); if (!stObj->pt) return GL_FALSE; diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 11db9d3..9526c41 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -651,6 +651,9 @@ void st_init_extensions(struct st_context *st) PIPE_TEXTURE_2D, i, PIPE_BIND_RENDER_TARGET)) { ctx->Const.MaxSamples = i; + ctx->Const.MaxColorTextureSamples = i; + ctx->Const.MaxDepthTextureSamples = i; + ctx->Const.MaxIntegerSamples = i; break; } } @@ -712,4 +715,8 @@ void st_init_extensions(struct st_context *st) if (!ctx->Extensions.EXT_transform_feedback) ctx->Const.DisableVaryingPacking = GL_TRUE; } + + if (screen->get_param(screen, PIPE_CAP_TEXTURE_MULTISAMPLE)) + ctx->Extensions.ARB_texture_multisample = GL_TRUE; + } diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 8ce2e06..e5512af 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -172,6 +172,7 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, oldTex->height0, oldTex->depth0, oldTex->array_size, + 0, oldTex->bind); /* This will copy the old texture's base image into the new texture diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index c41b583..2f69301 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -2674,7 +2674,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) void glsl_to_tgsi_visitor::visit(ir_texture *ir) { - st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy, offset; + st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy, offset, sample_index; st_dst_reg result_dst, coord_dst, cube_sc_dst; glsl_to_tgsi_instruction *inst = NULL; unsigned opcode = TGSI_OPCODE_NOP; @@ -2697,6 +2697,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) */ coord = get_temp(glsl_type::vec4_type); coord_dst = st_dst_reg(coord); + coord_dst.writemask = (1 << ir->coordinate->type->vector_elements) - 1; emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); } @@ -2747,7 +2748,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) } break; case ir_txf_ms: - assert(!"Unexpected ir_txf_ms opcode"); + opcode = TGSI_OPCODE_TXF; + ir->lod_info.sample_index->accept(this); + sample_index = this->result; break; } @@ -2831,7 +2834,11 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) } } - if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB || + if (ir->op == ir_txf_ms) { + coord_dst.writemask = WRITEMASK_W; + emit(ir, TGSI_OPCODE_MOV, coord_dst, sample_index); + coord_dst.writemask = WRITEMASK_XYZW; + } else if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB || opcode == TGSI_OPCODE_TXF) { /* TGSI stores LOD or LOD bias in the last channel of the coords. */ coord_dst.writemask = WRITEMASK_W; @@ -2893,6 +2900,10 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) case GLSL_SAMPLER_DIM_EXTERNAL: inst->tex_target = TEXTURE_EXTERNAL_INDEX; break; + case GLSL_SAMPLER_DIM_MS: + inst->tex_target = (sampler_type->sampler_array) + ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX : TEXTURE_2D_MULTISAMPLE_INDEX; + break; default: assert(!"Should not get here."); } diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index e326bcc..b07e37f 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -269,6 +269,8 @@ st_translate_texture_target( GLuint textarget, } switch( textarget ) { + case TEXTURE_2D_MULTISAMPLE_INDEX: return TGSI_TEXTURE_2D_MSAA; + case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: return TGSI_TEXTURE_2D_ARRAY_MSAA; case TEXTURE_BUFFER_INDEX: return TGSI_TEXTURE_BUFFER; case TEXTURE_1D_INDEX: return TGSI_TEXTURE_1D; case TEXTURE_2D_INDEX: return TGSI_TEXTURE_2D; diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index ed37098..9a27182 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -60,6 +60,7 @@ st_texture_create(struct st_context *st, GLuint height0, GLuint depth0, GLuint layers, + GLuint nr_samples, GLuint bind ) { struct pipe_resource pt, *newtex; @@ -90,6 +91,7 @@ st_texture_create(struct st_context *st, pt.usage = PIPE_USAGE_DEFAULT; pt.bind = bind; pt.flags = 0; + pt.nr_samples = nr_samples; newtex = screen->resource_create(screen, &pt); @@ -138,6 +140,8 @@ st_gl_texture_dims_to_pipe_dims(GLenum texture, case GL_TEXTURE_RECTANGLE: case GL_PROXY_TEXTURE_RECTANGLE: case GL_TEXTURE_EXTERNAL_OES: + case GL_PROXY_TEXTURE_2D_MULTISAMPLE: + case GL_TEXTURE_2D_MULTISAMPLE: assert(depthIn == 1); *widthOut = widthIn; *heightOut = heightIn; @@ -159,7 +163,9 @@ st_gl_texture_dims_to_pipe_dims(GLenum texture, *layersOut = 6; break; case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: case GL_PROXY_TEXTURE_2D_ARRAY: + case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: *widthOut = widthIn; *heightOut = heightIn; *depthOut = 1; @@ -402,7 +408,7 @@ st_create_color_map_texture(struct gl_context *ctx) /* create texture for color map/table */ pt = st_texture_create(st, PIPE_TEXTURE_2D, format, 0, - texSize, texSize, 1, 1, PIPE_BIND_SAMPLER_VIEW); + texSize, texSize, 1, 1, 0, PIPE_BIND_SAMPLER_VIEW); return pt; } diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 8a70100..da899c9 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -153,6 +153,7 @@ st_texture_create(struct st_context *st, GLuint height0, GLuint depth0, GLuint layers, + GLuint nr_samples, GLuint tex_usage ); -- 1.8.1.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev