X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fcommon%2Fmeta.c;h=485128696c5ae476f2ca7f4ce7a2c610210c5520;hb=89b1f5d6ac669343b1ee00f288e2ee71eb15dbe2;hp=606b604bcfbf359b4bbf265ffde8798197ba3588;hpb=1e0da6233be6e5fb0143615d5e3d3642ddb7964f;p=mesa.git diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 606b604bcfb..485128696c5 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -101,18 +101,18 @@ static void meta_decompress_cleanup(struct decompress_state *decompress); static void meta_drawpix_cleanup(struct drawpix_state *drawpix); void -_mesa_meta_bind_fbo_image(GLenum attachment, +_mesa_meta_bind_fbo_image(GLenum fboTarget, GLenum attachment, struct gl_texture_image *texImage, GLuint layer) { struct gl_texture_object *texObj = texImage->TexObject; int level = texImage->Level; - GLenum target = texObj->Target; + GLenum texTarget = texObj->Target; - switch (target) { + switch (texTarget) { case GL_TEXTURE_1D: - _mesa_FramebufferTexture1D(GL_FRAMEBUFFER, + _mesa_FramebufferTexture1D(fboTarget, attachment, - target, + texTarget, texObj->Name, level); break; @@ -121,19 +121,19 @@ _mesa_meta_bind_fbo_image(GLenum attachment, case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_TEXTURE_3D: - _mesa_FramebufferTextureLayer(GL_FRAMEBUFFER, + _mesa_FramebufferTextureLayer(fboTarget, attachment, texObj->Name, level, layer); break; default: /* 2D / cube */ - if (target == GL_TEXTURE_CUBE_MAP) - target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face; + if (texTarget == GL_TEXTURE_CUBE_MAP) + texTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face; - _mesa_FramebufferTexture2D(GL_FRAMEBUFFER, + _mesa_FramebufferTexture2D(fboTarget, attachment, - target, + texTarget, texObj->Name, level); } @@ -1527,12 +1527,12 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) { const char *vs_source = "#extension GL_AMD_vertex_shader_layer : enable\n" + "#extension GL_ARB_draw_instanced : enable\n" "attribute vec4 position;\n" - "uniform int layer;\n" "void main()\n" "{\n" "#ifdef GL_AMD_vertex_shader_layer\n" - " gl_Layer = layer;\n" + " gl_Layer = gl_InstanceID;\n" "#endif\n" " gl_Position = position;\n" "}\n"; @@ -1568,7 +1568,6 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) _mesa_LinkProgram(clear->ShaderProg); clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg, "color"); - clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg, "layer"); has_integer_textures = _mesa_is_gles3(ctx) || (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130); @@ -1579,12 +1578,12 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) ralloc_asprintf(shader_source_mem_ctx, "#version 130\n" "#extension GL_AMD_vertex_shader_layer : enable\n" + "#extension GL_ARB_draw_instanced : enable\n" "in vec4 position;\n" - "uniform int layer;\n" "void main()\n" "{\n" "#ifdef GL_AMD_vertex_shader_layer\n" - " gl_Layer = layer;\n" + " gl_Layer = gl_InstanceID;\n" "#endif\n" " gl_Position = position;\n" "}\n"); @@ -1623,8 +1622,6 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) clear->IntegerColorLocation = _mesa_GetUniformLocation(clear->IntegerShaderProg, "color"); - clear->IntegerLayerLocation = - _mesa_GetUniformLocation(clear->IntegerShaderProg, "layer"); } } @@ -1653,8 +1650,8 @@ meta_glsl_clear_cleanup(struct clear_state *clear) * Since the bitfield has no associated order, the assignment of draw buffer * indices to color attachment indices is rather arbitrary. */ -static void -drawbuffers_from_bitfield(GLbitfield bits) +void +_mesa_meta_drawbuffers_from_bitfield(GLbitfield bits) { GLenum enums[MAX_DRAW_BUFFERS]; int i = 0; @@ -1767,7 +1764,7 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl) /* GL_COLOR_BUFFER_BIT */ if (buffers & BUFFER_BITS_COLOR) { /* Only draw to the buffers we were asked to clear. */ - drawbuffers_from_bitfield(buffers & BUFFER_BITS_COLOR); + _mesa_meta_drawbuffers_from_bitfield(buffers & BUFFER_BITS_COLOR); /* leave colormask state as-is */ @@ -1832,15 +1829,7 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl) /* draw quad(s) */ if (fb->MaxNumLayers > 0) { - unsigned layer; - assert(glsl && clear->LayerLocation != -1); - for (layer = 0; layer < fb->MaxNumLayers; layer++) { - if (fb->_IntegerColor) - _mesa_Uniform1i(clear->IntegerLayerLocation, layer); - else - _mesa_Uniform1i(clear->LayerLocation, layer); - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); - } + _mesa_DrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, fb->MaxNumLayers); } else { _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -2732,9 +2721,9 @@ _mesa_meta_blit_shader_table_cleanup(struct blit_shader_table *table) static GLenum get_temp_image_type(struct gl_context *ctx, mesa_format format) { - GLenum baseFormat; - - baseFormat = _mesa_get_format_base_format(format); + const GLenum baseFormat = _mesa_get_format_base_format(format); + const GLenum datatype = _mesa_get_format_datatype(format); + const GLint format_red_bits = _mesa_get_format_bits(format, GL_RED_BITS); switch (baseFormat) { case GL_RGBA: @@ -2745,30 +2734,24 @@ get_temp_image_type(struct gl_context *ctx, mesa_format format) case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: case GL_INTENSITY: - if (ctx->DrawBuffer->Visual.redBits <= 8) { + if (datatype == GL_INT || datatype == GL_UNSIGNED_INT) { + return datatype; + } else if (format_red_bits <= 8) { return GL_UNSIGNED_BYTE; - } else if (ctx->DrawBuffer->Visual.redBits <= 16) { + } else if (format_red_bits <= 16) { return GL_UNSIGNED_SHORT; - } else { - GLenum datatype = _mesa_get_format_datatype(format); - if (datatype == GL_INT || datatype == GL_UNSIGNED_INT) - return datatype; - return GL_FLOAT; } - case GL_DEPTH_COMPONENT: { - GLenum datatype = _mesa_get_format_datatype(format); + return GL_FLOAT; + case GL_DEPTH_COMPONENT: if (datatype == GL_FLOAT) return GL_FLOAT; else return GL_UNSIGNED_INT; - } - case GL_DEPTH_STENCIL: { - GLenum datatype = _mesa_get_format_datatype(format); + case GL_DEPTH_STENCIL: if (datatype == GL_FLOAT) return GL_FLOAT_32_UNSIGNED_INT_24_8_REV; else return GL_UNSIGNED_INT_24_8; - } default: _mesa_problem(ctx, "Unexpected format %d in get_temp_image_type()", baseFormat); @@ -2808,17 +2791,20 @@ copytexsubimage_using_blit_framebuffer(struct gl_context *ctx, GLuint dims, if (rb->_BaseFormat == GL_DEPTH_STENCIL || rb->_BaseFormat == GL_DEPTH_COMPONENT) { - _mesa_meta_bind_fbo_image(GL_DEPTH_ATTACHMENT, texImage, zoffset); + _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + texImage, zoffset); mask = GL_DEPTH_BUFFER_BIT; if (rb->_BaseFormat == GL_DEPTH_STENCIL && texImage->_BaseFormat == GL_DEPTH_STENCIL) { - _mesa_meta_bind_fbo_image(GL_STENCIL_ATTACHMENT, texImage, zoffset); + _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + texImage, zoffset); mask |= GL_STENCIL_BUFFER_BIT; } _mesa_DrawBuffer(GL_NONE); } else { - _mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, texImage, zoffset); + _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + texImage, zoffset); mask = GL_COLOR_BUFFER_BIT; _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0); } @@ -2946,14 +2932,22 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, free(buf); } +static void +meta_decompress_fbo_cleanup(struct decompress_fbo_state *decompress_fbo) +{ + if (decompress_fbo->FBO != 0) { + _mesa_DeleteFramebuffers(1, &decompress_fbo->FBO); + _mesa_DeleteRenderbuffers(1, &decompress_fbo->RBO); + } + + memset(decompress_fbo, 0, sizeof(*decompress_fbo)); +} static void meta_decompress_cleanup(struct decompress_state *decompress) { - if (decompress->FBO != 0) { - _mesa_DeleteFramebuffers(1, &decompress->FBO); - _mesa_DeleteRenderbuffers(1, &decompress->RBO); - } + meta_decompress_fbo_cleanup(&decompress->byteFBO); + meta_decompress_fbo_cleanup(&decompress->floatFBO); if (decompress->VAO != 0) { _mesa_DeleteVertexArrays(1, &decompress->VAO); @@ -2975,7 +2969,7 @@ meta_decompress_cleanup(struct decompress_state *decompress) * \param dest destination buffer * \param destRowLength dest image rowLength (ala GL_PACK_ROW_LENGTH) */ -static void +static bool decompress_texture_image(struct gl_context *ctx, struct gl_texture_image *texImage, GLuint slice, @@ -2983,17 +2977,33 @@ decompress_texture_image(struct gl_context *ctx, GLvoid *dest) { struct decompress_state *decompress = &ctx->Meta->Decompress; + struct decompress_fbo_state *decompress_fbo; struct gl_texture_object *texObj = texImage->TexObject; const GLint width = texImage->Width; const GLint height = texImage->Height; const GLint depth = texImage->Height; const GLenum target = texObj->Target; + GLenum rbFormat; GLenum faceTarget; struct vertex verts[4]; GLuint samplerSave; + GLenum status; const bool use_glsl_version = ctx->Extensions.ARB_vertex_shader && ctx->Extensions.ARB_fragment_shader; + switch (_mesa_get_format_datatype(texImage->TexFormat)) { + case GL_FLOAT: + decompress_fbo = &decompress->floatFBO; + rbFormat = GL_RGBA32F; + break; + case GL_UNSIGNED_NORMALIZED: + decompress_fbo = &decompress->byteFBO; + rbFormat = GL_RGBA; + break; + default: + return false; + } + if (slice > 0) { assert(target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || @@ -3004,11 +3014,11 @@ decompress_texture_image(struct gl_context *ctx, case GL_TEXTURE_1D: case GL_TEXTURE_1D_ARRAY: assert(!"No compressed 1D textures."); - return; + return false; case GL_TEXTURE_3D: assert(!"No compressed 3D textures."); - return; + return false; case GL_TEXTURE_CUBE_MAP_ARRAY: faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + (slice % 6); @@ -3030,27 +3040,35 @@ decompress_texture_image(struct gl_context *ctx, ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; /* Create/bind FBO/renderbuffer */ - if (decompress->FBO == 0) { - _mesa_GenFramebuffers(1, &decompress->FBO); - _mesa_GenRenderbuffers(1, &decompress->RBO); - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress->FBO); - _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress->RBO); + if (decompress_fbo->FBO == 0) { + _mesa_GenFramebuffers(1, &decompress_fbo->FBO); + _mesa_GenRenderbuffers(1, &decompress_fbo->RBO); + _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress_fbo->FBO); + _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress_fbo->RBO); _mesa_FramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, - decompress->RBO); + decompress_fbo->RBO); } else { - _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress->FBO); + _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress_fbo->FBO); } /* alloc dest surface */ - if (width > decompress->Width || height > decompress->Height) { - _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress->RBO); - _mesa_RenderbufferStorage(GL_RENDERBUFFER_EXT, GL_RGBA, - width, height); - decompress->Width = width; - decompress->Height = height; + if (width > decompress_fbo->Width || height > decompress_fbo->Height) { + _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress_fbo->RBO); + _mesa_RenderbufferStorage(GL_RENDERBUFFER_EXT, rbFormat, + width, height); + status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + /* If the framebuffer isn't complete then we'll leave + * decompress_fbo->Width as zero so that it will fail again next time + * too */ + _mesa_meta_end(ctx); + return false; + } + decompress_fbo->Width = width; + decompress_fbo->Height = height; } if (use_glsl_version) { @@ -3172,6 +3190,8 @@ decompress_texture_image(struct gl_context *ctx, _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); _mesa_meta_end(ctx); + + return true; } @@ -3185,15 +3205,11 @@ _mesa_meta_GetTexImage(struct gl_context *ctx, GLenum format, GLenum type, GLvoid *pixels, struct gl_texture_image *texImage) { - /* We can only use the decompress-with-blit method here if the texels are - * unsigned, normalized values. We could handle signed and unnormalized - * with floating point renderbuffers... - */ - if (_mesa_is_format_compressed(texImage->TexFormat) && - _mesa_get_format_datatype(texImage->TexFormat) - == GL_UNSIGNED_NORMALIZED) { + if (_mesa_is_format_compressed(texImage->TexFormat)) { struct gl_texture_object *texObj = texImage->TexObject; GLuint slice; + bool result; + /* Need to unlock the texture here to prevent deadlock... */ _mesa_unlock_texture(ctx, texObj); for (slice = 0; slice < texImage->Depth; slice++) { @@ -3215,14 +3231,19 @@ _mesa_meta_GetTexImage(struct gl_context *ctx, else { dst = pixels; } - decompress_texture_image(ctx, texImage, slice, format, type, dst); + result = decompress_texture_image(ctx, texImage, slice, + format, type, dst); + if (!result) + break; } /* ... and relock it */ _mesa_lock_texture(ctx, texObj); + + if (result) + return; } - else { - _mesa_get_teximage(ctx, format, type, pixels, texImage); - } + + _mesa_get_teximage(ctx, format, type, pixels, texImage); } @@ -3362,7 +3383,8 @@ cleartexsubimage_color(struct gl_context *ctx, GLenum datatype; GLenum status; - _mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, texImage, zoffset); + _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + texImage, zoffset); status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) @@ -3408,10 +3430,12 @@ cleartexsubimage_depth_stencil(struct gl_context *ctx, GLfloat depthValue; GLenum status; - _mesa_meta_bind_fbo_image(GL_DEPTH_ATTACHMENT, texImage, zoffset); + _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + texImage, zoffset); if (texImage->_BaseFormat == GL_DEPTH_STENCIL) - _mesa_meta_bind_fbo_image(GL_STENCIL_ATTACHMENT, texImage, zoffset); + _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + texImage, zoffset); status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE)