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)) {
66 _mesa_DeleteTextures(1, view_tex_name
);
71 view_tex_obj
->Target
= tex_obj
->Target
;
73 *view_tex_image
= _mesa_get_tex_image(ctx
, view_tex_obj
, tex_obj
->Target
, 0);
75 if (!*view_tex_image
) {
76 _mesa_DeleteTextures(1, view_tex_name
);
81 _mesa_init_teximage_fields(ctx
, *view_tex_image
,
82 tex_image
->Width
, tex_image
->Height
,
84 0, internal_format
, tex_format
);
86 view_tex_obj
->MinLevel
= tex_image
->Level
;
87 view_tex_obj
->NumLevels
= 1;
88 view_tex_obj
->MinLayer
= tex_obj
->MinLayer
;
89 view_tex_obj
->NumLayers
= tex_obj
->NumLayers
;
90 view_tex_obj
->Immutable
= tex_obj
->Immutable
;
91 view_tex_obj
->ImmutableLevels
= tex_obj
->ImmutableLevels
;
92 view_tex_obj
->Target
= tex_obj
->Target
;
94 if (ctx
->Driver
.TextureView
!= NULL
&&
95 !ctx
->Driver
.TextureView(ctx
, view_tex_obj
, tex_obj
)) {
96 _mesa_DeleteTextures(1, view_tex_name
);
98 return false; /* driver recorded error */
104 /** A partial implementation of glCopyImageSubData
106 * This is a partial implementation of glCopyImageSubData that works only
107 * if both textures are uncompressed and the destination texture is
108 * renderable. It uses a slight abuse of a texture view (see make_view) to
109 * turn the source texture into the destination texture type and then uses
110 * _mesa_meta_BlitFramebuffers to do the copy.
113 _mesa_meta_CopyImageSubData_uncompressed(struct gl_context
*ctx
,
114 struct gl_texture_image
*src_tex_image
,
115 int src_x
, int src_y
, int src_z
,
116 struct gl_texture_image
*dst_tex_image
,
117 int dst_x
, int dst_y
, int dst_z
,
118 int src_width
, int src_height
)
120 GLuint src_view_texture
= 0;
121 struct gl_texture_image
*src_view_tex_image
;
123 bool success
= false;
125 GLenum status
, attachment
;
127 if (_mesa_is_format_compressed(dst_tex_image
->TexFormat
))
130 if (_mesa_is_format_compressed(src_tex_image
->TexFormat
))
133 if (src_tex_image
->InternalFormat
== dst_tex_image
->InternalFormat
) {
134 src_view_tex_image
= src_tex_image
;
136 if (!make_view(ctx
, src_tex_image
, &src_view_tex_image
, &src_view_texture
,
137 dst_tex_image
->InternalFormat
))
141 /* We really only need to stash the bound framebuffers. */
142 _mesa_meta_begin(ctx
, 0);
144 _mesa_GenFramebuffers(2, fbos
);
145 _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER
, fbos
[0]);
146 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbos
[1]);
148 switch (_mesa_get_format_base_format(src_tex_image
->TexFormat
)) {
149 case GL_DEPTH_COMPONENT
:
150 attachment
= GL_DEPTH_ATTACHMENT
;
151 mask
= GL_DEPTH_BUFFER_BIT
;
153 case GL_DEPTH_STENCIL
:
154 attachment
= GL_DEPTH_STENCIL_ATTACHMENT
;
155 mask
= GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
;
157 case GL_STENCIL_INDEX
:
158 attachment
= GL_STENCIL_ATTACHMENT
;
159 mask
= GL_STENCIL_BUFFER_BIT
;
162 attachment
= GL_COLOR_ATTACHMENT0
;
163 mask
= GL_COLOR_BUFFER_BIT
;
164 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0
);
165 _mesa_ReadBuffer(GL_COLOR_ATTACHMENT0
);
168 _mesa_meta_bind_fbo_image(GL_READ_FRAMEBUFFER
, attachment
,
169 src_view_tex_image
, src_z
);
171 status
= _mesa_CheckFramebufferStatus(GL_READ_FRAMEBUFFER
);
172 if (status
!= GL_FRAMEBUFFER_COMPLETE
)
175 _mesa_meta_bind_fbo_image(GL_DRAW_FRAMEBUFFER
, attachment
,
176 dst_tex_image
, dst_z
);
178 status
= _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER
);
179 if (status
!= GL_FRAMEBUFFER_COMPLETE
)
182 /* Since we've bound a new draw framebuffer, we need to update its
183 * derived state -- _Xmin, etc -- for BlitFramebuffer's clipping to
186 _mesa_update_state(ctx
);
188 /* We skip the core BlitFramebuffer checks for format consistency.
189 * We have already created views to ensure that the texture formats
192 ctx
->Driver
.BlitFramebuffer(ctx
, src_x
, src_y
,
193 src_x
+ src_width
, src_y
+ src_height
,
195 dst_x
+ src_width
, dst_y
+ src_height
,
201 _mesa_DeleteFramebuffers(2, fbos
);
205 _mesa_DeleteTextures(1, &src_view_texture
);