2 * Mesa 3-D graphics library
4 * Copyright (C) 2014 Intel Corporation. All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
38 /* This function makes a texture view without bothering with all of the API
39 * checks. Most of them are the same for CopyTexSubImage so checking would
40 * be redundant. The one major difference is that we don't check for
41 * whether the texture is immutable or not. However, since the view will
42 * be created and then immediately destroyed, this should not be a problem.
45 make_view(struct gl_context
*ctx
, struct gl_texture_image
*tex_image
,
46 struct gl_texture_image
**view_tex_image
, GLuint
*view_tex_name
,
47 GLenum internal_format
)
49 struct gl_texture_object
*tex_obj
= tex_image
->TexObject
;
50 struct gl_texture_object
*view_tex_obj
;
51 mesa_format tex_format
;
53 /* Set up the new texture object */
54 _mesa_GenTextures(1, view_tex_name
);
55 view_tex_obj
= _mesa_lookup_texture(ctx
, *view_tex_name
);
59 tex_format
= _mesa_choose_texture_format(ctx
, view_tex_obj
, tex_obj
->Target
,
63 if (!ctx
->Driver
.TestProxyTexImage(ctx
, tex_obj
->Target
, 0, tex_format
,
64 tex_image
->Width
, tex_image
->Height
,
65 tex_image
->Depth
, 0)) {
69 view_tex_obj
->Target
= tex_obj
->Target
;
71 *view_tex_image
= _mesa_get_tex_image(ctx
, view_tex_obj
, tex_obj
->Target
, 0);
72 _mesa_init_teximage_fields(ctx
, *view_tex_image
,
73 tex_image
->Width
, tex_image
->Height
,
75 0, internal_format
, tex_format
);
77 view_tex_obj
->MinLevel
= 0;
78 view_tex_obj
->NumLevels
= 1;
79 view_tex_obj
->MinLayer
= tex_obj
->MinLayer
;
80 view_tex_obj
->NumLayers
= tex_obj
->NumLayers
;
81 view_tex_obj
->Immutable
= tex_obj
->Immutable
;
82 view_tex_obj
->ImmutableLevels
= tex_obj
->ImmutableLevels
;
83 view_tex_obj
->Target
= tex_obj
->Target
;
85 if (ctx
->Driver
.TextureView
!= NULL
&&
86 !ctx
->Driver
.TextureView(ctx
, view_tex_obj
, tex_obj
)) {
87 _mesa_DeleteTextures(1, view_tex_name
);
89 return false; /* driver recorded error */
95 /** A partial implementation of glCopyImageSubData
97 * This is a partial implementation of glCopyImageSubData that works only
98 * if both textures are uncompressed and the destination texture is
99 * renderable. It uses a slight abuse of a texture view (see make_view) to
100 * turn the source texture into the destination texture type and then uses
101 * _mesa_meta_BlitFramebuffers to do the copy.
104 _mesa_meta_CopyImageSubData_uncompressed(struct gl_context
*ctx
,
105 struct gl_texture_image
*src_tex_image
,
106 int src_x
, int src_y
, int src_z
,
107 struct gl_texture_image
*dst_tex_image
,
108 int dst_x
, int dst_y
, int dst_z
,
109 int src_width
, int src_height
)
111 GLuint src_view_texture
= 0;
112 struct gl_texture_image
*src_view_tex_image
;
114 bool success
= false;
116 GLenum status
, attachment
;
118 if (_mesa_is_format_compressed(dst_tex_image
->TexFormat
))
121 if (_mesa_is_format_compressed(src_tex_image
->TexFormat
))
124 if (src_tex_image
->InternalFormat
== dst_tex_image
->InternalFormat
) {
125 src_view_tex_image
= src_tex_image
;
127 if (!make_view(ctx
, src_tex_image
, &src_view_tex_image
, &src_view_texture
,
128 dst_tex_image
->InternalFormat
))
132 /* We really only need to stash the bound framebuffers. */
133 _mesa_meta_begin(ctx
, 0);
135 _mesa_GenFramebuffers(2, fbos
);
136 _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER
, fbos
[0]);
137 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbos
[1]);
139 switch (_mesa_get_format_base_format(src_tex_image
->TexFormat
)) {
140 case GL_DEPTH_COMPONENT
:
141 attachment
= GL_DEPTH_ATTACHMENT
;
142 mask
= GL_DEPTH_BUFFER_BIT
;
144 case GL_DEPTH_STENCIL
:
145 attachment
= GL_DEPTH_STENCIL_ATTACHMENT
;
146 mask
= GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
148 case GL_STENCIL_INDEX
:
149 attachment
= GL_STENCIL_ATTACHMENT
;
150 mask
= GL_STENCIL_BUFFER_BIT
;
153 attachment
= GL_COLOR_ATTACHMENT0
;
154 mask
= GL_COLOR_BUFFER_BIT
;
155 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0
);
156 _mesa_ReadBuffer(GL_COLOR_ATTACHMENT0
);
159 _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER
, attachment
,
160 src_view_tex_image
, src_z
);
162 status
= _mesa_CheckFramebufferStatus(GL_READ_FRAMEBUFFER
);
163 if (status
!= GL_FRAMEBUFFER_COMPLETE
)
166 _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER
, attachment
,
167 dst_tex_image
, dst_z
);
169 status
= _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER
);
170 if (status
!= GL_FRAMEBUFFER_COMPLETE
)
173 /* Since we've bound a new draw framebuffer, we need to update its
174 * derived state -- _Xmin, etc -- for BlitFramebuffer's clipping to
177 _mesa_update_state(ctx
);
179 /* We skip the core BlitFramebuffer checks for format consistency.
180 * We have already created views to ensure that the texture formats
183 ctx
->Driver
.BlitFramebuffer(ctx
, src_x
, src_y
,
184 src_x
+ src_width
, src_y
+ src_height
,
186 dst_x
+ src_width
, dst_y
+ src_height
,
192 _mesa_DeleteFramebuffers(2, fbos
);
196 _mesa_DeleteTextures(1, &src_view_texture
);