1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2013 Advanced Micro Devices, Inc.
4848b8605Smrg * All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the
8848b8605Smrg * "Software"), to deal in the Software without restriction, including
9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
12848b8605Smrg * the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice (including the
15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
16848b8605Smrg * of the Software.
17848b8605Smrg *
18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21848b8605Smrg * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25848b8605Smrg *
26848b8605Smrg **************************************************************************/
27848b8605Smrg
28848b8605Smrg/*
29848b8605Smrg * Authors:
30848b8605Smrg *      Christian König <christian.koenig@amd.com>
31848b8605Smrg *
32848b8605Smrg */
33848b8605Smrg
34848b8605Smrg#include <stdbool.h>
35848b8605Smrg#include "util/hash_table.h"
36b8e80941Smrg#include "util/set.h"
37848b8605Smrg#include "context.h"
38848b8605Smrg#include "glformats.h"
39848b8605Smrg#include "texobj.h"
40848b8605Smrg#include "teximage.h"
41848b8605Smrg#include "vdpau.h"
42848b8605Smrg
43848b8605Smrg#define MAX_TEXTURES 4
44848b8605Smrg
45848b8605Smrgstruct vdp_surface
46848b8605Smrg{
47848b8605Smrg   GLenum target;
48848b8605Smrg   struct gl_texture_object *textures[MAX_TEXTURES];
49848b8605Smrg   GLenum access, state;
50848b8605Smrg   GLboolean output;
51848b8605Smrg   const GLvoid *vdpSurface;
52848b8605Smrg};
53848b8605Smrg
54848b8605Smrgvoid GLAPIENTRY
55848b8605Smrg_mesa_VDPAUInitNV(const GLvoid *vdpDevice, const GLvoid *getProcAddress)
56848b8605Smrg{
57848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
58848b8605Smrg
59848b8605Smrg   if (!vdpDevice) {
60848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "vdpDevice");
61848b8605Smrg      return;
62848b8605Smrg   }
63848b8605Smrg
64848b8605Smrg   if (!getProcAddress) {
65848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "getProcAddress");
66848b8605Smrg      return;
67848b8605Smrg   }
68848b8605Smrg
69848b8605Smrg   if (ctx->vdpDevice || ctx->vdpGetProcAddress || ctx->vdpSurfaces) {
70848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUInitNV");
71848b8605Smrg      return;
72848b8605Smrg   }
73848b8605Smrg
74848b8605Smrg   ctx->vdpDevice = vdpDevice;
75848b8605Smrg   ctx->vdpGetProcAddress = getProcAddress;
76b8e80941Smrg   ctx->vdpSurfaces = _mesa_set_create(NULL, _mesa_hash_pointer,
77b8e80941Smrg                                       _mesa_key_pointer_equal);
78848b8605Smrg}
79848b8605Smrg
80848b8605Smrgstatic void
81848b8605Smrgunregister_surface(struct set_entry *entry)
82848b8605Smrg{
83848b8605Smrg   struct vdp_surface *surf = (struct vdp_surface *)entry->key;
84848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
85848b8605Smrg
86848b8605Smrg   if (surf->state == GL_SURFACE_MAPPED_NV) {
87848b8605Smrg      GLintptr surfaces[] = { (GLintptr)surf };
88848b8605Smrg      _mesa_VDPAUUnmapSurfacesNV(1, surfaces);
89848b8605Smrg   }
90848b8605Smrg
91848b8605Smrg   _mesa_set_remove(ctx->vdpSurfaces, entry);
92848b8605Smrg   free(surf);
93848b8605Smrg}
94848b8605Smrg
95848b8605Smrgvoid GLAPIENTRY
96848b8605Smrg_mesa_VDPAUFiniNV(void)
97848b8605Smrg{
98848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
99848b8605Smrg
100848b8605Smrg   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
101848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUFiniNV");
102848b8605Smrg      return;
103848b8605Smrg   }
104848b8605Smrg
105848b8605Smrg   _mesa_set_destroy(ctx->vdpSurfaces, unregister_surface);
106848b8605Smrg
107848b8605Smrg   ctx->vdpDevice = 0;
108848b8605Smrg   ctx->vdpGetProcAddress = 0;
109848b8605Smrg   ctx->vdpSurfaces = NULL;
110848b8605Smrg}
111848b8605Smrg
112848b8605Smrgstatic GLintptr
113848b8605Smrgregister_surface(struct gl_context *ctx, GLboolean isOutput,
114848b8605Smrg                 const GLvoid *vdpSurface, GLenum target,
115848b8605Smrg                 GLsizei numTextureNames, const GLuint *textureNames)
116848b8605Smrg{
117848b8605Smrg   struct vdp_surface *surf;
118848b8605Smrg   int i;
119848b8605Smrg
120848b8605Smrg   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
121848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAURegisterSurfaceNV");
122848b8605Smrg      return (GLintptr)NULL;
123848b8605Smrg   }
124848b8605Smrg
125848b8605Smrg   if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE) {
126848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "VDPAURegisterSurfaceNV");
127848b8605Smrg      return (GLintptr)NULL;
128848b8605Smrg   }
129848b8605Smrg
130848b8605Smrg   if (target == GL_TEXTURE_RECTANGLE && !ctx->Extensions.NV_texture_rectangle) {
131848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "VDPAURegisterSurfaceNV");
132848b8605Smrg      return (GLintptr)NULL;
133848b8605Smrg   }
134848b8605Smrg
135848b8605Smrg   surf = CALLOC_STRUCT( vdp_surface );
136848b8605Smrg   if (surf == NULL) {
137848b8605Smrg      _mesa_error_no_memory("VDPAURegisterSurfaceNV");
138848b8605Smrg      return (GLintptr)NULL;
139848b8605Smrg   }
140848b8605Smrg
141848b8605Smrg   surf->vdpSurface = vdpSurface;
142848b8605Smrg   surf->target = target;
143848b8605Smrg   surf->access = GL_READ_WRITE;
144848b8605Smrg   surf->state = GL_SURFACE_REGISTERED_NV;
145848b8605Smrg   surf->output = isOutput;
146848b8605Smrg   for (i = 0; i < numTextureNames; ++i) {
147848b8605Smrg      struct gl_texture_object *tex;
148b8e80941Smrg
149b8e80941Smrg      tex = _mesa_lookup_texture_err(ctx, textureNames[i],
150b8e80941Smrg                                     "VDPAURegisterSurfaceNV");
151848b8605Smrg      if (tex == NULL) {
152848b8605Smrg         free(surf);
153848b8605Smrg         return (GLintptr)NULL;
154848b8605Smrg      }
155848b8605Smrg
156848b8605Smrg      _mesa_lock_texture(ctx, tex);
157848b8605Smrg
158848b8605Smrg      if (tex->Immutable) {
159848b8605Smrg         _mesa_unlock_texture(ctx, tex);
160848b8605Smrg         free(surf);
161848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION,
162848b8605Smrg                     "VDPAURegisterSurfaceNV(texture is immutable)");
163848b8605Smrg         return (GLintptr)NULL;
164848b8605Smrg      }
165848b8605Smrg
166b8e80941Smrg      if (tex->Target == 0) {
167848b8605Smrg         tex->Target = target;
168b8e80941Smrg         tex->TargetIndex = _mesa_tex_target_to_index(ctx, target);
169b8e80941Smrg      } else if (tex->Target != target) {
170848b8605Smrg         _mesa_unlock_texture(ctx, tex);
171848b8605Smrg         free(surf);
172848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION,
173848b8605Smrg                     "VDPAURegisterSurfaceNV(target mismatch)");
174848b8605Smrg         return (GLintptr)NULL;
175848b8605Smrg      }
176848b8605Smrg
177848b8605Smrg      /* This will disallow respecifying the storage. */
178848b8605Smrg      tex->Immutable = GL_TRUE;
179848b8605Smrg      _mesa_unlock_texture(ctx, tex);
180848b8605Smrg
181848b8605Smrg      _mesa_reference_texobj(&surf->textures[i], tex);
182848b8605Smrg   }
183848b8605Smrg
184b8e80941Smrg   _mesa_set_add(ctx->vdpSurfaces, surf);
185848b8605Smrg
186848b8605Smrg   return (GLintptr)surf;
187848b8605Smrg}
188848b8605Smrg
189848b8605SmrgGLintptr GLAPIENTRY
190848b8605Smrg_mesa_VDPAURegisterVideoSurfaceNV(const GLvoid *vdpSurface, GLenum target,
191848b8605Smrg                                  GLsizei numTextureNames,
192848b8605Smrg                                  const GLuint *textureNames)
193848b8605Smrg{
194848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
195848b8605Smrg
196848b8605Smrg   if (numTextureNames != 4) {
197848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "VDPAURegisterVideoSurfaceNV");
198848b8605Smrg      return (GLintptr)NULL;
199848b8605Smrg   }
200848b8605Smrg
201848b8605Smrg   return register_surface(ctx, false, vdpSurface, target,
202848b8605Smrg                           numTextureNames, textureNames);
203848b8605Smrg}
204848b8605Smrg
205848b8605SmrgGLintptr GLAPIENTRY
206848b8605Smrg_mesa_VDPAURegisterOutputSurfaceNV(const GLvoid *vdpSurface, GLenum target,
207848b8605Smrg                                   GLsizei numTextureNames,
208848b8605Smrg                                   const GLuint *textureNames)
209848b8605Smrg{
210848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
211848b8605Smrg
212848b8605Smrg   if (numTextureNames != 1) {
213848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "VDPAURegisterVideoSurfaceNV");
214848b8605Smrg      return (GLintptr)NULL;
215848b8605Smrg   }
216848b8605Smrg
217848b8605Smrg   return register_surface(ctx, true, vdpSurface, target,
218848b8605Smrg                           numTextureNames, textureNames);
219848b8605Smrg}
220848b8605Smrg
221848b8605SmrgGLboolean GLAPIENTRY
222848b8605Smrg_mesa_VDPAUIsSurfaceNV(GLintptr surface)
223848b8605Smrg{
224848b8605Smrg   struct vdp_surface *surf = (struct vdp_surface *)surface;
225848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
226848b8605Smrg
227848b8605Smrg   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
228848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUIsSurfaceNV");
229848b8605Smrg      return false;
230848b8605Smrg   }
231848b8605Smrg
232b8e80941Smrg   if (!_mesa_set_search(ctx->vdpSurfaces, surf)) {
233848b8605Smrg      return false;
234848b8605Smrg   }
235848b8605Smrg
236848b8605Smrg   return true;
237848b8605Smrg}
238848b8605Smrg
239848b8605Smrgvoid GLAPIENTRY
240848b8605Smrg_mesa_VDPAUUnregisterSurfaceNV(GLintptr surface)
241848b8605Smrg{
242848b8605Smrg   struct vdp_surface *surf = (struct vdp_surface *)surface;
243848b8605Smrg   struct set_entry *entry;
244848b8605Smrg   int i;
245848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
246848b8605Smrg
247848b8605Smrg   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
248848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnregisterSurfaceNV");
249848b8605Smrg      return;
250848b8605Smrg   }
251848b8605Smrg
252848b8605Smrg   /* according to the spec it's ok when this is zero */
253848b8605Smrg   if (surface == 0)
254848b8605Smrg      return;
255848b8605Smrg
256b8e80941Smrg   entry = _mesa_set_search(ctx->vdpSurfaces, surf);
257848b8605Smrg   if (!entry) {
258848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUUnregisterSurfaceNV");
259848b8605Smrg      return;
260848b8605Smrg   }
261848b8605Smrg
262848b8605Smrg   for (i = 0; i < MAX_TEXTURES; i++) {
263848b8605Smrg      if (surf->textures[i]) {
264848b8605Smrg         surf->textures[i]->Immutable = GL_FALSE;
265848b8605Smrg         _mesa_reference_texobj(&surf->textures[i], NULL);
266848b8605Smrg      }
267848b8605Smrg   }
268848b8605Smrg
269848b8605Smrg   _mesa_set_remove(ctx->vdpSurfaces, entry);
270848b8605Smrg   free(surf);
271848b8605Smrg}
272848b8605Smrg
273848b8605Smrgvoid GLAPIENTRY
274848b8605Smrg_mesa_VDPAUGetSurfaceivNV(GLintptr surface, GLenum pname, GLsizei bufSize,
275848b8605Smrg                          GLsizei *length, GLint *values)
276848b8605Smrg{
277848b8605Smrg   struct vdp_surface *surf = (struct vdp_surface *)surface;
278848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
279848b8605Smrg
280848b8605Smrg   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
281848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUGetSurfaceivNV");
282848b8605Smrg      return;
283848b8605Smrg   }
284848b8605Smrg
285b8e80941Smrg   if (!_mesa_set_search(ctx->vdpSurfaces, surf)) {
286848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUGetSurfaceivNV");
287848b8605Smrg      return;
288848b8605Smrg   }
289848b8605Smrg
290848b8605Smrg   if (pname != GL_SURFACE_STATE_NV) {
291848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "VDPAUGetSurfaceivNV");
292848b8605Smrg      return;
293848b8605Smrg   }
294848b8605Smrg
295848b8605Smrg   if (bufSize < 1) {
296848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUGetSurfaceivNV");
297848b8605Smrg      return;
298848b8605Smrg   }
299848b8605Smrg
300848b8605Smrg   values[0] = surf->state;
301848b8605Smrg
302848b8605Smrg   if (length != NULL)
303848b8605Smrg      *length = 1;
304848b8605Smrg}
305848b8605Smrg
306848b8605Smrgvoid GLAPIENTRY
307848b8605Smrg_mesa_VDPAUSurfaceAccessNV(GLintptr surface, GLenum access)
308848b8605Smrg{
309848b8605Smrg   struct vdp_surface *surf = (struct vdp_surface *)surface;
310848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
311848b8605Smrg
312848b8605Smrg   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
313848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUSurfaceAccessNV");
314848b8605Smrg      return;
315848b8605Smrg   }
316848b8605Smrg
317b8e80941Smrg   if (!_mesa_set_search(ctx->vdpSurfaces, surf)) {
318848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV");
319848b8605Smrg      return;
320848b8605Smrg   }
321848b8605Smrg
322848b8605Smrg   if (access != GL_READ_ONLY && access != GL_WRITE_ONLY &&
323848b8605Smrg       access != GL_READ_WRITE) {
324848b8605Smrg
325848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV");
326848b8605Smrg      return;
327848b8605Smrg   }
328848b8605Smrg
329848b8605Smrg   if (surf->state == GL_SURFACE_MAPPED_NV) {
330848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUSurfaceAccessNV");
331848b8605Smrg      return;
332848b8605Smrg   }
333848b8605Smrg
334848b8605Smrg   surf->access = access;
335848b8605Smrg}
336848b8605Smrg
337848b8605Smrgvoid GLAPIENTRY
338848b8605Smrg_mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces)
339848b8605Smrg{
340848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
341848b8605Smrg   int i;
342848b8605Smrg
343848b8605Smrg   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
344848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnmapSurfacesNV");
345848b8605Smrg      return;
346848b8605Smrg   }
347848b8605Smrg
348848b8605Smrg   for (i = 0; i < numSurfaces; ++i) {
349848b8605Smrg      struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
350848b8605Smrg
351b8e80941Smrg      if (!_mesa_set_search(ctx->vdpSurfaces, surf)) {
352848b8605Smrg         _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV");
353848b8605Smrg         return;
354848b8605Smrg      }
355848b8605Smrg
356848b8605Smrg      if (surf->state == GL_SURFACE_MAPPED_NV) {
357848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUSurfaceAccessNV");
358848b8605Smrg         return;
359848b8605Smrg      }
360848b8605Smrg   }
361848b8605Smrg
362848b8605Smrg   for (i = 0; i < numSurfaces; ++i) {
363848b8605Smrg      struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
364848b8605Smrg      unsigned numTextureNames = surf->output ? 1 : 4;
365848b8605Smrg      unsigned j;
366848b8605Smrg
367848b8605Smrg      for (j = 0; j < numTextureNames; ++j) {
368848b8605Smrg         struct gl_texture_object *tex = surf->textures[j];
369848b8605Smrg         struct gl_texture_image *image;
370848b8605Smrg
371848b8605Smrg         _mesa_lock_texture(ctx, tex);
372848b8605Smrg         image = _mesa_get_tex_image(ctx, tex, surf->target, 0);
373848b8605Smrg         if (!image) {
374848b8605Smrg            _mesa_error(ctx, GL_OUT_OF_MEMORY, "VDPAUMapSurfacesNV");
375848b8605Smrg            _mesa_unlock_texture(ctx, tex);
376848b8605Smrg            return;
377848b8605Smrg         }
378848b8605Smrg
379848b8605Smrg         ctx->Driver.FreeTextureImageBuffer(ctx, image);
380848b8605Smrg
381848b8605Smrg         ctx->Driver.VDPAUMapSurface(ctx, surf->target, surf->access,
382848b8605Smrg                                     surf->output, tex, image,
383848b8605Smrg                                     surf->vdpSurface, j);
384848b8605Smrg
385848b8605Smrg         _mesa_unlock_texture(ctx, tex);
386848b8605Smrg      }
387848b8605Smrg      surf->state = GL_SURFACE_MAPPED_NV;
388848b8605Smrg   }
389848b8605Smrg}
390848b8605Smrg
391848b8605Smrgvoid GLAPIENTRY
392848b8605Smrg_mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces)
393848b8605Smrg{
394848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
395848b8605Smrg   int i;
396848b8605Smrg
397848b8605Smrg   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
398848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnmapSurfacesNV");
399848b8605Smrg      return;
400848b8605Smrg   }
401848b8605Smrg
402848b8605Smrg   for (i = 0; i < numSurfaces; ++i) {
403848b8605Smrg      struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
404848b8605Smrg
405b8e80941Smrg      if (!_mesa_set_search(ctx->vdpSurfaces, surf)) {
406848b8605Smrg         _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUSurfaceAccessNV");
407848b8605Smrg         return;
408848b8605Smrg      }
409848b8605Smrg
410848b8605Smrg      if (surf->state != GL_SURFACE_MAPPED_NV) {
411848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUSurfaceAccessNV");
412848b8605Smrg         return;
413848b8605Smrg      }
414848b8605Smrg   }
415848b8605Smrg
416848b8605Smrg   for (i = 0; i < numSurfaces; ++i) {
417848b8605Smrg      struct vdp_surface *surf = (struct vdp_surface *)surfaces[i];
418848b8605Smrg      unsigned numTextureNames = surf->output ? 1 : 4;
419848b8605Smrg      unsigned j;
420848b8605Smrg
421848b8605Smrg      for (j = 0; j < numTextureNames; ++j) {
422848b8605Smrg         struct gl_texture_object *tex = surf->textures[j];
423848b8605Smrg         struct gl_texture_image *image;
424848b8605Smrg
425848b8605Smrg         _mesa_lock_texture(ctx, tex);
426848b8605Smrg
427b8e80941Smrg         image = _mesa_select_tex_image(tex, surf->target, 0);
428848b8605Smrg
429848b8605Smrg         ctx->Driver.VDPAUUnmapSurface(ctx, surf->target, surf->access,
430848b8605Smrg                                       surf->output, tex, image,
431848b8605Smrg                                       surf->vdpSurface, j);
432848b8605Smrg
433848b8605Smrg         if (image)
434848b8605Smrg            ctx->Driver.FreeTextureImageBuffer(ctx, image);
435848b8605Smrg
436848b8605Smrg         _mesa_unlock_texture(ctx, tex);
437848b8605Smrg      }
438848b8605Smrg      surf->state = GL_SURFACE_REGISTERED_NV;
439848b8605Smrg   }
440848b8605Smrg}
441