ReactOS  0.4.14-dev-606-g14ebc0b
texture.c
Go to the documentation of this file.
1 /*
2  * Copyright 2002-2005 Jason Edmeades
3  * Copyright 2002-2005 Raphael Junqueira
4  * Copyright 2005 Oliver Stieber
5  * Copyright 2007-2009, 2013 Stefan Dösinger for CodeWeavers
6  * Copyright 2009-2011 Henri Verbeet for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include "config.h"
24 #include "wine/port.h"
25 #include "wined3d_private.h"
26 
30 
31 #define WINED3D_TEXTURE_DYNAMIC_MAP_THRESHOLD 50
32 
33 static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
34 {
35  return !(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU)
36  && texture->resource.usage & WINED3DUSAGE_DYNAMIC
38  && !texture->resource.format->conv_byte_count
40 }
41 
43  const struct wined3d_gl_info *gl_info)
44 {
45  /* We don't expect to create texture views for textures with height-scaled formats.
46  * Besides, ARB_texture_storage doesn't allow specifying exact sizes for all levels. */
47  return gl_info->supported[ARB_TEXTURE_STORAGE]
48  && !(texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE);
49 }
50 
52 {
53  const struct wined3d_swapchain *swapchain = texture->swapchain;
54 
55  TRACE("texture %p.\n", texture);
56 
57  if (!swapchain)
58  {
59  ERR("Texture %p is not part of a swapchain.\n", texture);
60  return GL_NONE;
61  }
62 
63  if (texture == swapchain->front_buffer)
64  {
65  TRACE("Returning GL_FRONT.\n");
66  return GL_FRONT;
67  }
68 
69  if (texture == swapchain->back_buffers[0])
70  {
71  TRACE("Returning GL_BACK.\n");
72  return GL_BACK;
73  }
74 
75  FIXME("Higher back buffer, returning GL_BACK.\n");
76  return GL_BACK;
77 }
78 
80 {
81  switch (location)
82  {
84  return 0;
85 
89 
97 
98  default:
99  FIXME("Unhandled location %#x.\n", location);
100  return 0;
101  }
102 }
103 
105 {
106  return (x != 0) && !(x & (x - 1));
107 }
108 
110 {
111  struct wined3d_texture_sub_resource *sub_resource;
112  unsigned int i, sub_count;
113 
115  || texture->download_count > WINED3D_TEXTURE_DYNAMIC_MAP_THRESHOLD)
116  {
117  TRACE("Not evicting system memory for texture %p.\n", texture);
118  return;
119  }
120 
121  TRACE("Evicting system memory for texture %p.\n", texture);
122 
123  sub_count = texture->level_count * texture->layer_count;
124  for (i = 0; i < sub_count; ++i)
125  {
126  sub_resource = &texture->sub_resources[i];
127  if (sub_resource->locations == WINED3D_LOCATION_SYSMEM)
128  ERR("WINED3D_LOCATION_SYSMEM is the only location for sub-resource %u of texture %p.\n",
129  i, texture);
130  sub_resource->locations &= ~WINED3D_LOCATION_SYSMEM;
131  }
133 }
134 
136  unsigned int sub_resource_idx, DWORD location)
137 {
138  struct wined3d_texture_sub_resource *sub_resource;
139  DWORD previous_locations;
140 
141  TRACE("texture %p, sub_resource_idx %u, location %s.\n",
142  texture, sub_resource_idx, wined3d_debug_location(location));
143 
144  sub_resource = &texture->sub_resources[sub_resource_idx];
145  previous_locations = sub_resource->locations;
146  sub_resource->locations |= location;
147  if (previous_locations == WINED3D_LOCATION_SYSMEM && location != WINED3D_LOCATION_SYSMEM
148  && !--texture->sysmem_count)
150 
151  TRACE("New locations flags are %s.\n", wined3d_debug_location(sub_resource->locations));
152 }
153 
155 {
157 }
158 
160  unsigned int sub_resource_idx, DWORD location)
161 {
162  struct wined3d_texture_sub_resource *sub_resource;
163  DWORD previous_locations;
164 
165  TRACE("texture %p, sub_resource_idx %u, location %s.\n",
166  texture, sub_resource_idx, wined3d_debug_location(location));
167 
170 
171  sub_resource = &texture->sub_resources[sub_resource_idx];
172  previous_locations = sub_resource->locations;
173  sub_resource->locations &= ~location;
174  if (previous_locations != WINED3D_LOCATION_SYSMEM && sub_resource->locations == WINED3D_LOCATION_SYSMEM)
175  ++texture->sysmem_count;
176 
177  TRACE("New locations flags are %s.\n", wined3d_debug_location(sub_resource->locations));
178 
179  if (!sub_resource->locations)
180  ERR("Sub-resource %u of texture %p does not have any up to date location.\n",
181  sub_resource_idx, texture);
182 }
183 
185  unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
186 {
187  unsigned int size = texture->sub_resources[sub_resource_idx].size;
188  struct wined3d_device *device = texture->resource.device;
189  const struct wined3d_gl_info *gl_info;
190  struct wined3d_bo_address dst, src;
191 
192  if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
193  return FALSE;
194 
195  wined3d_texture_get_memory(texture, sub_resource_idx, &dst, location);
196  wined3d_texture_get_memory(texture, sub_resource_idx, &src,
197  texture->sub_resources[sub_resource_idx].locations);
198 
199  if (dst.buffer_object)
200  {
202  gl_info = context->gl_info;
203  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object));
204  GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr));
205  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
206  checkGLcall("PBO upload");
208  return TRUE;
209  }
210 
211  if (src.buffer_object)
212  {
214  gl_info = context->gl_info;
215  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object));
216  GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr));
217  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
218  checkGLcall("PBO download");
220  return TRUE;
221  }
222 
223  memcpy(dst.addr, src.addr, size);
224  return TRUE;
225 }
226 
227 /* Context activation is done by the caller. Context may be NULL in
228  * WINED3D_NO3D mode. */
230  unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
231 {
232  static const DWORD sysmem_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY
234  DWORD current = texture->sub_resources[sub_resource_idx].locations;
235  BOOL ret;
236 
237  TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
238  texture, sub_resource_idx, context, wined3d_debug_location(location));
239 
240  TRACE("Current resource location %s.\n", wined3d_debug_location(current));
241 
242  if (current & location)
243  {
244  TRACE("Location %s is already up to date.\n", wined3d_debug_location(location));
245  return TRUE;
246  }
247 
248  if (WARN_ON(d3d))
249  {
251  if ((texture->resource.access & required_access) != required_access)
252  WARN("Operation requires %#x access, but texture only has %#x.\n",
253  required_access, texture->resource.access);
254  }
255 
257  {
258  TRACE("Sub-resource previously discarded, nothing to do.\n");
259  if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
260  return FALSE;
263  return TRUE;
264  }
265 
266  if (!current)
267  {
268  ERR("Sub-resource %u of texture %p does not have any up to date location.\n",
269  sub_resource_idx, texture);
271  return wined3d_texture_load_location(texture, sub_resource_idx, context, location);
272  }
273 
274  if ((location & sysmem_locations) && (current & sysmem_locations))
276  else
277  ret = texture->texture_ops->texture_load_location(texture, sub_resource_idx, context, location);
278 
279  if (ret)
281 
282  return ret;
283 }
284 
285 void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx,
287 {
288  struct wined3d_texture_sub_resource *sub_resource;
289 
290  TRACE("texture %p, sub_resource_idx %u, data %p, locations %s.\n",
291  texture, sub_resource_idx, data, wined3d_debug_location(locations));
292 
293  sub_resource = &texture->sub_resources[sub_resource_idx];
295  {
296  data->addr = NULL;
297 #if !defined(STAGING_CSMT)
298  data->buffer_object = sub_resource->buffer_object;
299 #else /* STAGING_CSMT */
300  data->buffer_object = sub_resource->buffer->name;
301 #endif /* STAGING_CSMT */
302  return;
303  }
305  {
306  data->addr = texture->user_memory;
307  data->buffer_object = 0;
308  return;
309  }
311  {
312  data->addr = texture->resource.heap_memory;
313  data->addr += sub_resource->offset;
314  data->buffer_object = 0;
315  return;
316  }
317 
318  ERR("Unexpected locations %s.\n", wined3d_debug_location(locations));
319  data->addr = NULL;
320  data->buffer_object = 0;
321 }
322 
323 static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops,
324  UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD flags,
325  struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops,
326  const struct wined3d_resource_ops *resource_ops)
327 {
328  unsigned int i, j, size, offset = 0;
329  const struct wined3d_format *format;
330  HRESULT hr;
331 
332  TRACE("texture %p, texture_ops %p, layer_count %u, level_count %u, resource_type %s, format %s, "
333  "multisample_type %#x, multisample_quality %#x, usage %s, access %s, width %u, height %u, depth %u, "
334  "flags %#x, device %p, parent %p, parent_ops %p, resource_ops %p.\n",
335  texture, texture_ops, layer_count, level_count, debug_d3dresourcetype(desc->resource_type),
336  debug_d3dformat(desc->format), desc->multisample_type, desc->multisample_quality,
338  desc->width, desc->height, desc->depth, flags, device, parent, parent_ops, resource_ops);
339 
340  if (!desc->width || !desc->height || !desc->depth)
341  return WINED3DERR_INVALIDCALL;
342 
343  format = wined3d_get_format(&device->adapter->gl_info, desc->format, desc->usage);
344 
345  for (i = 0; i < layer_count; ++i)
346  {
347  for (j = 0; j < level_count; ++j)
348  {
349  unsigned int idx = i * level_count + j;
350 
351  size = wined3d_format_calculate_size(format, device->surface_alignment,
352  max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j));
353  texture->sub_resources[idx].offset = offset;
354  texture->sub_resources[idx].size = size;
355  offset += size;
356  }
357  offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1);
358  }
359 
360  if (!offset)
361  return WINED3DERR_INVALIDCALL;
362 
363  if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
364  desc->multisample_type, desc->multisample_quality, desc->usage, desc->access,
365  desc->width, desc->height, desc->depth, offset, parent, parent_ops, resource_ops)))
366  {
367  static unsigned int once;
368 
369  /* DXTn 3D textures are not supported. Do not write the ERR for them. */
370  if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3
371  || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5)
373  && desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !once++)
374  ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n");
375 
376  WARN("Failed to initialize resource, returning %#x\n", hr);
377  return hr;
378  }
382 
383  texture->texture_ops = texture_ops;
384 
385  texture->layer_count = layer_count;
386  texture->level_count = level_count;
387  texture->lod = 0;
396  {
397  if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP))
398  WARN("Format doesn't support mipmaps generation, "
399  "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n");
400  else
402  }
403 
404  return WINED3D_OK;
405 }
406 
407 /* Context activation is done by the caller. */
409 #if !defined(STAGING_CSMT)
410  unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
411 {
412  GLuint *buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object;
413 
414  GL_EXTCALL(glDeleteBuffers(1, buffer_object));
415  checkGLcall("glDeleteBuffers");
416 
417  TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n",
418  *buffer_object, texture, sub_resource_idx);
419 
421  *buffer_object = 0;
422 #else /* STAGING_CSMT */
423  unsigned int sub_resource_idx, struct wined3d_context *context)
424 {
425  struct wined3d_gl_bo *buffer = texture->sub_resources[sub_resource_idx].buffer;
426  GLuint name = buffer->name;
427 
428  wined3d_device_release_bo(texture->resource.device, buffer, context);
429  texture->sub_resources[sub_resource_idx].buffer = NULL;
431 
432  TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n",
433  name, texture, sub_resource_idx);
434 #endif /* STAGING_CSMT */
435 }
436 
438 {
439  unsigned int sub_count = texture->level_count * texture->layer_count;
440  const struct wined3d_device *device = texture->resource.device;
441  DWORD map_binding = texture->update_map_binding;
442  struct wined3d_context *context = NULL;
443  unsigned int i;
444 
445  if (device->d3d_initialized)
447 
448  for (i = 0; i < sub_count; ++i)
449  {
450  if (texture->sub_resources[i].locations == texture->resource.map_binding
451  && !wined3d_texture_load_location(texture, i, context, map_binding))
452  ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding));
453  if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER)
454 #if !defined(STAGING_CSMT)
456 #else /* STAGING_CSMT */
458 #endif /* STAGING_CSMT */
459  }
460 
461  if (context)
463 
464  texture->resource.map_binding = map_binding;
465  texture->update_map_binding = 0;
466 }
467 
469 {
470  texture->update_map_binding = map_binding;
471  if (!texture->resource.map_count)
473 }
474 
475 /* A GL context is provided by the caller */
476 static void gltexture_delete(struct wined3d_device *device, const struct wined3d_gl_info *gl_info,
477  struct gl_texture *tex)
478 {
480  gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex->name);
481  tex->name = 0;
482 }
483 
485 {
486  const struct wined3d_format *format = texture->resource.format;
487 
488  /* TODO: NVIDIA expose their Coverage Sample Anti-Aliasing (CSAA)
489  * feature through type == MULTISAMPLE_XX and quality != 0. This could
490  * be mapped to GL_NV_framebuffer_multisample_coverage.
491  *
492  * AMD have a similar feature called Enhanced Quality Anti-Aliasing
493  * (EQAA), but it does not have an equivalent OpenGL extension. */
494 
495  /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality
496  * levels as the count of advertised multisample types for the texture
497  * format. */
498  if (texture->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
499  {
500  unsigned int i, count = 0;
501 
502  for (i = 0; i < sizeof(format->multisample_types) * CHAR_BIT; ++i)
503  {
504  if (format->multisample_types & 1u << i)
505  {
506  if (texture->resource.multisample_quality == count++)
507  break;
508  }
509  }
510  return i + 1;
511  }
512 
513  return texture->resource.multisample_type;
514 }
515 
516 /* Context activation is done by the caller. */
517 /* The caller is responsible for binding the correct texture. */
519  GLenum gl_internal_format, const struct wined3d_format *format,
520  const struct wined3d_gl_info *gl_info)
521 {
522  unsigned int level, level_count, layer, layer_count;
524  GLenum target;
525 
526  level_count = texture->level_count;
527  layer_count = texture->target == GL_TEXTURE_2D_ARRAY ? 1 : texture->layer_count;
528 
529  for (layer = 0; layer < layer_count; ++layer)
530  {
532 
533  for (level = 0; level < level_count; ++level)
534  {
537  if (texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
538  {
539  height *= format->height_scale.numerator;
540  height /= format->height_scale.denominator;
541  }
542 
543  TRACE("texture %p, layer %u, level %u, target %#x, width %u, height %u.\n",
545 
546  if (texture->target == GL_TEXTURE_2D_ARRAY)
547  {
548  GL_EXTCALL(glTexImage3D(target, level, gl_internal_format, width, height,
549  texture->layer_count, 0, format->glFormat, format->glType, NULL));
550  checkGLcall("glTexImage3D");
551  }
552  else
553  {
554  gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format,
555  width, height, 0, format->glFormat, format->glType, NULL);
556  checkGLcall("glTexImage2D");
557  }
558  }
559  }
560 }
561 
562 /* Context activation is done by the caller. */
563 /* The caller is responsible for binding the correct texture. */
565  GLenum gl_internal_format, const struct wined3d_gl_info *gl_info)
566 {
570 
571  switch (texture->target)
572  {
573  case GL_TEXTURE_2D_ARRAY:
574  GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count,
575  gl_internal_format, width, height, texture->layer_count));
576  break;
578  GL_EXTCALL(glTexStorage2DMultisample(texture->target, samples,
579  gl_internal_format, width, height, GL_FALSE));
580  break;
582  GL_EXTCALL(glTexStorage3DMultisample(texture->target, samples,
583  gl_internal_format, width, height, texture->layer_count, GL_FALSE));
584  break;
585  default:
586  GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
587  gl_internal_format, width, height));
588  break;
589  }
590 
591  checkGLcall("allocate immutable storage");
592 }
593 
595 {
596  struct wined3d_device *device = texture->resource.device;
597  const struct wined3d_gl_info *gl_info = NULL;
598  struct wined3d_context *context = NULL;
599 
600  if (texture->texture_rgb.name || texture->texture_srgb.name
601  || texture->rb_multisample || texture->rb_resolved)
602  {
604  gl_info = context->gl_info;
605  }
606 
607  if (texture->texture_rgb.name)
608  gltexture_delete(device, context->gl_info, &texture->texture_rgb);
609 
610  if (texture->texture_srgb.name)
611  gltexture_delete(device, context->gl_info, &texture->texture_srgb);
612 
613  if (texture->rb_multisample)
614  {
615  TRACE("Deleting multisample renderbuffer %u.\n", texture->rb_multisample);
616  context_gl_resource_released(device, texture->rb_multisample, TRUE);
617  gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_multisample);
618  texture->rb_multisample = 0;
619  }
620 
621  if (texture->rb_resolved)
622  {
623  TRACE("Deleting resolved renderbuffer %u.\n", texture->rb_resolved);
625  gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_resolved);
626  texture->rb_resolved = 0;
627  }
628 
630 
632 
633  resource_unload(&texture->resource);
634 }
635 
637 {
638  unsigned int sub_count = texture->level_count * texture->layer_count;
639  struct wined3d_texture_sub_resource *sub_resource;
640  unsigned int i;
641 
642  for (i = 0; i < sub_count; ++i)
643  {
644  sub_resource = &texture->sub_resources[i];
645  if (sub_resource->parent)
646  {
647  TRACE("sub-resource %u.\n", i);
648  sub_resource->parent_ops->wined3d_object_destroyed(sub_resource->parent);
649  sub_resource->parent = NULL;
650  }
651  }
652 }
653 
655 {
656  unsigned int sub_count = texture->level_count * texture->layer_count;
657  struct wined3d_device *device = texture->resource.device;
658  struct wined3d_context *context = NULL;
659 #if !defined(STAGING_CSMT)
660  const struct wined3d_gl_info *gl_info;
661  GLuint buffer_object;
662 #else /* STAGING_CSMT */
663  struct wined3d_gl_bo *buffer;
664 #endif /* STAGING_CSMT */
665  unsigned int i;
666 
667  TRACE("texture %p.\n", texture);
668 
669  for (i = 0; i < sub_count; ++i)
670  {
671 #if !defined(STAGING_CSMT)
672  if (!(buffer_object = texture->sub_resources[i].buffer_object))
673  continue;
674 
675  TRACE("Deleting buffer object %u.\n", buffer_object);
676 #else /* STAGING_CSMT */
677  if (!(buffer = texture->sub_resources[i].buffer))
678  continue;
679 
680  TRACE("Deleting buffer object %u.\n", buffer->name);
681 #endif /* STAGING_CSMT */
682 
683  /* We may not be able to get a context in wined3d_texture_cleanup() in
684  * general, but if a buffer object was previously created we can. */
685  if (!context)
686 #if !defined(STAGING_CSMT)
687  {
689  gl_info = context->gl_info;
690  }
691 
692  GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
693 #else /* STAGING_CSMT */
695 
696  wined3d_device_release_bo(device, buffer, context);
697  texture->sub_resources[i].buffer = NULL;
698 #endif /* STAGING_CSMT */
699  }
700  if (context)
702 
703  texture->texture_ops->texture_cleanup_sub_resources(texture);
704  if (texture->overlay_info)
705  {
706  for (i = 0; i < sub_count; ++i)
707  {
708  struct wined3d_overlay_info *info = &texture->overlay_info[i];
709  struct wined3d_overlay_info *overlay, *cur;
710 
711  list_remove(&info->entry);
712  LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &info->overlays, struct wined3d_overlay_info, entry)
713  {
714  list_remove(&overlay->entry);
715  }
716  }
717  heap_free(texture->overlay_info);
718  }
720 }
721 
723 {
724  texture->swapchain = swapchain;
726 }
727 
728 /* Context activation is done by the caller. */
730  struct wined3d_context *context, BOOL srgb)
731 {
732  const struct wined3d_gl_info *gl_info = context->gl_info;
733  const struct wined3d_format *format = texture->resource.format;
734  const struct color_fixup_desc fixup = format->color_fixup;
735  struct gl_texture *gl_tex;
736  GLenum target;
737 
738  TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
739 
741  srgb = FALSE;
742 
743  /* sRGB mode cache for preload() calls outside drawprim. */
744  if (srgb)
746  else
747  texture->flags &= ~WINED3D_TEXTURE_IS_SRGB;
748 
749  gl_tex = wined3d_texture_get_gl_texture(texture, srgb);
750  target = texture->target;
751 
752  if (gl_tex->name)
753  {
755  return;
756  }
757 
758  gl_info->gl_ops.gl.p_glGenTextures(1, &gl_tex->name);
759  checkGLcall("glGenTextures");
760  TRACE("Generated texture %d.\n", gl_tex->name);
761 
762  if (!gl_tex->name)
763  {
764  ERR("Failed to generate a texture name.\n");
765  return;
766  }
767 
768  /* Initialise the state of the texture object to the OpenGL defaults, not
769  * the wined3d defaults. */
770  gl_tex->sampler_desc.address_u = WINED3D_TADDRESS_WRAP;
771  gl_tex->sampler_desc.address_v = WINED3D_TADDRESS_WRAP;
772  gl_tex->sampler_desc.address_w = WINED3D_TADDRESS_WRAP;
773  memset(gl_tex->sampler_desc.border_color, 0, sizeof(gl_tex->sampler_desc.border_color));
774  gl_tex->sampler_desc.mag_filter = WINED3D_TEXF_LINEAR;
775  gl_tex->sampler_desc.min_filter = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
776  gl_tex->sampler_desc.mip_filter = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
777  gl_tex->sampler_desc.lod_bias = 0.0f;
778  gl_tex->sampler_desc.min_lod = -1000.0f;
779  gl_tex->sampler_desc.max_lod = 1000.0f;
780  gl_tex->sampler_desc.max_anisotropy = 1;
781  gl_tex->sampler_desc.compare = FALSE;
782  gl_tex->sampler_desc.comparison_func = WINED3D_CMP_LESSEQUAL;
783  if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
784  gl_tex->sampler_desc.srgb_decode = TRUE;
785  else
786  gl_tex->sampler_desc.srgb_decode = srgb;
787  gl_tex->base_level = 0;
789 
791 
792  /* For a new texture we have to set the texture levels after binding the
793  * texture. Beware that texture rectangles do not support mipmapping, but
794  * set the maxmiplevel if we're relying on the partial
795  * GL_ARB_texture_non_power_of_two emulation with texture rectangles.
796  * (I.e., do not care about cond_np2 here, just look for
797  * GL_TEXTURE_RECTANGLE_ARB.) */
799  {
800  TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", texture->level_count - 1);
801  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1);
802  checkGLcall("glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count)");
803  }
804 
806  {
807  /* Cubemaps are always set to clamp, regardless of the sampler state. */
808  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
809  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
810  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
811  }
812 
813  if (texture->flags & WINED3D_TEXTURE_COND_NP2)
814  {
815  /* Conditinal non power of two textures use a different clamping
816  * default. If we're using the GL_WINE_normalized_texrect partial
817  * driver emulation, we're dealing with a GL_TEXTURE_2D texture which
818  * has the address mode set to repeat - something that prevents us
819  * from hitting the accelerated codepath. Thus manually set the GL
820  * state. The same applies to filtering. Even if the texture has only
821  * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW
822  * fallback on macos. */
823  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
824  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
825  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
826  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
827  checkGLcall("glTexParameteri");
828  gl_tex->sampler_desc.address_u = WINED3D_TADDRESS_CLAMP;
829  gl_tex->sampler_desc.address_v = WINED3D_TADDRESS_CLAMP;
830  gl_tex->sampler_desc.mag_filter = WINED3D_TEXF_POINT;
831  gl_tex->sampler_desc.min_filter = WINED3D_TEXF_POINT;
832  gl_tex->sampler_desc.mip_filter = WINED3D_TEXF_NONE;
833  }
834 
836  {
837  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
838  checkGLcall("glTexParameteri(GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY)");
839  }
840 
841  if (!is_identity_fixup(fixup) && can_use_texture_swizzle(gl_info, format))
842  {
843  static const GLenum swizzle_source[] =
844  {
845  GL_ZERO, /* CHANNEL_SOURCE_ZERO */
846  GL_ONE, /* CHANNEL_SOURCE_ONE */
847  GL_RED, /* CHANNEL_SOURCE_X */
848  GL_GREEN, /* CHANNEL_SOURCE_Y */
849  GL_BLUE, /* CHANNEL_SOURCE_Z */
850  GL_ALPHA, /* CHANNEL_SOURCE_W */
851  };
852  struct
853  {
854  GLint x, y, z, w;
855  }
856  swizzle;
857 
858  swizzle.x = swizzle_source[fixup.x_source];
859  swizzle.y = swizzle_source[fixup.y_source];
860  swizzle.z = swizzle_source[fixup.z_source];
861  swizzle.w = swizzle_source[fixup.w_source];
862  gl_info->gl_ops.gl.p_glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, &swizzle.x);
863  checkGLcall("glTexParameteriv(GL_TEXTURE_SWIZZLE_RGBA)");
864  }
865 }
866 
867 /* Context activation is done by the caller. */
869  struct wined3d_context *context, BOOL srgb)
870 {
871  /* We don't need a specific texture unit, but after binding the texture
872  * the current unit is dirty. Read the unit back instead of switching to
873  * 0, this avoids messing around with the state manager's GL states. The
874  * current texture unit should always be a valid one.
875  *
876  * To be more specific, this is tricky because we can implicitly be
877  * called from sampler() in state.c. This means we can't touch anything
878  * other than whatever happens to be the currently active texture, or we
879  * would risk marking already applied sampler states dirty again. */
880  if (context->active_texture < ARRAY_SIZE(context->rev_tex_unit_map))
881  {
882  DWORD active_sampler = context->rev_tex_unit_map[context->active_texture];
883  if (active_sampler != WINED3D_UNMAPPED_STAGE)
885  }
886  /* FIXME: Ideally we'd only do this when touching a binding that's used by
887  * a shader. */
890 
892 }
893 
894 /* Context activation is done by the caller (state handler). */
895 /* This function relies on the correct texture being bound and loaded. */
897  const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context *context)
898 {
899  const struct wined3d_gl_info *gl_info = context->gl_info;
900  GLenum target = texture->target;
901  struct gl_texture *gl_tex;
902  DWORD state;
903 
904  TRACE("texture %p, sampler_desc %p, context %p.\n", texture, sampler_desc, context);
905 
907 
908  state = sampler_desc->address_u;
909  if (state != gl_tex->sampler_desc.address_u)
910  {
911  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S,
913  gl_tex->sampler_desc.address_u = state;
914  }
915 
916  state = sampler_desc->address_v;
917  if (state != gl_tex->sampler_desc.address_v)
918  {
919  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T,
921  gl_tex->sampler_desc.address_v = state;
922  }
923 
924  state = sampler_desc->address_w;
925  if (state != gl_tex->sampler_desc.address_w)
926  {
927  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R,
929  gl_tex->sampler_desc.address_w = state;
930  }
931 
932  if (memcmp(gl_tex->sampler_desc.border_color, sampler_desc->border_color,
933  sizeof(gl_tex->sampler_desc.border_color)))
934  {
935  gl_info->gl_ops.gl.p_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, &sampler_desc->border_color[0]);
936  memcpy(gl_tex->sampler_desc.border_color, sampler_desc->border_color,
937  sizeof(gl_tex->sampler_desc.border_color));
938  }
939 
940  state = sampler_desc->mag_filter;
941  if (state != gl_tex->sampler_desc.mag_filter)
942  {
943  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(state));
944  gl_tex->sampler_desc.mag_filter = state;
945  }
946 
947  if (sampler_desc->min_filter != gl_tex->sampler_desc.min_filter
948  || sampler_desc->mip_filter != gl_tex->sampler_desc.mip_filter)
949  {
950  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
951  wined3d_gl_min_mip_filter(sampler_desc->min_filter, sampler_desc->mip_filter));
952  gl_tex->sampler_desc.min_filter = sampler_desc->min_filter;
953  gl_tex->sampler_desc.mip_filter = sampler_desc->mip_filter;
954  }
955 
956  state = sampler_desc->max_anisotropy;
957  if (state != gl_tex->sampler_desc.max_anisotropy)
958  {
960  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY, state);
961  else
962  WARN("Anisotropic filtering not supported.\n");
963  gl_tex->sampler_desc.max_anisotropy = state;
964  }
965 
966  if (!sampler_desc->srgb_decode != !gl_tex->sampler_desc.srgb_decode
967  && (context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)
968  && gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
969  {
970  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
972  gl_tex->sampler_desc.srgb_decode = sampler_desc->srgb_decode;
973  }
974 
975  if (!sampler_desc->compare != !gl_tex->sampler_desc.compare)
976  {
977  if (sampler_desc->compare)
978  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
979  else
980  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
981  gl_tex->sampler_desc.compare = sampler_desc->compare;
982  }
983 
984  checkGLcall("Texture parameter application");
985 
986  if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
987  {
988  gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
990  checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
991  }
992 }
993 
995 {
996  ULONG refcount;
997 
998  TRACE("texture %p, swapchain %p.\n", texture, texture->swapchain);
999 
1000  if (texture->swapchain)
1001  return wined3d_swapchain_incref(texture->swapchain);
1002 
1003  refcount = InterlockedIncrement(&texture->resource.ref);
1004  TRACE("%p increasing refcount to %u.\n", texture, refcount);
1005 
1006  return refcount;
1007 }
1008 
1010 {
1012  resource_cleanup(&texture->resource);
1013  wined3d_resource_wait_idle(&texture->resource);
1015 }
1016 
1017 static void wined3d_texture_destroy_object(void *object)
1018 {
1019  wined3d_texture_cleanup(object);
1020  heap_free(object);
1021 }
1022 
1024 {
1025  ULONG refcount;
1026 
1027  TRACE("texture %p, swapchain %p.\n", texture, texture->swapchain);
1028 
1029  if (texture->swapchain)
1030  return wined3d_swapchain_decref(texture->swapchain);
1031 
1032  refcount = InterlockedDecrement(&texture->resource.ref);
1033  TRACE("%p decreasing refcount to %u.\n", texture, refcount);
1034 
1035  if (!refcount)
1036  {
1037  /* Wait for the texture to become idle if it's using user memory,
1038  * since the application is allowed to free that memory once the
1039  * texture is destroyed. Note that this implies that
1040  * wined3d_texture_destroy_object() can't access that memory either. */
1041  if (texture->user_memory)
1042  wined3d_resource_wait_idle(&texture->resource);
1044  texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
1045  resource_cleanup(&texture->resource);
1047  }
1048 
1049  return refcount;
1050 }
1051 
1053 {
1054  TRACE("texture %p.\n", texture);
1055 
1056  return &texture->resource;
1057 }
1058 
1059 static BOOL color_key_equal(const struct wined3d_color_key *c1, struct wined3d_color_key *c2)
1060 {
1063 }
1064 
1065 /* Context activation is done by the caller */
1067  struct wined3d_context *context, BOOL srgb)
1068 {
1069  UINT sub_count = texture->level_count * texture->layer_count;
1070  const struct wined3d_d3d_info *d3d_info = context->d3d_info;
1071  DWORD flag;
1072  UINT i;
1073 
1074  TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
1075 
1077  srgb = FALSE;
1078 
1079  if (srgb)
1081  else
1083 
1084  if (!d3d_info->shader_color_key
1085  && (!(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
1086  != !(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
1087  || (texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY
1088  && !color_key_equal(&texture->async.gl_color_key, &texture->async.src_blt_color_key))))
1089  {
1090  unsigned int sub_count = texture->level_count * texture->layer_count;
1091  unsigned int i;
1092 
1093  TRACE("Reloading because of color key value change.\n");
1094  for (i = 0; i < sub_count; i++)
1095  {
1096  if (!wined3d_texture_load_location(texture, i, context, texture->resource.map_binding))
1097  ERR("Failed to load location %s.\n", wined3d_debug_location(texture->resource.map_binding));
1098  else
1099  wined3d_texture_invalidate_location(texture, i, ~texture->resource.map_binding);
1100  }
1101 
1102  texture->async.gl_color_key = texture->async.src_blt_color_key;
1103  }
1104 
1105  if (texture->flags & flag)
1106  {
1107  TRACE("Texture %p not dirty, nothing to do.\n", texture);
1108  return;
1109  }
1110 
1111  /* Reload the surfaces if the texture is marked dirty. */
1112  for (i = 0; i < sub_count; ++i)
1113  {
1116  ERR("Failed to load location (srgb %#x).\n", srgb);
1117  }
1118  texture->flags |= flag;
1119 }
1120 
1122 {
1123  TRACE("texture %p.\n", texture);
1124 
1125  return texture->resource.parent;
1126 }
1127 
1129  unsigned int level, const struct wined3d_box *box)
1130 {
1131  const struct wined3d_format *format = texture->resource.format;
1132  unsigned int width_mask, height_mask, width, height, depth;
1133 
1137 
1138  if (box->left >= box->right || box->right > width
1139  || box->top >= box->bottom || box->bottom > height
1140  || box->front >= box->back || box->back > depth)
1141  {
1142  WARN("Box %s is invalid.\n", debug_box(box));
1143  return WINEDDERR_INVALIDRECT;
1144  }
1145 
1146  if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
1147  {
1148  /* This assumes power of two block sizes, but NPOT block sizes would
1149  * be silly anyway.
1150  *
1151  * This also assumes that the format's block depth is 1. */
1152  width_mask = format->block_width - 1;
1153  height_mask = format->block_height - 1;
1154 
1155  if ((box->left & width_mask) || (box->top & height_mask)
1156  || (box->right & width_mask && box->right != width)
1157  || (box->bottom & height_mask && box->bottom != height))
1158  {
1159  WARN("Box %s is misaligned for %ux%u blocks.\n",
1160  debug_box(box), format->block_width, format->block_height);
1161  return WINED3DERR_INVALIDCALL;
1162  }
1163  }
1164 
1165  return WINED3D_OK;
1166 }
1167 
1169  unsigned int level, unsigned int *row_pitch, unsigned int *slice_pitch)
1170 {
1171  const struct wined3d_resource *resource = &texture->resource;
1174 
1175  if (texture->row_pitch)
1176  {
1177  *row_pitch = texture->row_pitch;
1178  *slice_pitch = texture->slice_pitch;
1179  return;
1180  }
1181 
1182  wined3d_format_calculate_pitch(resource->format, resource->device->surface_alignment,
1183  width, height, row_pitch, slice_pitch);
1184 }
1185 
1187 {
1188  DWORD old = texture->lod;
1189 
1190  TRACE("texture %p, lod %u.\n", texture, lod);
1191 
1192  /* The d3d9:texture test shows that SetLOD is ignored on non-managed
1193  * textures. The call always returns 0, and GetLOD always returns 0. */
1194  if (!wined3d_resource_access_is_managed(texture->resource.access))
1195  {
1196  TRACE("Ignoring LOD on texture with resource access %s.\n",
1197  wined3d_debug_resource_access(texture->resource.access));
1198  return 0;
1199  }
1200 
1201  if (lod >= texture->level_count)
1202  lod = texture->level_count - 1;
1203 
1204  if (texture->lod != lod)
1205  {
1206  struct wined3d_device *device = texture->resource.device;
1207 
1208  wined3d_resource_wait_idle(&texture->resource);
1209  texture->lod = lod;
1210 
1211  texture->texture_rgb.base_level = ~0u;
1212  texture->texture_srgb.base_level = ~0u;
1213  if (texture->resource.bind_count)
1215  device->state.sampler_states[texture->sampler][WINED3D_SAMP_MAX_MIP_LEVEL]);
1216  }
1217 
1218  return old;
1219 }
1220 
1222 {
1223  TRACE("texture %p, returning %u.\n", texture, texture->lod);
1224 
1225  return texture->lod;
1226 }
1227 
1229 {
1230  TRACE("texture %p, returning %u.\n", texture, texture->level_count);
1231 
1232  return texture->level_count;
1233 }
1234 
1236  DWORD flags, const struct wined3d_color_key *color_key)
1237 {
1238  struct wined3d_device *device = texture->resource.device;
1239  static const DWORD all_flags = WINED3D_CKEY_DST_BLT | WINED3D_CKEY_DST_OVERLAY
1241 
1242  TRACE("texture %p, flags %#x, color_key %p.\n", texture, flags, color_key);
1243 
1244  if (flags & ~all_flags)
1245  {
1246  WARN("Invalid flags passed, returning WINED3DERR_INVALIDCALL.\n");
1247  return WINED3DERR_INVALIDCALL;
1248  }
1249 
1251 
1252  return WINED3D_OK;
1253 }
1254 
1255 static void texture2d_create_dc(void *object)
1256 {
1257  struct wined3d_surface *surface = object;
1258  struct wined3d_context *context = NULL;
1259  const struct wined3d_format *format;
1260  unsigned int row_pitch, slice_pitch;
1261  struct wined3d_texture *texture;
1262  struct wined3d_bo_address data;
1264  unsigned int sub_resource_idx;
1265  struct wined3d_device *device;
1266  NTSTATUS status;
1267 
1268  TRACE("surface %p.\n", surface);
1269 
1270  texture = surface->container;
1271  sub_resource_idx = surface_get_sub_resource_idx(surface);
1272  device = texture->resource.device;
1273 
1274  format = texture->resource.format;
1275  if (!format->ddi_format)
1276  {
1277  WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id));
1278  return;
1279  }
1280 
1281  if (device->d3d_initialized)
1283 
1284  wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding);
1285  wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
1286  wined3d_texture_get_pitch(texture, surface->texture_level, &row_pitch, &slice_pitch);
1287  wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
1289  texture->sub_resources[sub_resource_idx].size,
1291 
1292  if (context)
1294 
1295  desc.Format = format->ddi_format;
1298  desc.Pitch = row_pitch;
1299  desc.hDeviceDc = CreateCompatibleDC(NULL);
1300  desc.pColorTable = NULL;
1301 
1303  DeleteDC(desc.hDeviceDc);
1304  if (status)
1305  {
1306  WARN("Failed to create DC, status %#x.\n", status);
1307  return;
1308  }
1309 
1310  surface->dc = desc.hDc;
1311  surface->bitmap = desc.hBitmap;
1312 
1313  TRACE("Created DC %p, bitmap %p for surface %p.\n", surface->dc, surface->bitmap, surface);
1314 }
1315 
1316 static void texture2d_destroy_dc(void *object)
1317 {
1318  struct wined3d_surface *surface = object;
1319  D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
1320  struct wined3d_context *context = NULL;
1321  struct wined3d_texture *texture;
1322  struct wined3d_bo_address data;
1323  unsigned int sub_resource_idx;
1324  struct wined3d_device *device;
1325  NTSTATUS status;
1326 
1327  texture = surface->container;
1328  sub_resource_idx = surface_get_sub_resource_idx(surface);
1329  device = texture->resource.device;
1330 
1331  if (!surface->dc)
1332  {
1333  ERR("Surface %p has no DC.\n", surface);
1334  return;
1335  }
1336 
1337  TRACE("dc %p, bitmap %p.\n", surface->dc, surface->bitmap);
1338 
1339  destroy_desc.hDc = surface->dc;
1340  destroy_desc.hBitmap = surface->bitmap;
1341  if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc)))
1342  ERR("Failed to destroy dc, status %#x.\n", status);
1343  surface->dc = NULL;
1344  surface->bitmap = NULL;
1345 
1346  if (device->d3d_initialized)
1348 
1349  wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
1351 
1352  if (context)
1354 }
1355 
1357  enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type,
1358  UINT multisample_quality, void *mem, UINT pitch)
1359 {
1360  struct wined3d_device *device = texture->resource.device;
1361  const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
1362  const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, texture->resource.usage);
1363  UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
1364  struct wined3d_texture_sub_resource *sub_resource;
1365  struct wined3d_surface *surface;
1366  DWORD valid_location = 0;
1367  BOOL create_dib = FALSE;
1368 
1369  TRACE("texture %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, "
1370  "mem %p, pitch %u.\n",
1371  texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_quality, mem, pitch);
1372 
1373  if (!resource_size)
1374  return WINED3DERR_INVALIDCALL;
1375 
1376  if (texture->level_count * texture->layer_count > 1)
1377  {
1378  WARN("Texture has multiple sub-resources, not supported.\n");
1379  return WINED3DERR_INVALIDCALL;
1380  }
1381 
1382  if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
1383  {
1384  WARN("Not supported on %s.\n", debug_d3dresourcetype(texture->resource.type));
1385  return WINED3DERR_INVALIDCALL;
1386  }
1387 
1388  if (texture->resource.type == WINED3D_RTYPE_TEXTURE_1D)
1389  {
1390  FIXME("Not yet supported for 1D textures.\n");
1391  return WINED3DERR_INVALIDCALL;
1392  }
1393 
1394  if (texture->resource.map_count)
1395  {
1396  WARN("Texture is mapped.\n");
1397  return WINED3DERR_INVALIDCALL;
1398  }
1399 
1400  /* We have no way of supporting a pitch that is not a multiple of the pixel
1401  * byte width short of uploading the texture row-by-row.
1402  * Fortunately that's not an issue since D3D9Ex doesn't allow a custom pitch
1403  * for user-memory textures (it always expects packed data) while DirectDraw
1404  * requires a 4-byte aligned pitch and doesn't support texture formats
1405  * larger than 4 bytes per pixel nor any format using 3 bytes per pixel.
1406  * This check is here to verify that the assumption holds. */
1407  if (pitch % texture->resource.format->byte_count)
1408  {
1409  WARN("Pitch unsupported, not a multiple of the texture format byte width.\n");
1410  return WINED3DERR_INVALIDCALL;
1411  }
1412 
1413  if (device->d3d_initialized)
1415  wined3d_resource_wait_idle(&texture->resource);
1416 
1417  sub_resource = &texture->sub_resources[0];
1418  surface = sub_resource->u.surface;
1419  if (surface->dc)
1420  {
1422  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
1423  create_dib = TRUE;
1424  }
1425 
1427 
1428  if ((texture->row_pitch = pitch))
1429  texture->slice_pitch = height * pitch;
1430  else
1431  /* User memory surfaces don't have the regular surface alignment. */
1433  &texture->row_pitch, &texture->slice_pitch);
1434 
1435  texture->resource.format = format;
1436  texture->resource.multisample_type = multisample_type;
1437  texture->resource.multisample_quality = multisample_quality;
1438  texture->resource.width = width;
1439  texture->resource.height = height;
1440  texture->resource.size = texture->slice_pitch;
1441  sub_resource->size = texture->slice_pitch;
1442  sub_resource->locations = WINED3D_LOCATION_DISCARDED;
1443 
1444  if (multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
1446  else
1447  texture->target = GL_TEXTURE_2D;
1448 
1451  {
1453  texture->pow2_width = texture->pow2_height = 1;
1454  while (texture->pow2_width < width)
1455  texture->pow2_width <<= 1;
1456  while (texture->pow2_height < height)
1457  texture->pow2_height <<= 1;
1458  }
1459  else
1460  {
1462  texture->pow2_width = width;
1463  texture->pow2_height = height;
1464  }
1465 
1466  if ((texture->user_memory = mem))
1467  {
1468  texture->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
1469  valid_location = WINED3D_LOCATION_USER_MEMORY;
1470  }
1471  else
1472  {
1474  valid_location = WINED3D_LOCATION_SYSMEM;
1475  }
1476 
1477  /* The format might be changed to a format that needs conversion.
1478  * If the surface didn't use PBOs previously but could now, don't
1479  * change it - whatever made us not use PBOs might come back, e.g.
1480  * color keys. */
1481  if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, gl_info))
1482  texture->resource.map_binding = WINED3D_LOCATION_SYSMEM;
1483 
1484  wined3d_texture_validate_location(texture, 0, valid_location);
1485  wined3d_texture_invalidate_location(texture, 0, ~valid_location);
1486 
1487  if (create_dib)
1488  {
1490  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
1491  }
1492 
1493  return WINED3D_OK;
1494 }
1495 
1496 /* Context activation is done by the caller. */
1498 #if !defined(STAGING_CSMT)
1499  unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
1500 #else /* STAGING_CSMT */
1501  unsigned int sub_resource_idx, struct wined3d_context *context)
1502 #endif /* STAGING_CSMT */
1503 {
1504  struct wined3d_texture_sub_resource *sub_resource;
1505 
1506  sub_resource = &texture->sub_resources[sub_resource_idx];
1507 #if !defined(STAGING_CSMT)
1508  if (sub_resource->buffer_object)
1509  return;
1510 
1511  GL_EXTCALL(glGenBuffers(1, &sub_resource->buffer_object));
1512  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sub_resource->buffer_object));
1513  GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sub_resource->size, NULL, GL_STREAM_DRAW));
1514  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
1515  checkGLcall("Create buffer object");
1516 
1517  TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
1518  sub_resource->buffer_object, texture, sub_resource_idx);
1519 #else /* STAGING_CSMT */
1520  if (sub_resource->buffer)
1521  return;
1522 
1523  sub_resource->buffer = wined3d_device_get_bo(texture->resource.device,
1524  sub_resource->size, GL_STREAM_DRAW, GL_PIXEL_UNPACK_BUFFER, context);
1525 
1526  TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
1527  sub_resource->buffer->name, texture, sub_resource_idx);
1528 #endif /* STAGING_CSMT */
1529 }
1530 
1532 {
1533  unsigned int sub_count = texture->level_count * texture->layer_count;
1534  unsigned int i;
1535 
1538  texture->async.flags &= ~WINED3D_TEXTURE_ASYNC_COLOR_KEY;
1539  for (i = 0; i < sub_count; ++i)
1540  {
1543  }
1544 }
1545 
1547 {
1549  const struct wined3d_d3d_info *d3d_info = context->d3d_info;
1550 
1551  if (!d3d_info->shader_color_key
1552  && !(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
1553  != !(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT))
1554  {
1556 
1557  if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
1558  texture->async.flags |= WINED3D_TEXTURE_ASYNC_COLOR_KEY;
1559  }
1560 
1561  if (texture->flags & alloc_flag)
1562  return;
1563 
1564  texture->texture_ops->texture_prepare_texture(texture, context, srgb);
1565  texture->flags |= alloc_flag;
1566 }
1567 
1569  const struct wined3d_gl_info *gl_info, BOOL multisample)
1570 {
1571  const struct wined3d_format *format = texture->resource.format;
1572 
1573  if (multisample)
1574  {
1575  DWORD samples;
1576 
1577  if (texture->rb_multisample)
1578  return;
1579 
1581 
1582  gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_multisample);
1583  gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_multisample);
1584  gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
1585  format->glInternal, texture->resource.width, texture->resource.height);
1586  checkGLcall("glRenderbufferStorageMultisample()");
1587  TRACE("Created multisample rb %u.\n", texture->rb_multisample);
1588  }
1589  else
1590  {
1591  if (texture->rb_resolved)
1592  return;
1593 
1594  gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_resolved);
1595  gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_resolved);
1596  gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format->glInternal,
1597  texture->resource.width, texture->resource.height);
1598  checkGLcall("glRenderbufferStorage()");
1599  TRACE("Created resolved rb %u.\n", texture->rb_resolved);
1600  }
1601 }
1602 
1603 /* Context activation is done by the caller. Context may be NULL in
1604  * WINED3D_NO3D mode. */
1605 BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
1607 {
1608  switch (location)
1609  {
1611  if (texture->resource.heap_memory)
1612  return TRUE;
1613 
1614  if (!wined3d_resource_allocate_sysmem(&texture->resource))
1615  {
1616  ERR("Failed to allocate system memory.\n");
1617  return FALSE;
1618  }
1619  return TRUE;
1620 
1622  if (!texture->user_memory)
1623  ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->user_memory is NULL.\n");
1624  return TRUE;
1625 
1627 #if !defined(STAGING_CSMT)
1628  wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context->gl_info);
1629 #else /* STAGING_CSMT */
1631 #endif /* STAGING_CSMT */
1632  return TRUE;
1633 
1636  return TRUE;
1637 
1640  return TRUE;
1641 
1644  ERR("Texture %p does not have a drawable.\n", texture);
1645  return TRUE;
1646 
1649  return TRUE;
1650 
1653  return TRUE;
1654 
1655  default:
1656  ERR("Invalid location %s.\n", wined3d_debug_location(location));
1657  return FALSE;
1658  }
1659 }
1660 
1661 static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(struct wined3d_texture *texture,
1662  unsigned int sub_resource_idx)
1663 {
1664  UINT sub_count = texture->level_count * texture->layer_count;
1665 
1666  TRACE("texture %p, sub_resource_idx %u.\n", texture, sub_resource_idx);
1667 
1668  if (sub_resource_idx >= sub_count)
1669  {
1670  WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count);
1671  return NULL;
1672  }
1673 
1674  return &texture->sub_resources[sub_resource_idx];
1675 }
1676 
1678  UINT layer, const struct wined3d_box *dirty_region)
1679 {
1680  TRACE("texture %p, layer %u, dirty_region %s.\n", texture, layer, debug_box(dirty_region));
1681 
1682  if (layer >= texture->layer_count)
1683  {
1684  WARN("Invalid layer %u specified.\n", layer);
1685  return WINED3DERR_INVALIDCALL;
1686  }
1687 
1688  if (dirty_region)
1689  WARN("Ignoring dirty_region %s.\n", debug_box(dirty_region));
1690 
1692 
1693  return WINED3D_OK;
1694 }
1695 
1696 void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
1697  const struct wined3d_context *context, const struct wined3d_box *box,
1698  const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch)
1699 {
1700  texture->texture_ops->texture_upload_data(texture, sub_resource_idx,
1701  context, box, data, row_pitch, slice_pitch);
1702 }
1703 
1704 
1705 /* This call just uploads data, the caller is responsible for binding the
1706  * correct texture. */
1707 /* Context activation is done by the caller. */
1708 static void texture1d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
1709  const struct wined3d_context *context, const struct wined3d_box *box, const struct wined3d_const_bo_address *data,
1710  unsigned int row_pitch, unsigned int slice_pitch)
1711 {
1712  struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
1713  const struct wined3d_format *format = texture->resource.format;
1714  unsigned int level = sub_resource_idx % texture->level_count;
1715  const struct wined3d_gl_info *gl_info = context->gl_info;
1716  const void *mem = data->addr;
1717  void *converted_mem = NULL;
1718  unsigned int width, x, update_w;
1719  GLenum target;
1720 
1721  TRACE("texture %p, sub_resource_idx %u, context %p, box %p, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n",
1722  texture, sub_resource_idx, context, box, data->buffer_object, data->addr, row_pitch, slice_pitch);
1723 
1725 
1726  if (!box)
1727  {
1728  x = 0;
1729  update_w = width;
1730  }
1731  else
1732  {
1733  x = box->left;
1734  update_w = box->right - box->left;
1735  }
1736 
1737  if (format->upload)
1738  {
1739  unsigned int dst_row_pitch;
1740 
1741  if (data->buffer_object)
1742  ERR("Loading a converted texture from a PBO.\n");
1743  if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
1744  ERR("Converting a block-based format.\n");
1745 
1746  dst_row_pitch = update_w * format->conv_byte_count;
1747 
1748  converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_row_pitch);
1749  format->upload(data->addr, converted_mem, row_pitch, slice_pitch, dst_row_pitch, dst_row_pitch, update_w, 1, 1);
1750  mem = converted_mem;
1751  }
1752 
1753  if (data->buffer_object)
1754  {
1755  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
1756  checkGLcall("glBindBuffer");
1757  }
1758 
1760  if (target == GL_TEXTURE_1D_ARRAY)
1761  {
1762  gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, row_pitch / format->byte_count);
1763 
1764  gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, x, surface->texture_layer, update_w, 1, format->glFormat, format->glType, mem);
1765  checkGLcall("glTexSubImage2D");
1766 
1767  gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1768  }
1769  else
1770  {
1771  gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, x, update_w, format->glFormat, format->glType, mem);
1772  checkGLcall("glTexSubImage1D");
1773  }
1774 
1775  if (data->buffer_object)
1776  {
1777  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
1778  checkGLcall("glBindBuffer");
1779  }
1780 
1781  HeapFree(GetProcessHeap(), 0, converted_mem);
1782 }
1783 
1784 /* Context activation is done by the caller. */
1785 static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
1786  const struct wined3d_context *context, const struct wined3d_bo_address *data)
1787 {
1788  struct wined3d_surface *surface = texture->sub_resources[sub_resource_idx].u.surface;
1789  const struct wined3d_format *format = texture->resource.format;
1790  const struct wined3d_gl_info *gl_info = context->gl_info;
1791  struct wined3d_texture_sub_resource *sub_resource;
1792  BYTE *temporary_mem = NULL;
1793  void *mem;
1794  GLenum target;
1795 
1796  sub_resource = &texture->sub_resources[sub_resource_idx];
1797 
1798  if (format->conv_byte_count)
1799  {
1800  FIXME("Attempting to download a converted 1d texture, format %s.\n",
1801  debug_d3dformat(format->id));
1802  return;
1803  }
1804 
1806  if (target == GL_TEXTURE_1D_ARRAY)
1807  {
1808  WARN_(d3d_perf)("Downloading all miplevel layers to get the surface data for a single sub-resource.\n");
1809 
1810  if (!(temporary_mem = heap_calloc(texture->layer_count, sub_resource->size)))
1811  {
1812  ERR("Out of memory.\n");
1813  return;
1814  }
1815 
1816  mem = temporary_mem;
1817  }
1818  else if (data->buffer_object)
1819  {
1820  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
1821  checkGLcall("glBindBuffer");
1822  mem = data->addr;
1823  }
1824  else
1825  mem = data->addr;
1826 
1827  gl_info->gl_ops.gl.p_glGetTexImage(target, sub_resource_idx,
1828  format->glFormat, format->glType, mem);
1829  checkGLcall("glGetTexImage");
1830 
1831  if (temporary_mem)
1832  {
1833  void *src_data = temporary_mem + surface->texture_layer * sub_resource->size;
1834  if (data->buffer_object)
1835  {
1836  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
1837  checkGLcall("glBindBuffer");
1838  GL_EXTCALL(glBufferSubData(GL_PIXEL_PACK_BUFFER, 0, sub_resource->size, src_data));
1839  checkGLcall("glBufferSubData");
1840  }
1841  else
1842  {
1843  memcpy(data->addr, src_data, sub_resource->size);
1844  }
1845  }
1846 
1847  if (data->buffer_object)
1848  {
1849  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
1850  checkGLcall("glBindBuffer");
1851  }
1852 
1853  HeapFree(GetProcessHeap(), 0, temporary_mem);
1854 }
1855 
1856 /* Context activation is done by the caller. */
1857 static void texture1d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx,
1858  struct wined3d_context *context, BOOL dest_is_srgb)
1859 {
1860  struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
1861  unsigned int row_pitch, slice_pitch;
1862  struct wined3d_bo_address data;
1863 
1864  WARN_(d3d_perf)("Performing slow rgb/srgb 1d texture transfer.\n");
1865  data.buffer_object = 0;
1866  if (!(data.addr = HeapAlloc(GetProcessHeap(), 0, sub_resource->size)))
1867  return;
1868 
1869  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
1871  texture1d_download_data(texture, sub_resource_idx, context, &data);
1873  texture1d_upload_data(texture, sub_resource_idx, context, NULL,
1874  wined3d_const_bo_address(&data), row_pitch, slice_pitch);
1875 
1876  HeapFree(GetProcessHeap(), 0, data.addr);
1877 }
1878 
1879 /* Context activation is done by the caller. */
1880 static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
1882 {
1883  struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
1885  unsigned int row_pitch, slice_pitch;
1886 
1887  TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
1888  texture, sub_resource_idx, context, wined3d_debug_location(location));
1889 
1890  TRACE("Current resource location %s.\n", wined3d_debug_location(sub_resource->locations));
1891 
1892  if ((sub_resource->locations & location) == location)
1893  {
1894  TRACE("Location(s) already up to date.\n");
1895  return TRUE;
1896  }
1897 
1898  if ((texture->resource.access & required_access) != required_access)
1899  {
1900  ERR("Operation requires %#x access, but 1d texture only has %#x.\n",
1901  required_access, texture->resource.access);
1902  return FALSE;
1903  }
1904 
1905  if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
1906  return FALSE;
1907 
1908  if (sub_resource->locations & WINED3D_LOCATION_DISCARDED)
1909  {
1910  TRACE("1d texture previously discarded, nothing to do.\n");
1913  goto done;
1914  }
1915 
1916  switch (location)
1917  {
1920  if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
1921  {
1922  struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
1923  data.addr += sub_resource->offset;
1925  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
1926  texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
1927  }
1928  else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
1929  {
1930 #if !defined(STAGING_CSMT)
1931  struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
1932 #else /* STAGING_CSMT */
1933  struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL};
1934 #endif /* STAGING_CSMT */
1936  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
1937  texture1d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
1938  }
1939  else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
1940  {
1941  texture1d_srgb_transfer(texture, sub_resource_idx, context, TRUE);
1942  }
1943  else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB)
1944  {
1945  texture1d_srgb_transfer(texture, sub_resource_idx, context, FALSE);
1946  }
1947  else
1948  {
1949  FIXME("Implement 1d texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
1950  return FALSE;
1951  }
1952  break;
1953 
1955  if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
1956  {
1957  struct wined3d_bo_address data = {0, texture->resource.heap_memory};
1958 
1959  data.addr += sub_resource->offset;
1960  if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
1962  else
1964 
1965  texture1d_download_data(texture, sub_resource_idx, context, &data);
1966  ++texture->download_count;
1967  }
1968  else
1969  {
1970  FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
1971  wined3d_debug_location(sub_resource->locations));
1972  return FALSE;
1973  }
1974  break;
1975 
1977  if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
1978  {
1979 #if !defined(STAGING_CSMT)
1980  struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
1981 #else /* STAGING_CSMT */
1982  struct wined3d_bo_address data = {sub_resource->buffer->name, NULL};
1983 #endif /* STAGING_CSMT */
1984 
1985  if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
1987  else
1989 
1990  texture1d_download_data(texture, sub_resource_idx, context, &data);
1991  }
1992  else
1993  {
1994  FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
1995  wined3d_debug_location(sub_resource->locations));
1996  return FALSE;
1997  }
1998  break;
1999 
2000  default:
2001  FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
2002  wined3d_debug_location(sub_resource->locations));
2003  return FALSE;
2004  }
2005 
2006 done:
2008 
2009  return TRUE;
2010 }
2011 
2013 {
2014  const struct wined3d_format *format = texture->resource.format;
2015  unsigned int sub_count = texture->level_count * texture->layer_count;
2016  const struct wined3d_gl_info *gl_info = context->gl_info;
2017  unsigned int width;
2018  GLenum internal;
2019 
2021 
2022  if (srgb)
2023  internal = format->glGammaInternal;
2024  else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
2025  && wined3d_resource_is_offscreen(&texture->resource))
2026  internal = format->rtInternal;
2027  else
2028  internal = format->glInternal;
2029 
2031  {
2033 
2034  if (texture->target == GL_TEXTURE_1D_ARRAY)
2035  {
2036  GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count, internal, width, texture->layer_count));
2037  checkGLcall("glTexStorage2D");
2038  }
2039  else
2040  {
2041  GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, internal, width));
2042  checkGLcall("glTexStorage1D");
2043  }
2044  }
2045  else
2046  {
2047  unsigned int i;
2048 
2049  for (i = 0; i < sub_count; ++i)
2050  {
2051  GLenum target;
2052  struct wined3d_surface *surface = texture->sub_resources[i].u.surface;
2055 
2056  if (texture->target == GL_TEXTURE_1D_ARRAY)
2057  {
2058  gl_info->gl_ops.gl.p_glTexImage2D(target, surface->texture_level,
2059  internal, width, texture->layer_count, 0, format->glFormat, format->glType, NULL);
2060  checkGLcall("glTexImage2D");
2061  }
2062  else
2063  {
2064  gl_info->gl_ops.gl.p_glTexImage1D(target, surface->texture_level,
2065  internal, width, 0, format->glFormat, format->glType, NULL);
2066  checkGLcall("glTexImage1D");
2067  }
2068  }
2069  }
2070 }
2071 
2073 {
2074 }
2075 
2076 static const struct wined3d_texture_ops texture1d_ops =
2077 {
2082 };
2083 
2084 static void texture2d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
2085  const struct wined3d_context *context, const struct wined3d_box *box,
2086  const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch)
2087 {
2088  unsigned int texture_level;
2089  POINT dst_point;
2090  RECT src_rect;
2091 
2092  src_rect.left = 0;
2093  src_rect.top = 0;
2094  if (box)
2095  {
2096  dst_point.x = box->left;
2097  dst_point.y = box->top;
2098  src_rect.right = box->right - box->left;
2099  src_rect.bottom = box->bottom - box->top;
2100  }
2101  else
2102  {
2103  dst_point.x = dst_point.y = 0;
2104  texture_level = sub_resource_idx % texture->level_count;
2105  src_rect.right = wined3d_texture_get_level_width(texture, texture_level);
2106  src_rect.bottom = wined3d_texture_get_level_height(texture, texture_level);
2107  }
2108 
2109  wined3d_surface_upload_data(texture->sub_resources[sub_resource_idx].u.surface, context->gl_info,
2110  texture->resource.format, &src_rect, row_pitch, &dst_point, FALSE, data);
2111 }
2112 
2113 static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
2115 {
2116  return surface_load_location(texture->sub_resources[sub_resource_idx].u.surface, context, location);
2117 }
2118 
2119 /* Context activation is done by the caller. */
2121 {
2122  const struct wined3d_format *format = texture->resource.format;
2123  const struct wined3d_gl_info *gl_info = context->gl_info;
2124  const struct wined3d_color_key_conversion *conversion;
2125  GLenum internal;
2126 
2127  TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id));
2128 
2129  if (format->conv_byte_count)
2130  {
2132  }
2133  else if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
2134  {
2136  format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage);
2137  TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id));
2138  }
2139 
2141 
2142  if (srgb)
2143  internal = format->glGammaInternal;
2144  else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
2145  && wined3d_resource_is_offscreen(&texture->resource))
2146  internal = format->rtInternal;
2147  else
2148  internal = format->glInternal;
2149 
2150  if (!internal)
2151  FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id));
2152 
2153  TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType);
2154 
2157  else
2159 }
2160 
2162 {
2163  unsigned int sub_count = texture->level_count * texture->layer_count;
2164  struct wined3d_device *device = texture->resource.device;
2165  struct wined3d_texture_sub_resource *sub_resource;
2166  struct wined3d_renderbuffer_entry *entry, *entry2;
2167  const struct wined3d_gl_info *gl_info = NULL;
2168  struct wined3d_context *context = NULL;
2169  struct wined3d_surface *surface;
2170  unsigned int i;
2171 
2172  for (i = 0; i < sub_count; ++i)
2173  {
2174  sub_resource = &texture->sub_resources[i];
2175  if (!(surface = sub_resource->u.surface))
2176  continue;
2177 
2178  TRACE("surface %p.\n", surface);
2179 
2180  if (!context && !list_empty(&surface->renderbuffers))
2181  {
2183  gl_info = context->gl_info;
2184  }
2185 
2187  {
2188  TRACE("Deleting renderbuffer %u.\n", entry->id);
2190  gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
2191  heap_free(entry);
2192  }
2193 
2194  if (surface->dc)
2195  texture2d_destroy_dc(surface);
2196  }
2197  if (context)
2199  heap_free(texture->sub_resources[0].u.surface);
2200 }
2201 
2202 static const struct wined3d_texture_ops texture2d_ops =
2203 {
2208 };
2209 
2211 {
2213 }
2214 
2216 {
2218 }
2219 
2221 {
2223 }
2224 
2226 {
2228  struct wined3d_context *context;
2229 
2230  context = context_acquire(resource->device, NULL, 0);
2233 }
2234 
2236 {
2238  UINT sub_count = texture->level_count * texture->layer_count;
2239  struct wined3d_device *device = resource->device;
2240  const struct wined3d_gl_info *gl_info;
2241  struct wined3d_context *context;
2242  UINT i;
2243 
2244  TRACE("texture %p.\n", texture);
2245 
2247  gl_info = context->gl_info;
2248 
2249  for (i = 0; i < sub_count; ++i)
2250  {
2251  struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[i];
2252 
2255  {
2257  }
2258  else
2259  {
2260  /* We should only get here on device reset/teardown for implicit
2261  * resources. */
2263  || resource->type != WINED3D_RTYPE_TEXTURE_2D)
2264  ERR("Discarding %s %p sub-resource %u with resource access %s.\n",
2269  }
2270 
2271 #if !defined(STAGING_CSMT)
2272  if (sub_resource->buffer_object)
2274 #else /* STAGING_CSMT */
2275  if (sub_resource->buffer)
2277 #endif /* STAGING_CSMT */
2278 
2279  if (resource->type == WINED3D_RTYPE_TEXTURE_2D)
2280  {
2281  struct wined3d_surface *surface = sub_resource->u.surface;
2282  struct wined3d_renderbuffer_entry *entry, *entry2;
2283 
2285  {
2287  gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
2288  list_remove(&entry->entry);
2289  heap_free(entry);
2290  }
2291  list_init(&surface->renderbuffers);
2292  surface->current_renderbuffer = NULL;
2293  }
2294  }
2295 
2297 
2300 }
2301 
2302 static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
2303  struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
2304 {
2305  const struct wined3d_format *format = resource->format;
2306  struct wined3d_texture_sub_resource *sub_resource;
2307  struct wined3d_device *device = resource->device;
2308  unsigned int fmt_flags = resource->format_flags;
2309  struct wined3d_context *context = NULL;
2310  struct wined3d_texture *texture;
2311  struct wined3d_bo_address data;
2312  unsigned int texture_level;
2313  BYTE *base_memory;
2314  BOOL ret;
2315 
2316  TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n",
2317  resource, sub_resource_idx, map_desc, debug_box(box), flags);
2318 
2320  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
2321  return E_INVALIDARG;
2322 
2323  texture_level = sub_resource_idx % texture->level_count;
2324  if (box && FAILED(wined3d_texture_check_box_dimensions(texture, texture_level, box)))
2325  {
2326  WARN("Map box is invalid.\n");
2327  if (((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !(resource->access & WINED3D_RESOURCE_ACCESS_CPU))
2328  || resource->type != WINED3D_RTYPE_TEXTURE_2D)
2329  return WINED3DERR_INVALIDCALL;
2330  }
2331 
2332  if (texture->flags & WINED3D_TEXTURE_DC_IN_USE)
2333  {
2334  WARN("DC is in use.\n");
2335  return WINED3DERR_INVALIDCALL;
2336  }
2337 
2338  if (sub_resource->map_count)
2339  {
2340  WARN("Sub-resource is already mapped.\n");
2341  return WINED3DERR_INVALIDCALL;
2342  }
2343 
2344  if (device->d3d_initialized)
2346 
2347  if (flags & WINED3D_MAP_DISCARD)
2348  {
2349  TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n",
2350  wined3d_debug_location(resource->map_binding));
2351  if ((ret = wined3d_texture_prepare_location(texture, sub_resource_idx, context, resource->map_binding)))
2352  wined3d_texture_validate_location(texture, sub_resource_idx, resource->map_binding);
2353  }
2354  else
2355  {
2356  if (resource->usage & WINED3DUSAGE_DYNAMIC)
2357  WARN_(d3d_perf)("Mapping a dynamic texture without WINED3D_MAP_DISCARD.\n");
2358  ret = wined3d_texture_load_location(texture, sub_resource_idx, context, resource->map_binding);
2359  }
2360 
2361  if (!ret)
2362  {
2363  ERR("Failed to prepare location.\n");
2365  return E_OUTOFMEMORY;
2366  }
2367 
2368  if (flags & WINED3D_MAP_WRITE
2370  wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding);
2371 
2372  wined3d_texture_get_memory(texture, sub_resource_idx, &data, resource->map_binding);
2373  base_memory = context_map_bo_address(context, &data, sub_resource->size, GL_PIXEL_UNPACK_BUFFER, flags);
2374  TRACE("Base memory pointer %p.\n", base_memory);
2375 
2376  if (context)
2378 
2379  if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
2380  {
2381  map_desc->row_pitch = wined3d_texture_get_level_width(texture, texture_level) * format->byte_count;
2382  map_desc->slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * map_desc->row_pitch;
2383  }
2384  else
2385  {
2386  wined3d_texture_get_pitch(texture, texture_level, &map_desc->row_pitch, &map_desc->slice_pitch);
2387  }
2388 
2389  if (!box)
2390  {
2391  map_desc->data = base_memory;
2392  }
2393  else
2394  {
2396  {
2397  /* Compressed textures are block based, so calculate the offset of
2398  * the block that contains the top-left pixel of the mapped box. */
2399  map_desc->data = base_memory
2400  + (box->front * map_desc->slice_pitch)
2401  + ((box->top / format->block_height) * map_desc->row_pitch)
2402  + ((box->left / format->block_width) * format->block_byte_count);
2403  }
2404  else
2405  {
2406  map_desc->data = base_memory
2407  + (box->front * map_desc->slice_pitch)
2408  + (box->top * map_desc->row_pitch)
2409  + (box->left * format->byte_count);
2410  }
2411  }
2412 
2413  if (texture->swapchain && texture->swapchain->front_buffer == texture)
2414  {
2415  RECT *r = &texture->swapchain->front_buffer_update;
2416 
2417  if (!box)
2418  SetRect(r, 0, 0, resource->width, resource->height);
2419  else
2420  SetRect(r, box->left, box->top, box->right, box->bottom);
2421  TRACE("Mapped front buffer %s.\n", wine_dbgstr_rect(r));
2422  }
2423 
2424  ++resource->map_count;
2425  ++sub_resource->map_count;
2426 
2427  TRACE("Returning memory %p, row pitch %u, slice pitch %u.\n",
2428  map_desc->data, map_desc->row_pitch, map_desc->slice_pitch);
2429 
2430  return WINED3D_OK;
2431 }
2432 
2433 static HRESULT texture_resource_sub_resource_map_info(struct wined3d_resource *resource, unsigned int sub_resource_idx,
2434  struct wined3d_map_info *info, DWORD flags)
2435 {
2436  const struct wined3d_format *format = resource->format;
2437  struct wined3d_texture_sub_resource *sub_resource;
2438  unsigned int fmt_flags = resource->format_flags;
2439  struct wined3d_texture *texture;
2440  unsigned int texture_level;
2441 
2443  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
2444  return E_INVALIDARG;
2445 
2446  texture_level = sub_resource_idx % texture->level_count;
2447 
2448  if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
2449  {
2450  info->row_pitch = wined3d_texture_get_level_width(texture, texture_level) * format->byte_count;
2451  info->slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * info->row_pitch;
2452  }
2453  else
2454  {
2455  wined3d_texture_get_pitch(texture, texture_level, &info->row_pitch, &info->slice_pitch);
2456  }
2457 
2458  info->size = info->slice_pitch * wined3d_texture_get_level_depth(texture, texture_level);
2459 
2460  return WINED3D_OK;
2461 }
2462 
2463 static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
2464 {
2465  struct wined3d_texture_sub_resource *sub_resource;
2466  struct wined3d_device *device = resource->device;
2467  struct wined3d_context *context = NULL;
2468  struct wined3d_texture *texture;
2469  struct wined3d_bo_address data;
2470 
2471  TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx);
2472 
2474  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
2475  return E_INVALIDARG;
2476 
2477  if (!sub_resource->map_count)
2478  {
2479  WARN("Trying to unmap unmapped sub-resource.\n");
2480  if (texture->flags & WINED3D_TEXTURE_DC_IN_USE)
2481  return WINED3D_OK;
2482  return WINEDDERR_NOTLOCKED;
2483  }
2484 
2485  if (device->d3d_initialized)
2487 
2488  wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
2490 
2491  if (context)
2493 
2494  if (texture->swapchain && texture->swapchain->front_buffer == texture)
2495  {
2496  if (!(sub_resource->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)))
2497  texture->swapchain->swapchain_ops->swapchain_frontbuffer_updated(texture->swapchain);
2498  }
2499 
2500  --sub_resource->map_count;
2501  if (!--resource->map_count && texture->update_map_binding)
2503 
2504  return WINED3D_OK;
2505 }
2506 
2508 {
2516 };
2517 
2519  UINT layer_count, UINT level_count, struct wined3d_device *device, void *parent,
2520  const struct wined3d_parent_ops *parent_ops)
2521 {
2522  struct wined3d_device_parent *device_parent = device->device_parent;
2523  const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2524  struct wined3d_surface *surfaces;
2525  unsigned int i, j;
2526  HRESULT hr;
2527 
2528  if (layer_count > 1 && !gl_info->supported[EXT_TEXTURE_ARRAY])
2529  {
2530  WARN("OpenGL implementation does not support array textures.\n");
2531  return WINED3DERR_INVALIDCALL;
2532  }
2533 
2534  /* TODO: It should only be possible to create textures for formats
2535  * that are reported as supported. */
2536  if (WINED3DFMT_UNKNOWN >= desc->format)
2537  {
2538  WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
2539  return WINED3DERR_INVALIDCALL;
2540  }
2541 
2542  if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
2543  {
2544  WARN("1d textures can not be used for cube mapping, returning D3DERR_INVALIDCALL.\n");
2545  return WINED3DERR_INVALIDCALL;
2546  }
2547 
2549  || (desc->usage & WINED3DUSAGE_SCRATCH))
2550  {
2551  WARN("Attempted to create a DYNAMIC texture in pool %s.\n", wined3d_debug_resource_access(desc->access));
2552  return WINED3DERR_INVALIDCALL;
2553  }
2554 
2555  if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && !is_power_of_two(desc->width))
2556  {
2557  if (desc->usage & WINED3DUSAGE_SCRATCH)
2558  {
2559  WARN("Creating a scratch NPOT 1d texture despite lack of HW support.\n");
2560  }
2561  else
2562  {
2563  WARN("Attempted to create a NPOT 1d texture (%u, %u, %u) without GL support.\n",
2564  desc->width, desc->height, desc->depth);
2565  return WINED3DERR_INVALIDCALL;
2566  }
2567  }
2568 
2569  if (desc->usage & WINED3DUSAGE_QUERY_GENMIPMAP)
2570  {
2571  if (level_count != 1)
2572  {
2573  WARN("WINED3DUSAGE_QUERY_GENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n");
2574  return WINED3DERR_INVALIDCALL;
2575  }
2576  }
2577 
2578  if (FAILED(hr = wined3d_texture_init(texture, &texture1d_ops, layer_count, level_count, desc,
2579  0, device, parent, parent_ops, &texture_resource_ops)))
2580  {
2581  WARN("Failed to initialize texture, returning %#x.\n", hr);
2582  return hr;
2583  }
2584 
2585  texture->pow2_matrix[0] = 1.0f;
2586  texture->pow2_matrix[5] = 1.0f;
2587  texture->pow2_matrix[10] = 1.0f;
2588  texture->pow2_matrix[15] = 1.0f;
2589  texture->target = (layer_count > 1) ? GL_TEXTURE_1D_ARRAY : GL_TEXTURE_1D;
2590 
2591  if (wined3d_texture_use_pbo(texture, gl_info))
2592  {
2594  texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
2595  }
2596 
2597  if (level_count > ~(SIZE_T)0 / layer_count
2598  || !(surfaces = heap_calloc(level_count * layer_count, sizeof(*surfaces))))
2599  {
2601  return E_OUTOFMEMORY;
2602  }
2603 
2604  /* Generate all the surfaces. */
2605  for (i = 0; i < texture->level_count; ++i)
2606  {
2607  for (j = 0; j < texture->layer_count; ++j)
2608  {
2609  struct wined3d_texture_sub_resource *sub_resource;
2610  unsigned int idx = j * texture->level_count + i;
2611  struct wined3d_surface *surface;
2612 
2613  surface = &surfaces[idx];
2614  surface->container = texture;
2615  surface->texture_level = i;
2616  surface->texture_layer = j;
2617  list_init(&surface->renderbuffers);
2618 
2619  sub_resource = &texture->sub_resources[idx];
2620  sub_resource->locations = WINED3D_LOCATION_DISCARDED;
2621  sub_resource->u.surface = surface;
2622 
2623  if (FAILED(hr = device_parent->ops->surface_created(device_parent,
2624  texture, idx, &sub_resource->parent, &sub_resource->parent_ops)))
2625  {
2626  WARN("Failed to create texture1d parent, hr %#x.\n", hr);
2627  sub_resource->parent = NULL;
2629  return hr;
2630  }
2631 
2632  TRACE("parent %p, parent_ops %p.\n", parent, parent_ops);
2633 
2634  TRACE("Created 1d texture surface level %u, layer %u @ %p.\n", i, j, surface);
2635  }
2636  }
2637 
2638  return WINED3D_OK;
2639 }
2640 
2642  unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device,
2643  void *parent, const struct wined3d_parent_ops *parent_ops)
2644 {
2645  struct wined3d_device_parent *device_parent = device->device_parent;
2646  const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2647  struct wined3d_surface *surfaces;
2648  UINT pow2_width, pow2_height;
2649  unsigned int i, j, sub_count;
2650  HRESULT hr;
2651 
2652  if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1
2653  && !gl_info->supported[EXT_TEXTURE_ARRAY])
2654  {
2655  WARN("OpenGL implementation does not support array textures.\n");
2656  return WINED3DERR_INVALIDCALL;
2657  }
2658 
2659  /* TODO: It should only be possible to create textures for formats
2660  * that are reported as supported. */
2661  if (WINED3DFMT_UNKNOWN >= desc->format)
2662  {
2663  WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
2664  return WINED3DERR_INVALIDCALL;
2665  }
2666 
2668  FIXME("Trying to create a managed texture with dynamic usage.\n");
2671  WARN("Creating a mappable texture that doesn't specify dynamic usage.\n");
2673  FIXME("Trying to create a CPU accessible render target.\n");
2674 
2675  pow2_width = desc->width;
2676  pow2_height = desc->height;
2677  if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1)))
2679  {
2680  /* level_count == 0 returns an error as well. */
2681  if (level_count != 1 || layer_count != 1)
2682  {
2683  if (!(desc->usage & WINED3DUSAGE_SCRATCH))
2684  {
2685  WARN("Attempted to create a mipmapped/cube/array NPOT texture without unconditional NPOT support.\n");
2686  return WINED3DERR_INVALIDCALL;
2687  }
2688 
2689  WARN("Creating a scratch mipmapped/cube/array NPOT texture despite lack of HW support.\n");
2690  }
2692 
2694  {
2695  const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format, desc->usage);
2696 
2697  /* TODO: Add support for non-power-of-two compressed textures. */
2700  {
2701  FIXME("Compressed or height scaled non-power-of-two (%ux%u) textures are not supported.\n",
2702  desc->width, desc->height);
2703  return WINED3DERR_NOTAVAILABLE;
2704  }
2705 
2706  /* Find the nearest pow2 match. */
2707  pow2_width = pow2_height = 1;
2708  while (pow2_width < desc->width)
2709  pow2_width <<= 1;
2710  while (pow2_height < desc->height)
2711  pow2_height <<= 1;
2713  }
2714  }
2715  texture->pow2_width = pow2_width;
2716  texture->pow2_height = pow2_height;
2717 
2718  if ((pow2_width > gl_info->limits.texture_size || pow2_height > gl_info->limits.texture_size)
2719  && (desc->usage & WINED3DUSAGE_TEXTURE))
2720  {
2721  /* One of four options:
2722  * 1: Do the same as we do with NPOT and scale the texture. (Any
2723  * texture ops would require the texture to be scaled which is
2724  * potentially slow.)
2725  * 2: Set the texture to the maximum size (bad idea).
2726  * 3: WARN and return WINED3DERR_NOTAVAILABLE.
2727  * 4: Create the surface, but allow it to be used only for DirectDraw
2728  * Blts. Some apps (e.g. Swat 3) create textures with a height of
2729  * 16 and a width > 3000 and blt 16x16 letter areas from them to
2730  * the render target. */
2731  if (desc->access & WINED3D_RESOURCE_ACCESS_GPU)
2732  {
2733  WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height);
2734  return WINED3DERR_NOTAVAILABLE;
2735  }
2736 
2737  /* We should never use this surface in combination with OpenGL. */
2738  TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height);
2739  }
2740 
2741  if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc,
2742  flags, device, parent, parent_ops, &texture_resource_ops)))
2743  {
2744  WARN("Failed to initialize texture, returning %#x.\n", hr);
2745  return hr;
2746  }
2747 
2748  /* Precalculated scaling for 'faked' non power of two texture coords. */
2749  if (texture->resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT)
2750  {
2751  texture->pow2_matrix[0] = (float)desc->width;
2752  texture->pow2_matrix[5] = (float)desc->height;
2755  }
2756  else
2757  {
2759  {
2760  texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
2761  texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
2763  }
2764  else
2765  {
2766  texture->pow2_matrix[0] = 1.0f;
2767  texture->pow2_matrix[5] = 1.0f;
2768  }
2769  if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
2770  {
2771  texture->target = GL_TEXTURE_CUBE_MAP_ARB;
2772  }
2773  else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
2774  {
2775  if (layer_count > 1)
2777  else
2779  }
2780  else
2781  {
2782  if (layer_count > 1)
2783  texture->target = GL_TEXTURE_2D_ARRAY;
2784  else
2785  texture->target = GL_TEXTURE_2D;
2786  }
2787  }
2788  texture->pow2_matrix[10] = 1.0f;
2789  texture->pow2_matrix[15] = 1.0f;
2790  TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]);
2791 
2792  if (wined3d_texture_use_pbo(texture, gl_info))
2793  texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
2794 
2795  sub_count = level_count * layer_count;
2796  if (sub_count / layer_count != level_count
2797  || !(surfaces = heap_calloc(sub_count, sizeof(*surfaces))))
2798  {
2800  return E_OUTOFMEMORY;
2801  }
2802 
2803  if (desc->usage & WINED3DUSAGE_OVERLAY)
2804  {
2805  if (!(texture->overlay_info = heap_calloc(sub_count, sizeof(*texture->overlay_info))))
2806  {
2809  return E_OUTOFMEMORY;
2810  }
2811 
2812  for (i = 0; i < sub_count; ++i)
2813  {
2814  list_init(&texture->overlay_info[i].entry);
2815  list_init(&texture->overlay_info[i].overlays);
2816  }
2817  }
2818 
2819  /* Generate all the surfaces. */
2820  for (i = 0; i < texture->level_count; ++i)
2821  {
2822  for (j = 0; j < texture->layer_count; ++j)
2823  {
2824  struct wined3d_texture_sub_resource *sub_resource;
2825  unsigned int idx = j * texture->level_count + i;
2826  struct wined3d_surface *surface;
2827 
2828  surface = &surfaces[idx];
2829  surface->container = texture;
2830  surface->texture_level = i;
2831  surface->texture_layer = j;
2832  list_init(&surface->renderbuffers);
2833 
2834  sub_resource = &texture->sub_resources[idx];
2835  sub_resource->locations = WINED3D_LOCATION_DISCARDED;
2836  sub_resource->u.surface = surface;
2837  if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
2838  {
2841  }
2842 
2843  if (FAILED(hr = device_parent->ops->surface_created(device_parent,
2844  texture, idx, &sub_resource->parent, &sub_resource->parent_ops)))
2845  {
2846  WARN("Failed to create surface parent, hr %#x.\n", hr);
2847  sub_resource->parent = NULL;
2849  return hr;
2850  }
2851 
2852  TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops);
2853 
2854  TRACE("Created surface level %u, layer %u @ %p.\n", i, j, surface);
2855 
2856  if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
2857  {
2859  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
2860  if (!surface->dc)
2861  {
2863  return WINED3DERR_INVALIDCALL;
2864  }
2865  }
2866  }
2867  }
2868 
2869  return WINED3D_OK;
2870 }
2871 
2872 /* This call just uploads data, the caller is responsible for binding the
2873  * correct texture. */
2874 /* Context activation is done by the caller. */
2875 static void texture3d_upload_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
2876  const struct wined3d_context *context, const struct wined3d_box *box,
2877  const struct wined3d_const_bo_address *data, unsigned int row_pitch, unsigned int slice_pitch)
2878 {
2879  const struct wined3d_format *format = texture->resource.format;
2880  unsigned int level = sub_resource_idx % texture->level_count;
2881  const struct wined3d_gl_info *gl_info = context->gl_info;
2882  unsigned int x, y, z, update_w, update_h, update_d;
2883  unsigned int dst_row_pitch, dst_slice_pitch;
2884  unsigned int width, height, depth;
2885  const void *mem = data->addr;
2886  void *converted_mem = NULL;
2887 
2888  TRACE("texture %p, sub_resource_idx %u, context %p, box %s, data {%#x:%p}, row_pitch %#x, slice_pitch %#x.\n",
2889  texture, sub_resource_idx, context, debug_box(box),
2890  data->buffer_object, data->addr, row_pitch, slice_pitch);
2891 
2895 
2896  if (!box)
2897  {
2898  x = y = z = 0;
2899  update_w = width;
2900  update_h = height;
2901  update_d = depth;
2902  }
2903  else
2904  {
2905  x = box->left;
2906  y = box->top;
2907  z = box->front;
2908  update_w = box->right - box->left;
2909  update_h = box->bottom - box->top;
2910  update_d = box->back - box->front;
2911  }
2912 
2913  if (format->conv_byte_count)
2914  {
2915  if (data->buffer_object)
2916  ERR("Loading a converted texture from a PBO.\n");
2917  if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
2918  ERR("Converting a block-based format.\n");
2919 
2920  dst_row_pitch = update_w * format->conv_byte_count;
2921  dst_slice_pitch = dst_row_pitch * update_h;
2922 
2923  converted_mem = heap_calloc(update_d, dst_slice_pitch);
2924  format->upload(data->addr, converted_mem, row_pitch, slice_pitch,
2925  dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
2926  mem = converted_mem;
2927  }
2928  else
2929  {
2930  wined3d_texture_get_pitch(texture, sub_resource_idx, &dst_row_pitch, &dst_slice_pitch);
2931  if (row_pitch != dst_row_pitch || slice_pitch != dst_slice_pitch)
2932  FIXME("Ignoring row/slice pitch (%u/%u).\n", row_pitch, slice_pitch);
2933  }
2934 
2935  if (data->buffer_object)
2936  {
2937  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, data->buffer_object));
2938  checkGLcall("glBindBuffer");
2939  }
2940 
2942  update_w, update_h, update_d, format->glFormat, format->glType, mem));
2943  checkGLcall("glTexSubImage3D");
2944 
2945  if (data->buffer_object)
2946  {
2947  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
2948  checkGLcall("glBindBuffer");
2949  }
2950 
2951  heap_free(converted_mem);
2952 }
2953 
2954 /* Context activation is done by the caller. */
2955 static void texture3d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx,
2956  const struct wined3d_context *context, const struct wined3d_bo_address *data)
2957 {
2958  const struct wined3d_format *format = texture->resource.format;
2959  const struct wined3d_gl_info *gl_info = context->gl_info;
2960 
2961  if (format->conv_byte_count)
2962  {
2963  FIXME("Attempting to download a converted volume, format %s.\n",
2964  debug_d3dformat(format->id));
2965  return;
2966  }
2967 
2968  if (data->buffer_object)
2969  {
2970  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
2971  checkGLcall("glBindBuffer");
2972  }
2973 
2974  gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, sub_resource_idx,
2975  format->glFormat, format->glType, data->addr);
2976  checkGLcall("glGetTexImage");
2977 
2978  if (data->buffer_object)
2979  {
2980  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
2981  checkGLcall("glBindBuffer");
2982  }
2983 
2984 }
2985 
2986 /* Context activation is done by the caller. */
2987 static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx,
2988  struct wined3d_context *context, BOOL dest_is_srgb)
2989 {
2990  struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
2991  unsigned int row_pitch, slice_pitch;
2992  struct wined3d_bo_address data;
2993 
2994  /* Optimisations are possible, but the effort should be put into either
2995  * implementing EXT_SRGB_DECODE in the driver or finding out why we
2996  * picked the wrong copy for the original upload and fixing that.
2997  *
2998  * Also keep in mind that we want to avoid using resource.heap_memory
2999  * for DEFAULT pool surfaces. */
3000  WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n");
3001  data.buffer_object = 0;
3002  if (!(data.addr = heap_alloc(sub_resource->size)))
3003  return;
3004 
3005  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
3007  texture3d_download_data(texture, sub_resource_idx, context, &data);
3009  texture3d_upload_data(texture, sub_resource_idx, context,
3010  NULL, wined3d_const_bo_address(&data), row_pitch, slice_pitch);
3011 
3012  heap_free(data.addr);
3013 }
3014 
3015 /* Context activation is done by the caller. */
3016 static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx,
3018 {
3019  struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
3020  unsigned int row_pitch, slice_pitch;
3021 
3022  if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
3023  return FALSE;
3024 
3025  switch (location)
3026  {
3029  if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
3030  {
3031  struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
3032  data.addr += sub_resource->offset;
3035  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
3036  texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
3037  }
3038  else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
3039  {
3040 #if !defined(STAGING_CSMT)
3041  struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
3042 #else /* STAGING_CSMT */
3043  struct wined3d_const_bo_address data = {sub_resource->buffer->name, NULL};
3044 #endif /* STAGING_CSMT */
3047  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
3048  texture3d_upload_data(texture, sub_resource_idx, context, NULL, &data, row_pitch, slice_pitch);
3049  }
3050  else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
3051  {
3052  texture3d_srgb_transfer(texture, sub_resource_idx, context, TRUE);
3053  }
3054  else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB)
3055  {
3056  texture3d_srgb_transfer(texture, sub_resource_idx, context, FALSE);
3057  }
3058  else
3059  {
3060  FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
3061  return FALSE;
3062  }
3063  break;
3064 
3066  if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
3067  {
3068  struct wined3d_bo_address data = {0, texture->resource.heap_memory};
3069 
3070  data.addr += sub_resource->offset;
3071  if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
3073  else
3075 
3076  texture3d_download_data(texture, sub_resource_idx, context, &data);
3077  ++texture->download_count;
3078  }
3079  else
3080  {
3081  FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
3082  wined3d_debug_location(sub_resource->locations));
3083  return FALSE;
3084  }
3085  break;
3086 
3088  if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
3089  {
3090 #if !defined(STAGING_CSMT)
3091  struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
3092 #else /* STAGING_CSMT */
3093  struct wined3d_bo_address data = {sub_resource->buffer->name, NULL};
3094 #endif /* STAGING_CSMT */
3095 
3096  if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
3098  else
3100 
3101  texture3d_download_data(texture, sub_resource_idx, context, &data);
3102  }
3103  else
3104  {
3105  FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
3106  wined3d_debug_location(sub_resource->locations));
3107  return FALSE;
3108  }
3109  break;
3110 
3111  default:
3112  FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
3113  wined3d_debug_location(sub_resource->locations));
3114  return FALSE;
3115  }
3116 
3117  return TRUE;
3118 }
3119 
3121 {
3122  const struct wined3d_format *format = texture->resource.format;
3123  GLenum internal = srgb ? format->glGammaInternal : format->glInternal;
3124  unsigned int sub_count = texture->level_count * texture->layer_count;
3125  const struct wined3d_gl_info *gl_info = context->gl_info;
3126  unsigned int i;
3127 
3129 
3131  {
3132  GL_EXTCALL(glTexStorage3D(GL_TEXTURE_3D, texture->level_count, internal,
3136  checkGLcall("glTexStorage3D");
3137  }
3138  else
3139  {
3140  for (i = 0; i < sub_count; ++i)
3141  {
3146  0, format->glFormat, format->glType, NULL));
3147  checkGLcall("glTexImage3D");
3148  }
3149  }
3150 }
3151 
3153 {
3154 }
3155 
3156 static const struct wined3d_texture_ops texture3d_ops =
3157 {
3162 };
3163 
3165  UINT layer_count, UINT level_count, DWORD flags, struct wined3d_device *device, void *parent,
3166  const struct wined3d_parent_ops *parent_ops)
3167 {
3168  struct wined3d_device_parent *device_parent = device->device_parent;
3169  const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
3170  unsigned int i;
3171  HRESULT hr;
3172 
3173  if (layer_count != 1)
3174  {
3175  ERR("Invalid layer count for volume texture.\n");
3176  return E_INVALIDARG;
3177  }
3178 
3179  /* TODO: It should only be possible to create textures for formats
3180  * that are reported as supported. */
3181  if (WINED3DFMT_UNKNOWN >= desc->format)
3182  {
3183  WARN("(%p) : Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n", texture);
3184  return WINED3DERR_INVALIDCALL;
3185  }
3186 
3187  if (!gl_info->supported[EXT_TEXTURE3D])
3188  {
3189  WARN("(%p) : Texture cannot be created - no volume texture support.\n", texture);
3190  return WINED3DERR_INVALIDCALL;
3191  }
3192 
3194  || desc->usage & WINED3DUSAGE_SCRATCH))
3195  {
3196  WARN("Attempted to create a DYNAMIC texture with access %s.\n",
3198  return WINED3DERR_INVALIDCALL;
3199  }
3200 
3201  if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
3202  {
3203  if (!is_power_of_two(desc->width) || !is_power_of_two(desc->height) || !is_power_of_two(desc->depth))
3204  {
3205  if (desc->usage & WINED3DUSAGE_SCRATCH)
3206  {
3207  WARN("Creating a scratch NPOT volume texture despite lack of HW support.\n");
3208  }
3209  else
3210  {
3211  WARN("Attempted to create a NPOT volume texture (%u, %u, %u) without GL support.\n",
3212  desc->width, desc->height, desc->depth);
3213  return WINED3DERR_INVALIDCALL;
3214  }
3215  }
3216  }
3217 
3218  if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, level_count, desc,
3219  flags, device, parent, parent_ops, &texture_resource_ops)))
3220  {
3221  WARN("Failed to initialize texture, returning %#x.\n", hr);
3222  return hr;
3223  }
3224 
3225  texture->pow2_matrix[0] = 1.0f;
3226  texture->pow2_matrix[5] = 1.0f;
3227  texture->pow2_matrix[10] = 1.0f;
3228  texture->pow2_matrix[15] = 1.0f;
3229  texture->target = GL_TEXTURE_3D;
3230 
3231  if (wined3d_texture_use_pbo(texture, gl_info))
3232  {
3234  texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
3235  }
3236 
3237  /* Generate all the sub resources. */
3238  for (i = 0; i < texture->level_count; ++i)
3239  {
3240  struct wined3d_texture_sub_resource *sub_resource;
3241 
3242  sub_resource = &texture->sub_resources[i];
3243  sub_resource->locations = WINED3D_LOCATION_DISCARDED;
3244 
3245  if (FAILED(hr = device_parent->ops->volume_created(device_parent,
3246  texture, i, &sub_resource->parent, &sub_resource->parent_ops)))
3247  {
3248  WARN("Failed to create volume parent, hr %#x.\n", hr);
3249  sub_resource->parent = NULL;
3251  return hr;
3252  }
3253 
3254  TRACE("parent %p, parent_ops %p.\n", parent, parent_ops);
3255 
3256  TRACE("Created volume level %u.\n", i);
3257  }
3258 
3259  return WINED3D_OK;
3260 }
3261 
3262 HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
3263  const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
3264  const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
3265 {
3266  struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1};
3267  struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1};
3268  unsigned int dst_format_flags, src_format_flags = 0;
3269  HRESULT hr;
3270 
3271  TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_rect %s, src_texture %p, "
3272  "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s.\n",
3273  dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture,
3274  src_sub_resource_idx, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter));
3275 
3276  if (dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count
3277  || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
3278  return WINED3DERR_INVALIDCALL;
3279 
3280  if (src_sub_resource_idx >= src_texture->level_count * src_texture->layer_count
3281  || src_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
3282  return WINED3DERR_INVALIDCALL;
3283 
3284  dst_format_flags = dst_texture->resource.format_flags;
3286  dst_sub_resource_idx % dst_texture->level_count, &dst_box)))
3287  return hr;
3288 
3289  src_format_flags = src_texture->resource.format_flags;
3291  src_sub_resource_idx % src_texture->level_count, &src_box)))
3292  return hr;
3293 
3294  if (dst_texture->sub_resources[dst_sub_resource_idx].map_count
3295  || src_texture->sub_resources[src_sub_resource_idx].map_count)
3296  {
3297 #if !defined(STAGING_CSMT)
3298  WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n");
3299  return WINEDDERR_SURFACEBUSY;
3300 #else /* STAGING_CSMT */
3301  struct wined3d_device *device = dst_texture->resource.device;
3302  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
3303  if (dst_texture->sub_resources[dst_sub_resource_idx].map_count
3304  || (src_texture && src_texture->sub_resources[src_sub_resource_idx].map_count))
3305  {
3306  WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n");
3307  return WINEDDERR_SURFACEBUSY;
3308  }
3309 #endif /* STAGING_CSMT */
3310  }
3311 
3312  if ((src_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
3313  != (dst_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
3314  {
3315  WARN("Rejecting depth/stencil blit between incompatible formats.\n");
3316  return WINED3DERR_INVALIDCALL;
3317  }
3318 
3319  wined3d_cs_emit_blt_sub_resource(dst_texture->resource.device->cs, &dst_texture->resource, dst_sub_resource_idx,
3320  &dst_box, &src_texture->resource, src_sub_resource_idx, &src_box, flags, fx, filter);
3321 
3322  return WINED3D_OK;
3323 }
3324 
3326  unsigned int sub_resource_idx, LONG *x, LONG *y)
3327 {
3328  struct wined3d_overlay_info *overlay;
3329 
3330  TRACE("texture %p, sub_resource_idx %u, x %p, y %p.\n", texture, sub_resource_idx, x, y);
3331 
3332  if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY)
3333  || sub_resource_idx >= texture->level_count * texture->layer_count)
3334  {
3335  WARN("Invalid sub-resource specified.\n");
3337  }
3338 
3339  overlay = &texture->overlay_info[sub_resource_idx];
3340  if (!overlay->dst)
3341  {
3342  TRACE("Overlay not visible.\n");
3343  *x = 0;
3344  *y = 0;
3346  }
3347 
3348  *x = overlay->dst_rect.left;
3349  *y = overlay->dst_rect.top;
3350 
3351  TRACE("Returning position %d, %d.\n", *x, *y);
3352 
3353  return WINED3D_OK;
3354 }
3355 
3357  unsigned int sub_resource_idx, LONG x, LONG y)
3358 {
3359  struct wined3d_overlay_info *overlay;
3360  LONG w, h;
3361 
3362  TRACE("texture %p, sub_resource_idx %u, x %d, y %d.\n", texture, sub_resource_idx, x, y);
3363 
3364  if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY)
3365  || sub_resource_idx >= texture->level_count * texture->layer_count)
3366  {
3367  WARN("Invalid sub-resource specified.\n");
3369  }
3370 
3371  overlay = &texture->overlay_info[sub_resource_idx];
3372  w = overlay->dst_rect.right - overlay->dst_rect.left;
3373  h = overlay->dst_rect.bottom - overlay->dst_rect.top;
3374  SetRect(&overlay->dst_rect, x, y, x + w, y + h);
3375 
3376  return WINED3D_OK;
3377 }
3378 
3379 HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, unsigned int sub_resource_idx,
3380  const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
3381  const RECT *dst_rect, DWORD flags)
3382 {
3383  struct wined3d_texture_sub_resource *sub_resource, *dst_sub_resource;
3384  struct wined3d_surface *surface, *dst_surface;
3385  struct wined3d_overlay_info *overlay;
3386 
3387  TRACE("texture %p, sub_resource_idx %u, src_rect %s, dst_texture %p, "
3388  "dst_sub_resource_idx %u, dst_rect %s, flags %#x.\n",
3389  texture, sub_resource_idx, wine_dbgstr_rect(src_rect), dst_texture,
3390  dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), flags);
3391 
3392  if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY) || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D
3393  || !(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
3394  {
3395  WARN("Invalid sub-resource specified.\n");
3397  }
3398 
3399  if (!dst_texture || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D
3400  || !(dst_sub_resource = wined3d_texture_get_sub_resource(dst_texture, dst_sub_resource_idx)))
3401  {
3402  WARN("Invalid destination sub-resource specified.\n");
3403  return WINED3DERR_INVALIDCALL;
3404  }
3405 
3406  overlay = &texture->overlay_info[sub_resource_idx];
3407 
3408  surface = sub_resource->u.surface;
3409  if (src_rect)
3410  overlay->src_rect = *src_rect;
3411  else
3412  SetRect(&overlay->src_rect, 0, 0,
3415 
3416  dst_surface = dst_sub_resource->u.surface;
3417  if (dst_rect)
3418  overlay->dst_rect = *dst_rect;
3419  else
3420  SetRect(&overlay->dst_rect, 0, 0,
3421  wined3d_texture_get_level_width(dst_texture, dst_surface->texture_level),
3422  wined3d_texture_get_level_height(dst_texture, dst_surface->texture_level));
3423 
3424  if (overlay->dst && (overlay->dst != dst_surface || flags & WINEDDOVER_HIDE))
3425  {
3426  overlay->dst = NULL;
3427  list_remove(&overlay->entry);
3428  }
3429 
3430  if (flags & WINEDDOVER_SHOW)
3431  {
3432  if (overlay->dst != dst_surface)
3433  {
3434  overlay->dst = dst_surface;
3435  list_add_tail(&texture->overlay_info[dst_sub_resource_idx].overlays, &overlay->entry);
3436  }
3437  }
3438  else if (flags & WINEDDOVER_HIDE)
3439  {
3440  /* Tests show that the rectangles are erased on hide. */
3441  SetRectEmpty(&overlay->src_rect);
3442  SetRectEmpty(&overlay->dst_rect);
3443  overlay->dst = NULL;
3444  }
3445 
3446  return WINED3D_OK;
3447 }
3448 
3449 void * CDECL wined3d_texture_get_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx)
3450 {
3451  unsigned int sub_count = texture->level_count * texture->layer_count;
3452 
3453  TRACE("texture %p, sub_resource_idx %u.\n", texture, sub_resource_idx);
3454 
3455  if (sub_resource_idx >= sub_count)
3456  {
3457  WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count);
3458  return NULL;
3459  }
3460 
3461  return texture->sub_resources[sub_resource_idx].parent;
3462 }
3463 
3465  unsigned int sub_resource_idx, void *parent)
3466 {
3467  unsigned int sub_count = texture->level_count * texture->layer_count;
3468 
3469  TRACE("texture %p, sub_resource_idx %u, parent %p.\n", texture, sub_resource_idx, parent);
3470 
3471  if (sub_resource_idx >= sub_count)
3472  {
3473  WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count);
3474  return;
3475  }
3476 
3477  texture->sub_resources[sub_resource_idx].parent = parent;
3478 }
3479 
3481  unsigned int sub_resource_idx, struct wined3d_sub_resource_desc *desc)
3482 {
3483  unsigned int sub_count = texture->level_count * texture->layer_count;
3484  const struct wined3d_resource *resource;
3485  unsigned int level_idx;
3486 
3487  TRACE("texture %p, sub_resource_idx %u, desc %p.\n", texture, sub_resource_idx, desc);
3488 
3489  if (sub_resource_idx >= sub_count)
3490  {
3491  WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count);
3492  return WINED3DERR_INVALIDCALL;
3493  }
3494 
3495  resource = &texture->resource;
3496  desc->format = resource->format->id;
3497  desc->multisample_type = resource->multisample_type;
3498  desc->multisample_quality = resource->multisample_quality;
3499  desc->usage = resource->usage;
3500  desc->access = resource->access;
3501 
3502  level_idx = sub_resource_idx % texture->level_count;
3503  desc->width = wined3d_texture_get_level_width(texture, level_idx);
3504  desc->height = wined3d_texture_get_level_height(texture, level_idx);
3505  desc->depth = wined3d_texture_get_level_depth(texture, level_idx);
3506  desc->size = texture->sub_resources[sub_resource_idx].size;
3507 
3508  return WINED3D_OK;
3509 }
3510 
3512  UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data,
3513  void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
3514 {
3515  struct wined3d_texture *object;
3516  HRESULT hr;
3517 
3518  TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, data %p, "
3519  "parent %p, parent_ops %p, texture %p.\n",
3520  device, desc, layer_count, level_count, flags, data, parent, parent_ops, texture);
3521 
3522  if (!layer_count)
3523  {
3524  WARN("Invalid layer count.\n");
3525  return E_INVALIDARG;
3526  }
3527  if ((desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count != 6)
3528  {
3529  ERR("Invalid layer count %u for legacy cubemap.\n", layer_count);
3530  layer_count = 6;
3531  }
3532 
3533  if (!level_count)
3534  {
3535  WARN("Invalid level count.\n");
3536  return WINED3DERR_INVALIDCALL;
3537  }
3538 
3539  if (desc->multisample_type != WINED3D_MULTISAMPLE_NONE)
3540  {
3541  const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info,
3542  desc->format, desc->usage);
3543 
3544  if (desc->multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE
3545  && desc->multisample_quality >= wined3d_popcount(format->multisample_types))
3546  {
3547  WARN("Unsupported quality level %u requested for WINED3D_MULTISAMPLE_NON_MASKABLE.\n",
3548  desc->multisample_quality);
3549  return WINED3DERR_NOTAVAILABLE;
3550  }
3551  if (desc->multisample_type != WINED3D_MULTISAMPLE_NON_MASKABLE
3552  && (!(format->multisample_types & 1u << (desc->multisample_type - 1))
3553  || desc->multisample_quality))
3554  {
3555  WARN("Unsupported multisample type %u quality %u requested.\n", desc->multisample_type,
3556  desc->multisample_quality);
3557  return WINED3DERR_NOTAVAILABLE;
3558  }
3559  }
3560 
3561  if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture,
3562  sub_resources[level_count * layer_count]))))
3563  return E_OUTOFMEMORY;
3564 
3565  switch (desc->resource_type)
3566  {
3568  hr = texture1d_init(object, desc, layer_count, level_count, device, parent, parent_ops);
3569  break;
3570 
3572  hr = texture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops);
3573  break;
3574 
3576  hr = volumetexture_init(object, desc, layer_count, level_count, flags, device, parent, parent_ops);
3577  break;
3578 
3579  default:
3580  ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
3582  break;
3583  }
3584 
3585  if (FAILED(hr))
3586  {
3587  WARN("Failed to initialize texture, returning %#x.\n", hr);
3588  heap_free(object);
3589  return hr;
3590  }
3591 
3592  /* FIXME: We'd like to avoid ever allocating system memory for the texture
3593  * in this case. */
3594  if (data)
3595  {
3596  unsigned int sub_count = level_count * layer_count;
3597  unsigned int i;
3598 
3599  for (i = 0; i < sub_count; ++i)
3600  {
3601  if (!data[i].data)
3602  {
3603  WARN("Invalid sub-resource data specified for sub-resource %u.\n", i);
3605  heap_free(object);
3606  return E_INVALIDARG;
3607  }
3608  }
3609 
3610  for (i = 0; i < sub_count; ++i)
3611  {
3613  i, NULL, data[i].data, data[i].row_pitch, data[i].slice_pitch);
3614  }
3615  }
3616 
3617  TRACE("Created texture %p.\n", object);
3618  *texture = object;
3619 
3620  return WINED3D_OK;
3621 }
3622 
3623 HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc)
3624 {
3625  struct wined3d_device *device = texture->resource.device;
3626  struct wined3d_texture_sub_resource *sub_resource;
3627  struct wined3d_surface *surface;
3628 
3629  TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
3630 
3631  if (!(texture->flags & WINED3D_TEXTURE_GET_DC))
3632  {
3633  WARN("Texture does not support GetDC\n");
3634  /* Don't touch the DC */
3635  return WINED3DERR_INVALIDCALL;
3636  }
3637 
3638  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
3639  return WINED3DERR_INVALIDCALL;
3640 
3641  if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
3642  {
3643  WARN("Not supported on %s resources.\n", debug_d3dresourcetype(texture->resource.type));
3644  return WINED3DERR_INVALIDCALL;
3645  }
3646 
3647  surface = sub_resource->u.surface;
3648 
3649  if (texture->resource.map_count && !(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
3650  return WINED3DERR_INVALIDCALL;
3651 
3652  if (!surface->dc)
3653  {
3655  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
3656  }
3657  if (!surface->dc)
3658  return WINED3DERR_INVALIDCALL;
3659 
3660  if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
3662  ++texture->resource.map_count;
3663  ++sub_resource->map_count;
3664 
3665  *dc = surface->dc;
3666  TRACE("Returning dc %p.\n", *dc);
3667 
3668  return WINED3D_OK;
3669 }
3670 
3671 HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc)
3672 {
3673  struct wined3d_device *device = texture->resource.device;
3674  struct wined3d_texture_sub_resource *sub_resource;
3675  struct wined3d_surface *surface;
3676 
3677  TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
3678 
3679  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
3680  return WINED3DERR_INVALIDCALL;
3681 
3682  if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
3683  {
3684  WARN("Not supported on %s resources.\n", debug_d3dresourcetype(texture->resource.type));
3685  return WINED3DERR_INVALIDCALL;
3686  }
3687 
3688  surface = sub_resource->u.surface;
3689 
3691  return WINED3DERR_INVALIDCALL;
3692 
3693  if (surface->dc != dc)
3694  {
3695  WARN("Application tries to release invalid DC %p, surface DC is %p.\n", dc, surface->dc);
3696  return WINED3DERR_INVALIDCALL;
3697  }
3698 
3699  if (!(texture->resource.usage & WINED3DUSAGE_OWNDC) && !(device->wined3d->flags & WINED3D_NO3D))
3700  {
3702  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
3703  }
3704 
3705  --sub_resource->map_count;
3706  if (!--texture->resource.map_count && texture->update_map_binding)
3708  if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
3710 
3711  return WINED3D_OK;
3712 }
HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device, enum wined3d_resource_type type, const struct wined3d_format *format, enum wined3d_multisample_type multisample_type, unsigned int multisample_quality, unsigned int usage, unsigned int access, unsigned int width, unsigned int height, unsigned int depth, unsigned int size, void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops)
Definition: resource.c:59
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
void CDECL wined3d_device_update_sub_resource(struct wined3d_device *device, struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, unsigned int depth_pitch)
Definition: device.c:4281
#define WINED3DFMT_FLAG_STENCIL
static GLenum wined3d_texture_get_sub_resource_target(const struct wined3d_texture *texture, unsigned int sub_resource_idx)
#define GL_RENDERBUFFER
Definition: glext.h:1733
static void wined3d_texture_force_reload(struct wined3d_texture *texture)
Definition: texture.c:1531
ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain)
Definition: swapchain.c:113
const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion(const struct wined3d_texture *texture, BOOL need_alpha_ck)
Definition: utils.c:1046
static void wined3d_texture_destroy_object(void *object)
Definition: texture.c:1017
#define WINED3DERR_INVALIDCALL
Definition: wined3d.h:48
struct wined3d_texture * front_buffer
#define GL_BACK
Definition: gl.h:271
#define WINED3D_CKEY_DST_OVERLAY
Definition: wined3d.h:1335
GLsizei samples
Definition: glext.h:7006
GLint level
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
unsigned short x_source
#define max(a, b)
Definition: svc.c:63
void *CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture)
Definition: texture.c:1121
#define TRUE
Definition: types.h:120
static unsigned int wined3d_texture_get_level_height(const struct wined3d_texture *texture, unsigned int level)
#define GL_RED
Definition: gl.h:480
#define GL_ONE
Definition: gl.h:375
#define WINED3DUSAGE_OVERLAY
Definition: wined3d.h:921
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
static BOOL needs_separate_srgb_gl_texture(const struct wined3d_context *context, const struct wined3d_texture *texture)
struct opengl_funcs gl_ops
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define GL_CLAMP_TO_EDGE
Definition: gl.h:1481
long y
Definition: polytest.cpp:48
static void wined3d_texture_unload(struct wined3d_resource *resource)
Definition: texture.c:2235
#define WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS
Definition: wined3d.h:1562
HRESULT hr
Definition: shlfolder.c:183
#define __cdecl
Definition: accygwin.h:79
void context_unmap_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *data, GLenum binding)
Definition: context.c:2831
#define WINED3D_TEXTURE_SRGB_VALID
#define GL_TEXTURE_LOD_BIAS_EXT
Definition: glext.h:3362
#define GL_TEXTURE_SRGB_DECODE_EXT
Definition: glext.h:5289
static unsigned int wined3d_texture_get_gl_sample_count(const struct wined3d_texture *texture)
Definition: texture.c:484
long x
Definition: polytest.cpp:48
static const struct wined3d_texture_ops texture2d_ops
Definition: texture.c:2202
#define RESOURCE_ALIGNMENT
Definition: http.c:7098
#define WINED3D_CKEY_SRC_BLT
Definition: wined3d.h:1336
DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod)
Definition: texture.c:1186
static unsigned int wined3d_texture_get_level_width(const struct wined3d_texture *texture, unsigned int level)
static const struct wined3d_texture_ops texture1d_ops
Definition: texture.c:2076
void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
Definition: texture.c:1546
unsigned short w_source
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define GL_FALSE
Definition: gl.h:173
HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device, UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
Definition: texture.c:1094
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define WINED3DUSAGE_DYNAMIC
Definition: wined3d.h:907
#define GL_NEAREST
Definition: gl.h:678
#define GL_ALPHA
Definition: gl.h:483
#define WINED3D_TEXTURE_POW2_MAT_IDENT
static unsigned int wined3d_popcount(unsigned int x)
static BOOL can_use_texture_swizzle(const struct wined3d_gl_info *gl_info, const struct wined3d_format *format)
#define WARN(fmt,...)
Definition: debug.h:111
#define ERR_(ch,...)
Definition: debug.h:156
#define WINED3DFMT_FLAG_BROKEN_PITCH
LONG NTSTATUS
Definition: precomp.h:26
#define WINED3DFMT_FLAG_BLOCKS
static HDC
Definition: imagelist.c:92
GLintptr offset
Definition: glext.h:5920
static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
Definition: texture.c:2113
#define GL_TEXTURE_SWIZZLE_RGBA
Definition: glext.h:2032
const struct wined3d_renderbuffer_entry * current_renderbuffer
LONG top
Definition: windef.h:307
static void texture3d_srgb_transfer(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, BOOL dest_is_srgb)
Definition: texture.c:2987
static unsigned int wined3d_texture_get_level_depth(const struct wined3d_texture *texture, unsigned int level)
HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc)
Definition: texture.c:3671
const struct wined3d_format * wined3d_get_format(const struct wined3d_gl_info *gl_info, enum wined3d_format_id format_id, unsigned int resource_usage)
Definition: utils.c:3831
static void texture2d_create_dc(void *object)
Definition: texture.c:1255
const char * debug_box(const struct wined3d_box *box)
Definition: utils.c:3939
#define WINED3D_LOCATION_BUFFER
struct wined3d_resource resource
static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture)
Definition: texture.c:594
GLuint buffer
Definition: glext.h:5915
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
HRESULT CDECL wined3d_texture_get_sub_resource_desc(const struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_sub_resource_desc *desc)
Definition: texture.c:3480
const GLvdpauSurfaceNV * surfaces
Definition: glext.h:11586
void wined3d_cs_init_object(struct wined3d_cs *cs, void(*callback)(void *object), void *object)
Definition: cs.c:1890
#define WINED3DUSAGE_DEPTHSTENCIL
Definition: wined3d.h:900
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
unsigned int texture_level
void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource)
Definition: cs.c:1978
#define CHAR_BIT
Definition: urlcache.c:58
#define WINED3D_RESOURCE_ACCESS_MAP_W
Definition: wined3d.h:58
DWORD color_space_low_value
Definition: wined3d.h:1980
#define WINED3D_TEXTURE_ASYNC_COLOR_KEY
void context_invalidate_state(struct wined3d_context *context, DWORD state)
Definition: context.c:1652
void wined3d_cs_destroy_object(struct wined3d_cs *cs, void(*callback)(void *object), void *object)
Definition: cs.c:1885
void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context *context)
Definition: texture.c:896
void resource_unload(struct wined3d_resource *resource)
Definition: resource.c:257
LONG left
Definition: windef.h:306
void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name)
Definition: context.c:2734
#define WINED3D_TEXTURE_COND_NP2
HRESULT wined3d_texture_check_box_dimensions(const struct wined3d_texture *texture, unsigned int level, const struct wined3d_box *box)
Definition: texture.c:1128
int resource
Definition: rdpsnd_sgi.c:44
static void * heap_calloc(SIZE_T count, SIZE_T size)
Definition: heap.h:49
struct wined3d_texture ** back_buffers
LONG right
Definition: windef.h:308
#define GL_STREAM_DRAW
Definition: glext.h:347
static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx, struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
Definition: texture.c:2302
static ULONG texture_resource_incref(struct wined3d_resource *resource)
Definition: texture.c:2215
#define GL_UNPACK_ROW_LENGTH
Definition: gl.h:634
GLint wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP+1]
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static BOOL wined3d_texture_copy_sysmem_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
Definition: texture.c:184
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define WINED3D_TEXTURE_CREATE_GET_DC
Definition: wined3d.h:1561
static BOOL wined3d_texture_use_immutable_storage(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
Definition: texture.c:42
static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture)
Definition: texture.c:1009
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
void CDECL wined3d_texture_set_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx, void *parent)
Definition: texture.c:3464
void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain)
Definition: texture.c:722
static void wined3d_texture_allocate_gl_mutable_storage(struct wined3d_texture *texture, GLenum gl_internal_format, const struct wined3d_format *format, const struct wined3d_gl_info *gl_info)
Definition: texture.c:518
WINE_DEFAULT_DEBUG_CHANNEL(d3d8)
static void wined3d_resource_wait_idle(struct wined3d_resource *resource)
struct wined3d_texture *__cdecl wined3d_texture_from_resource(struct wined3d_resource *resource)
Definition: texture.c:2210
DWORD CDECL wined3d_texture_get_level_count(const struct wined3d_texture *texture)
Definition: texture.c:1228
GLAPI void GLAPIENTRY glTexImage3D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
static void wined3d_texture_prepare_rb(struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info, BOOL multisample)
Definition: texture.c:1568
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define GL_TEXTURE_CUBE_MAP_ARB
Definition: glext.h:1230
#define WINED3D_RESOURCE_ACCESS_CPU
Definition: wined3d.h:56
#define WARN_ON(c)
Definition: module.h:255
HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture *texture, unsigned int sub_resource_idx, LONG *x, LONG *y)
Definition: texture.c:3325
#define GL_TEXTURE_2D_MULTISAMPLE
Definition: glext.h:1939
#define WINED3D_TEXTURE_SRGB_ALLOCATED
#define WINED3D_TEXTURE_CREATE_DISCARD
Definition: wined3d.h:1559
#define GL_TEXTURE_RECTANGLE_ARB
Definition: glext.h:1614
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define GL_TEXTURE_WRAP_R
Definition: gl.h:1518
static void create_dib(STGMEDIUM *med)
Definition: ole2.c:211
static void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture)
Definition: texture.c:636
#define WINED3D_TEXTURE_IS_SRGB
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define WINED3D_TEXTURE_GENERATE_MIPMAPS
#define GL_TEXTURE_1D
Definition: gl.h:644
const char * wined3d_debug_location(DWORD location)
Definition: utils.c:6396
enum wined3d_format_id dst_format
unsigned int BOOL
Definition: ntddk_ex.h:94
static void gltexture_delete(struct wined3d_device *device, const struct wined3d_gl_info *gl_info, struct gl_texture *tex)
Definition: texture.c:476
#define WINED3D_TEXTURE_GET_DC_LENIENT
long LONG
Definition: pedump.c:60
wined3d_texture_filter_type
Definition: wined3d.h:683
Definition: devices.h:37
#define WINED3D_LOCATION_RB_MULTISAMPLE
int GLsizei
Definition: gl.h:160
#define GL_FRONT
Definition: gl.h:270
static const WCHAR desc[]
Definition: protectdata.c:36
#define GL_ZERO
Definition: gl.h:374
#define WINED3D_CKEY_SRC_OVERLAY
Definition: wined3d.h:1337
#define WINED3DFMT_FLAG_TEXTURE
static BOOL wined3d_resource_access_is_managed(unsigned int access)
static void wined3d_texture_set_dirty(struct wined3d_texture *texture)
Definition: texture.c:154
#define FIXME(fmt,...)
Definition: debug.h:110
BOOL supported[WINED3D_GL_EXT_COUNT]
unsigned int idx
Definition: utils.c:41
#define ORM_BACKBUFFER
#define WINED3D_LOCATION_RB_RESOLVED
#define E_INVALIDARG
Definition: ddrawi.h:101
GLdouble GLdouble z
Definition: glext.h:5874
static void wined3d_texture_cleanup(struct wined3d_texture *texture)
Definition: texture.c:654
static GLenum wined3d_gl_min_mip_filter(enum wined3d_texture_filter_type min_filter, enum wined3d_texture_filter_type mip_filter)
#define GL_TEXTURE_3D
Definition: gl.h:1515
#define GL_PIXEL_UNPACK_BUFFER
Definition: glext.h:477
smooth NULL
Definition: ftsmooth.c:416
#define GL_TEXTURE_WRAP_T
Definition: gl.h:647
static void texture2d_destroy_dc(void *object)
Definition: texture.c:1316
#define WINED3D_LOCATION_DRAWABLE
#define WINEDDOVER_SHOW
Definition: wined3d.h:1404
#define WINED3D_TEXTURE_GET_DC
void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_bo_address *data, DWORD locations)
Definition: texture.c:285
static void texture3d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
Definition: texture.c:3120
unsigned short z_source
void context_release(struct wined3d_context *context)
Definition: context.c:1571
void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, enum wined3d_sampler_state state, DWORD value)
Definition: cs.c:1538
#define WINED3DUSAGE_LEGACY_CUBEMAP
Definition: wined3d.h:917
#define WINED3DUSAGE_QUERY_GENMIPMAP
Definition: wined3d.h:923
#define GL_TEXTURE_MIN_FILTER
Definition: gl.h:649
static const struct wined3d_resource_ops texture_resource_ops
Definition: texture.c:2507
#define STATE_GRAPHICS_SHADER_RESOURCE_BINDING