summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/common
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2015-08-28 00:42:00 -0600
committerBrian Paul <[email protected]>2015-09-24 07:52:42 -0600
commit200aee424790f3167fcb175f4798af27783fe364 (patch)
tree91b4724c5503637359b8068f94d35cdbdabe00df /src/mesa/drivers/common
parentc8cb5ed93c8e7343390f188bbf1a8459380a5739 (diff)
mesa: rework Driver.CopyImageSubData() and related code
Previously, core Mesa's _mesa_CopyImageSubData() created temporary textures to wrap renderbuffer sources/destinations. This caused a bit of a mess in the Mesa/gallium state tracker because we had to basically undo that wrapping. Instead, change ctx->Driver.CopyImageSubData() to take both gl_renderbuffer and gl_texture_image src/dst pointers (one being null, the other non-null) so the driver can handle renderbuffer vs. texture as needed. For the i965 driver, we basically moved the code that wrapped textures around renderbuffers from copyimage.c down into the met and driver code. The old code in copyimage.c also made some questionable calls to _mesa_BindTexture(), etc. which weren't undone at the end. v2 (Jason Ekstrand): Rework the intel bits v3 (Brian Paul): Update the temporary st_CopyImageSubData() function. Reviewed-by: Topi Pohjolainen <[email protected]> Tested-by: Kai Wasserbäch <[email protected]> Tested-by: Nick Sarnie <[email protected]>
Diffstat (limited to 'src/mesa/drivers/common')
-rw-r--r--src/mesa/drivers/common/meta.h2
-rw-r--r--src/mesa/drivers/common/meta_copy_image.c103
2 files changed, 97 insertions, 8 deletions
diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h
index fe439153aa0..23fa209905d 100644
--- a/src/mesa/drivers/common/meta.h
+++ b/src/mesa/drivers/common/meta.h
@@ -494,8 +494,10 @@ _mesa_meta_and_swrast_BlitFramebuffer(struct gl_context *ctx,
bool
_mesa_meta_CopyImageSubData_uncompressed(struct gl_context *ctx,
struct gl_texture_image *src_tex_image,
+ struct gl_renderbuffer *src_renderbuffer,
int src_x, int src_y, int src_z,
struct gl_texture_image *dst_tex_image,
+ struct gl_renderbuffer *dst_renderbuffer,
int dst_x, int dst_y, int dst_z,
int src_width, int src_height);
diff --git a/src/mesa/drivers/common/meta_copy_image.c b/src/mesa/drivers/common/meta_copy_image.c
index 149ed18503c..33490ee6615 100644
--- a/src/mesa/drivers/common/meta_copy_image.c
+++ b/src/mesa/drivers/common/meta_copy_image.c
@@ -35,6 +35,46 @@
#include "mtypes.h"
#include "meta.h"
+/**
+ * Create a texture image that wraps a renderbuffer.
+ */
+static struct gl_texture_image *
+wrap_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+ GLenum texTarget;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+
+ if (rb->NumSamples > 1)
+ texTarget = GL_TEXTURE_2D_MULTISAMPLE;
+ else
+ texTarget = GL_TEXTURE_2D;
+
+ /* Texture ID is not significant since it never goes into the hash table */
+ texObj = ctx->Driver.NewTextureObject(ctx, 0, texTarget);
+ assert(texObj);
+ if (!texObj)
+ return NULL;
+
+ texImage = _mesa_get_tex_image(ctx, texObj, texTarget, 0);
+ assert(texImage);
+ if (!texImage)
+ return NULL;
+
+ if (!ctx->Driver.BindRenderbufferTexImage(ctx, rb, texImage)) {
+ _mesa_problem(ctx, "Failed to create texture from renderbuffer");
+ return NULL;
+ }
+
+ if (ctx->Driver.FinishRenderTexture && !rb->NeedsFinishRenderTexture) {
+ rb->NeedsFinishRenderTexture = true;
+ ctx->Driver.FinishRenderTexture(ctx, rb);
+ }
+
+ return texImage;
+}
+
+
/* This function makes a texture view without bothering with all of the API
* checks. Most of them are the same for CopyTexSubImage so checking would
* be redundant. The one major difference is that we don't check for
@@ -112,11 +152,15 @@ make_view(struct gl_context *ctx, struct gl_texture_image *tex_image,
bool
_mesa_meta_CopyImageSubData_uncompressed(struct gl_context *ctx,
struct gl_texture_image *src_tex_image,
+ struct gl_renderbuffer *src_renderbuffer,
int src_x, int src_y, int src_z,
struct gl_texture_image *dst_tex_image,
+ struct gl_renderbuffer *dst_renderbuffer,
int dst_x, int dst_y, int dst_z,
int src_width, int src_height)
{
+ mesa_format src_format, dst_format;
+ GLint src_internal_format, dst_internal_format;
GLuint src_view_texture = 0;
struct gl_texture_image *src_view_tex_image;
GLuint fbos[2];
@@ -124,15 +168,37 @@ _mesa_meta_CopyImageSubData_uncompressed(struct gl_context *ctx,
GLbitfield mask;
GLenum status, attachment;
- if (_mesa_is_format_compressed(dst_tex_image->TexFormat))
+ if (src_renderbuffer) {
+ src_format = src_renderbuffer->Format;
+ src_internal_format = src_renderbuffer->InternalFormat;
+ } else {
+ assert(src_tex_image);
+ src_format = src_tex_image->TexFormat;
+ src_internal_format = src_tex_image->InternalFormat;
+ }
+
+ if (dst_renderbuffer) {
+ dst_format = dst_renderbuffer->Format;
+ dst_internal_format = dst_renderbuffer->InternalFormat;
+ } else {
+ assert(dst_tex_image);
+ dst_format = dst_tex_image->TexFormat;
+ dst_internal_format = dst_tex_image->InternalFormat;
+ }
+
+ if (_mesa_is_format_compressed(src_format))
return false;
- if (_mesa_is_format_compressed(src_tex_image->TexFormat))
+ if (_mesa_is_format_compressed(dst_format))
return false;
- if (src_tex_image->InternalFormat == dst_tex_image->InternalFormat) {
+ if (src_internal_format == dst_internal_format) {
src_view_tex_image = src_tex_image;
} else {
+ if (src_renderbuffer) {
+ assert(src_tex_image == NULL);
+ src_tex_image = wrap_renderbuffer(ctx, src_renderbuffer);
+ }
if (!make_view(ctx, src_tex_image, &src_view_tex_image, &src_view_texture,
dst_tex_image->InternalFormat))
goto cleanup;
@@ -145,7 +211,7 @@ _mesa_meta_CopyImageSubData_uncompressed(struct gl_context *ctx,
_mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);
_mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
- switch (_mesa_get_format_base_format(src_tex_image->TexFormat)) {
+ switch (_mesa_get_format_base_format(src_format)) {
case GL_DEPTH_COMPONENT:
attachment = GL_DEPTH_ATTACHMENT;
mask = GL_DEPTH_BUFFER_BIT;
@@ -165,15 +231,32 @@ _mesa_meta_CopyImageSubData_uncompressed(struct gl_context *ctx,
_mesa_ReadBuffer(GL_COLOR_ATTACHMENT0);
}
- _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, attachment,
- src_view_tex_image, src_z);
+ if (src_view_tex_image) {
+ /* Prever the tex image because, even if we have a renderbuffer, we may
+ * have had to wrap it in a texture view.
+ */
+ _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER, attachment,
+ src_view_tex_image, src_z);
+ } else {
+ _mesa_FramebufferRenderbuffer(GL_READ_FRAMEBUFFER,
+ attachment,
+ GL_RENDERBUFFER,
+ src_renderbuffer->Name);
+ }
status = _mesa_CheckFramebufferStatus(GL_READ_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
goto meta_end;
- _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, attachment,
- dst_tex_image, dst_z);
+ if (dst_renderbuffer) {
+ _mesa_FramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
+ attachment,
+ GL_RENDERBUFFER,
+ dst_renderbuffer->Name);
+ } else {
+ _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER, attachment,
+ dst_tex_image, dst_z);
+ }
status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
@@ -205,5 +288,9 @@ meta_end:
cleanup:
_mesa_DeleteTextures(1, &src_view_texture);
+ /* If we got a renderbuffer source, delete the temporary texture */
+ if (src_renderbuffer && src_tex_image)
+ ctx->Driver.DeleteTexture(ctx, src_tex_image->TexObject);
+
return success;
}