ReactOS  0.4.12-dev-90-g2e2e63e
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 
34 {
36  unsigned int sub_resource_idx;
37 };
38 
40 {
41  float l;
42  float t;
43  float r;
44  float b;
45 };
46 
47 static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
48 {
49  return !(texture->resource.access & WINED3D_RESOURCE_ACCESS_CPU)
50  && texture->resource.usage & WINED3DUSAGE_DYNAMIC
52  && !texture->resource.format->conv_byte_count
54 }
55 
57  const struct wined3d_gl_info *gl_info)
58 {
59  /* We don't expect to create texture views for textures with height-scaled formats.
60  * Besides, ARB_texture_storage doesn't allow specifying exact sizes for all levels. */
61  return gl_info->supported[ARB_TEXTURE_STORAGE]
62  && !(texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE);
63 }
64 
65 /* Front buffer coordinates are always full screen coordinates, but our GL
66  * drawable is limited to the window's client area. The sysmem and texture
67  * copies do have the full screen size. Note that GL has a bottom-left
68  * origin, while D3D has a top-left origin. */
70 {
71  unsigned int drawable_height;
72  POINT offset = {0, 0};
73  RECT windowsize;
74 
75  if (!texture->swapchain)
76  return;
77 
78  if (texture == texture->swapchain->front_buffer)
79  {
80  ScreenToClient(window, &offset);
81  OffsetRect(rect, offset.x, offset.y);
82  }
83 
84  GetClientRect(window, &windowsize);
85  drawable_height = windowsize.bottom - windowsize.top;
86 
87  rect->top = drawable_height - rect->top;
88  rect->bottom = drawable_height - rect->bottom;
89 }
90 
92 {
93  const struct wined3d_swapchain *swapchain = texture->swapchain;
94 
95  TRACE("texture %p.\n", texture);
96 
97  if (!swapchain)
98  {
99  ERR("Texture %p is not part of a swapchain.\n", texture);
100  return GL_NONE;
101  }
102 
103  if (texture == swapchain->front_buffer)
104  {
105  TRACE("Returning GL_FRONT.\n");
106  return GL_FRONT;
107  }
108 
109  if (texture == swapchain->back_buffers[0])
110  {
111  TRACE("Returning GL_BACK.\n");
112  return GL_BACK;
113  }
114 
115  FIXME("Higher back buffer, returning GL_BACK.\n");
116  return GL_BACK;
117 }
118 
120 {
121  switch (location)
122  {
124  return 0;
125 
129 
137 
138  default:
139  FIXME("Unhandled location %#x.\n", location);
140  return 0;
141  }
142 }
143 
144 static inline void cube_coords_float(const RECT *r, UINT w, UINT h, struct wined3d_rect_f *f)
145 {
146  f->l = ((r->left * 2.0f) / w) - 1.0f;
147  f->t = ((r->top * 2.0f) / h) - 1.0f;
148  f->r = ((r->right * 2.0f) / w) - 1.0f;
149  f->b = ((r->bottom * 2.0f) / h) - 1.0f;
150 }
151 
153  unsigned int sub_resource_idx, const RECT *rect, struct wined3d_blt_info *info)
154 {
155  struct wined3d_vec3 *coords = info->texcoords;
156  struct wined3d_rect_f f;
157  unsigned int level;
158  GLenum target;
159  GLsizei w, h;
160 
161  level = sub_resource_idx % texture->level_count;
162  w = wined3d_texture_get_level_pow2_width(texture, level);
163  h = wined3d_texture_get_level_pow2_height(texture, level);
164  target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
165 
166  switch (target)
167  {
168  default:
169  FIXME("Unsupported texture target %#x.\n", target);
170  /* Fall back to GL_TEXTURE_2D */
171  case GL_TEXTURE_2D:
172  info->bind_target = GL_TEXTURE_2D;
173  coords[0].x = (float)rect->left / w;
174  coords[0].y = (float)rect->top / h;
175  coords[0].z = 0.0f;
176 
177  coords[1].x = (float)rect->right / w;
178  coords[1].y = (float)rect->top / h;
179  coords[1].z = 0.0f;
180 
181  coords[2].x = (float)rect->left / w;
182  coords[2].y = (float)rect->bottom / h;
183  coords[2].z = 0.0f;
184 
185  coords[3].x = (float)rect->right / w;
186  coords[3].y = (float)rect->bottom / h;
187  coords[3].z = 0.0f;
188  break;
189 
192  coords[0].x = rect->left; coords[0].y = rect->top; coords[0].z = 0.0f;
193  coords[1].x = rect->right; coords[1].y = rect->top; coords[1].z = 0.0f;
194  coords[2].x = rect->left; coords[2].y = rect->bottom; coords[2].z = 0.0f;
195  coords[3].x = rect->right; coords[3].y = rect->bottom; coords[3].z = 0.0f;
196  break;
197 
200  cube_coords_float(rect, w, h, &f);
201 
202  coords[0].x = 1.0f; coords[0].y = -f.t; coords[0].z = -f.l;
203  coords[1].x = 1.0f; coords[1].y = -f.t; coords[1].z = -f.r;
204  coords[2].x = 1.0f; coords[2].y = -f.b; coords[2].z = -f.l;
205  coords[3].x = 1.0f; coords[3].y = -f.b; coords[3].z = -f.r;
206  break;
207 
210  cube_coords_float(rect, w, h, &f);
211 
212  coords[0].x = -1.0f; coords[0].y = -f.t; coords[0].z = f.l;
213  coords[1].x = -1.0f; coords[1].y = -f.t; coords[1].z = f.r;
214  coords[2].x = -1.0f; coords[2].y = -f.b; coords[2].z = f.l;
215  coords[3].x = -1.0f; coords[3].y = -f.b; coords[3].z = f.r;
216  break;
217 
220  cube_coords_float(rect, w, h, &f);
221 
222  coords[0].x = f.l; coords[0].y = 1.0f; coords[0].z = f.t;
223  coords[1].x = f.r; coords[1].y = 1.0f; coords[1].z = f.t;
224  coords[2].x = f.l; coords[2].y = 1.0f; coords[2].z = f.b;
225  coords[3].x = f.r; coords[3].y = 1.0f; coords[3].z = f.b;
226  break;
227 
230  cube_coords_float(rect, w, h, &f);
231 
232  coords[0].x = f.l; coords[0].y = -1.0f; coords[0].z = -f.t;
233  coords[1].x = f.r; coords[1].y = -1.0f; coords[1].z = -f.t;
234  coords[2].x = f.l; coords[2].y = -1.0f; coords[2].z = -f.b;
235  coords[3].x = f.r; coords[3].y = -1.0f; coords[3].z = -f.b;
236  break;
237 
240  cube_coords_float(rect, w, h, &f);
241 
242  coords[0].x = f.l; coords[0].y = -f.t; coords[0].z = 1.0f;
243  coords[1].x = f.r; coords[1].y = -f.t; coords[1].z = 1.0f;
244  coords[2].x = f.l; coords[2].y = -f.b; coords[2].z = 1.0f;
245  coords[3].x = f.r; coords[3].y = -f.b; coords[3].z = 1.0f;
246  break;
247 
250  cube_coords_float(rect, w, h, &f);
251 
252  coords[0].x = -f.l; coords[0].y = -f.t; coords[0].z = -1.0f;
253  coords[1].x = -f.r; coords[1].y = -f.t; coords[1].z = -1.0f;
254  coords[2].x = -f.l; coords[2].y = -f.b; coords[2].z = -1.0f;
255  coords[3].x = -f.r; coords[3].y = -f.b; coords[3].z = -1.0f;
256  break;
257  }
258 }
259 
261 {
262  struct wined3d_texture_sub_resource *sub_resource;
263  unsigned int i, sub_count;
264 
267  {
268  TRACE("Not evicting system memory for texture %p.\n", texture);
269  return;
270  }
271 
272  TRACE("Evicting system memory for texture %p.\n", texture);
273 
274  sub_count = texture->level_count * texture->layer_count;
275  for (i = 0; i < sub_count; ++i)
276  {
277  sub_resource = &texture->sub_resources[i];
278  if (sub_resource->locations == WINED3D_LOCATION_SYSMEM)
279  ERR("WINED3D_LOCATION_SYSMEM is the only location for sub-resource %u of texture %p.\n",
280  i, texture);
281  sub_resource->locations &= ~WINED3D_LOCATION_SYSMEM;
282  }
284 }
285 
287  unsigned int sub_resource_idx, DWORD location)
288 {
289  struct wined3d_texture_sub_resource *sub_resource;
290  DWORD previous_locations;
291 
292  TRACE("texture %p, sub_resource_idx %u, location %s.\n",
293  texture, sub_resource_idx, wined3d_debug_location(location));
294 
295  sub_resource = &texture->sub_resources[sub_resource_idx];
296  previous_locations = sub_resource->locations;
297  sub_resource->locations |= location;
298  if (previous_locations == WINED3D_LOCATION_SYSMEM && location != WINED3D_LOCATION_SYSMEM
299  && !--texture->sysmem_count)
301 
302  TRACE("New locations flags are %s.\n", wined3d_debug_location(sub_resource->locations));
303 }
304 
306 {
308 }
309 
311  unsigned int sub_resource_idx, DWORD location)
312 {
313  struct wined3d_texture_sub_resource *sub_resource;
314  DWORD previous_locations;
315 
316  TRACE("texture %p, sub_resource_idx %u, location %s.\n",
317  texture, sub_resource_idx, wined3d_debug_location(location));
318 
320  wined3d_texture_set_dirty(texture);
321 
322  sub_resource = &texture->sub_resources[sub_resource_idx];
323  previous_locations = sub_resource->locations;
324  sub_resource->locations &= ~location;
325  if (previous_locations != WINED3D_LOCATION_SYSMEM && sub_resource->locations == WINED3D_LOCATION_SYSMEM)
326  ++texture->sysmem_count;
327 
328  TRACE("New locations flags are %s.\n", wined3d_debug_location(sub_resource->locations));
329 
330  if (!sub_resource->locations)
331  ERR("Sub-resource %u of texture %p does not have any up to date location.\n",
332  sub_resource_idx, texture);
333 }
334 
336  unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
337 {
338  unsigned int size = texture->sub_resources[sub_resource_idx].size;
339  struct wined3d_device *device = texture->resource.device;
340  const struct wined3d_gl_info *gl_info;
341  struct wined3d_bo_address dst, src;
342 
343  if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
344  return FALSE;
345 
346  wined3d_texture_get_memory(texture, sub_resource_idx, &dst, location);
347  wined3d_texture_get_memory(texture, sub_resource_idx, &src,
348  texture->sub_resources[sub_resource_idx].locations);
349 
350  if (dst.buffer_object)
351  {
352  context = context_acquire(device, NULL, 0);
353  gl_info = context->gl_info;
354  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, dst.buffer_object));
355  GL_EXTCALL(glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, size, src.addr));
356  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
357  checkGLcall("PBO upload");
358  context_release(context);
359  return TRUE;
360  }
361 
362  if (src.buffer_object)
363  {
364  context = context_acquire(device, NULL, 0);
365  gl_info = context->gl_info;
366  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, src.buffer_object));
367  GL_EXTCALL(glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, size, dst.addr));
368  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
369  checkGLcall("PBO download");
370  context_release(context);
371  return TRUE;
372  }
373 
374  memcpy(dst.addr, src.addr, size);
375  return TRUE;
376 }
377 
378 /* Context activation is done by the caller. Context may be NULL in
379  * WINED3D_NO3D mode. */
381  unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
382 {
383  static const DWORD sysmem_locations = WINED3D_LOCATION_SYSMEM | WINED3D_LOCATION_USER_MEMORY
385  DWORD current = texture->sub_resources[sub_resource_idx].locations;
386  BOOL ret;
387 
388  TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
389  texture, sub_resource_idx, context, wined3d_debug_location(location));
390 
391  TRACE("Current resource location %s.\n", wined3d_debug_location(current));
392 
393  if (current & location)
394  {
395  TRACE("Location %s is already up to date.\n", wined3d_debug_location(location));
396  return TRUE;
397  }
398 
399  if (WARN_ON(d3d))
400  {
401  DWORD required_access = wined3d_resource_access_from_location(location);
402  if ((texture->resource.access & required_access) != required_access)
403  WARN("Operation requires %#x access, but texture only has %#x.\n",
404  required_access, texture->resource.access);
405  }
406 
407  if (current & WINED3D_LOCATION_DISCARDED)
408  {
409  TRACE("Sub-resource previously discarded, nothing to do.\n");
410  if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
411  return FALSE;
412  wined3d_texture_validate_location(texture, sub_resource_idx, location);
413  wined3d_texture_invalidate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED);
414  return TRUE;
415  }
416 
417  if (!current)
418  {
419  ERR("Sub-resource %u of texture %p does not have any up to date location.\n",
420  sub_resource_idx, texture);
421  wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_DISCARDED);
422  return wined3d_texture_load_location(texture, sub_resource_idx, context, location);
423  }
424 
425  if ((location & sysmem_locations) && (current & sysmem_locations))
426  ret = wined3d_texture_copy_sysmem_location(texture, sub_resource_idx, context, location);
427  else
428  ret = texture->texture_ops->texture_load_location(texture, sub_resource_idx, context, location);
429 
430  if (ret)
431  wined3d_texture_validate_location(texture, sub_resource_idx, location);
432 
433  return ret;
434 }
435 
438 {
439  struct wined3d_texture_sub_resource *sub_resource;
440 
441  TRACE("texture %p, sub_resource_idx %u, data %p, locations %s.\n",
442  texture, sub_resource_idx, data, wined3d_debug_location(locations));
443 
444  sub_resource = &texture->sub_resources[sub_resource_idx];
445  if (locations & WINED3D_LOCATION_BUFFER)
446  {
447  data->addr = NULL;
448  data->buffer_object = sub_resource->buffer_object;
449  return;
450  }
451  if (locations & WINED3D_LOCATION_USER_MEMORY)
452  {
453  data->addr = texture->user_memory;
454  data->buffer_object = 0;
455  return;
456  }
457  if (locations & WINED3D_LOCATION_SYSMEM)
458  {
459  data->addr = texture->resource.heap_memory;
460  data->addr += sub_resource->offset;
461  data->buffer_object = 0;
462  return;
463  }
464 
465  ERR("Unexpected locations %s.\n", wined3d_debug_location(locations));
466  data->addr = NULL;
467  data->buffer_object = 0;
468 }
469 
470 /* Context activation is done by the caller. */
472  unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
473 {
474  GLuint *buffer_object = &texture->sub_resources[sub_resource_idx].buffer_object;
475 
476  GL_EXTCALL(glDeleteBuffers(1, buffer_object));
477  checkGLcall("glDeleteBuffers");
478 
479  TRACE("Deleted buffer object %u for texture %p, sub-resource %u.\n",
480  *buffer_object, texture, sub_resource_idx);
481 
483  *buffer_object = 0;
484 }
485 
487 {
488  unsigned int sub_count = texture->level_count * texture->layer_count;
489  const struct wined3d_device *device = texture->resource.device;
490  DWORD map_binding = texture->update_map_binding;
491  struct wined3d_context *context = NULL;
492  unsigned int i;
493 
494  if (device->d3d_initialized)
495  context = context_acquire(device, NULL, 0);
496 
497  for (i = 0; i < sub_count; ++i)
498  {
499  if (texture->sub_resources[i].locations == texture->resource.map_binding
500  && !wined3d_texture_load_location(texture, i, context, map_binding))
501  ERR("Failed to load location %s.\n", wined3d_debug_location(map_binding));
502  if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER)
503  wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
504  }
505 
506  if (context)
507  context_release(context);
508 
509  texture->resource.map_binding = map_binding;
510  texture->update_map_binding = 0;
511 }
512 
514 {
515  texture->update_map_binding = map_binding;
516  if (!texture->resource.map_count)
518 }
519 
520 /* A GL context is provided by the caller */
521 static void gltexture_delete(struct wined3d_device *device, const struct wined3d_gl_info *gl_info,
522  struct gl_texture *tex)
523 {
524  context_gl_resource_released(device, tex->name, FALSE);
525  gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex->name);
526  tex->name = 0;
527 }
528 
530 {
531  const struct wined3d_format *format = texture->resource.format;
532 
533  /* TODO: NVIDIA expose their Coverage Sample Anti-Aliasing (CSAA)
534  * feature through type == MULTISAMPLE_XX and quality != 0. This could
535  * be mapped to GL_NV_framebuffer_multisample_coverage.
536  *
537  * AMD have a similar feature called Enhanced Quality Anti-Aliasing
538  * (EQAA), but it does not have an equivalent OpenGL extension. */
539 
540  /* We advertise as many WINED3D_MULTISAMPLE_NON_MASKABLE quality
541  * levels as the count of advertised multisample types for the texture
542  * format. */
543  if (texture->resource.multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
544  {
545  unsigned int i, count = 0;
546 
547  for (i = 0; i < sizeof(format->multisample_types) * CHAR_BIT; ++i)
548  {
549  if (format->multisample_types & 1u << i)
550  {
551  if (texture->resource.multisample_quality == count++)
552  break;
553  }
554  }
555  return i + 1;
556  }
557 
558  return texture->resource.multisample_type;
559 }
560 
561 /* Context activation is done by the caller. */
562 /* The caller is responsible for binding the correct texture. */
564  GLenum gl_internal_format, const struct wined3d_format *format,
565  const struct wined3d_gl_info *gl_info)
566 {
567  unsigned int level, level_count, layer, layer_count;
569  GLenum target;
570 
571  level_count = texture->level_count;
572  if (texture->target == GL_TEXTURE_1D_ARRAY || texture->target == GL_TEXTURE_2D_ARRAY)
573  layer_count = 1;
574  else
575  layer_count = texture->layer_count;
576 
577  for (layer = 0; layer < layer_count; ++layer)
578  {
579  target = wined3d_texture_get_sub_resource_target(texture, layer * level_count);
580 
581  for (level = 0; level < level_count; ++level)
582  {
583  width = wined3d_texture_get_level_pow2_width(texture, level);
584  height = wined3d_texture_get_level_pow2_height(texture, level);
585  if (texture->resource.format_flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
586  {
587  height *= format->height_scale.numerator;
588  height /= format->height_scale.denominator;
589  }
590 
591  TRACE("texture %p, layer %u, level %u, target %#x, width %u, height %u.\n",
592  texture, layer, level, target, width, height);
593 
594  if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY)
595  {
596  depth = wined3d_texture_get_level_depth(texture, level);
597  GL_EXTCALL(glTexImage3D(target, level, gl_internal_format, width, height,
598  target == GL_TEXTURE_2D_ARRAY ? texture->layer_count : depth, 0,
599  format->glFormat, format->glType, NULL));
600  checkGLcall("glTexImage3D");
601  }
602  else if (target == GL_TEXTURE_1D)
603  {
604  gl_info->gl_ops.gl.p_glTexImage1D(target, level, gl_internal_format,
605  width, 0, format->glFormat, format->glType, NULL);
606  }
607  else
608  {
609  gl_info->gl_ops.gl.p_glTexImage2D(target, level, gl_internal_format, width,
610  target == GL_TEXTURE_1D_ARRAY ? texture->layer_count : height, 0,
611  format->glFormat, format->glType, NULL);
612  checkGLcall("glTexImage2D");
613  }
614  }
615  }
616 }
617 
618 /* Context activation is done by the caller. */
619 /* The caller is responsible for binding the correct texture. */
621  GLenum gl_internal_format, const struct wined3d_gl_info *gl_info)
622 {
623  unsigned int samples = wined3d_texture_get_gl_sample_count(texture);
626 
627  switch (texture->target)
628  {
629  case GL_TEXTURE_3D:
630  GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count,
631  gl_internal_format, width, height, wined3d_texture_get_level_depth(texture, 0)));
632  break;
633  case GL_TEXTURE_2D_ARRAY:
634  GL_EXTCALL(glTexStorage3D(texture->target, texture->level_count,
635  gl_internal_format, width, height, texture->layer_count));
636  break;
638  GL_EXTCALL(glTexStorage2DMultisample(texture->target, samples,
639  gl_internal_format, width, height, GL_FALSE));
640  break;
642  GL_EXTCALL(glTexStorage3DMultisample(texture->target, samples,
643  gl_internal_format, width, height, texture->layer_count, GL_FALSE));
644  break;
645  case GL_TEXTURE_1D_ARRAY:
646  GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
647  gl_internal_format, width, texture->layer_count));
648  break;
649  case GL_TEXTURE_1D:
650  GL_EXTCALL(glTexStorage1D(texture->target, texture->level_count, gl_internal_format, width));
651  break;
652  default:
653  GL_EXTCALL(glTexStorage2D(texture->target, texture->level_count,
654  gl_internal_format, width, height));
655  break;
656  }
657 
658  checkGLcall("allocate immutable storage");
659 }
660 
662 {
663  struct wined3d_device *device = texture->resource.device;
664  const struct wined3d_gl_info *gl_info = NULL;
665  struct wined3d_context *context = NULL;
666 
667  if (texture->texture_rgb.name || texture->texture_srgb.name
668  || texture->rb_multisample || texture->rb_resolved)
669  {
670  context = context_acquire(device, NULL, 0);
671  gl_info = context->gl_info;
672  }
673 
674  if (texture->texture_rgb.name)
675  gltexture_delete(device, context->gl_info, &texture->texture_rgb);
676 
677  if (texture->texture_srgb.name)
678  gltexture_delete(device, context->gl_info, &texture->texture_srgb);
679 
680  if (texture->rb_multisample)
681  {
682  TRACE("Deleting multisample renderbuffer %u.\n", texture->rb_multisample);
684  gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_multisample);
685  texture->rb_multisample = 0;
686  }
687 
688  if (texture->rb_resolved)
689  {
690  TRACE("Deleting resolved renderbuffer %u.\n", texture->rb_resolved);
691  context_gl_resource_released(device, texture->rb_resolved, TRUE);
692  gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture->rb_resolved);
693  texture->rb_resolved = 0;
694  }
695 
696  if (context) context_release(context);
697 
698  wined3d_texture_set_dirty(texture);
699 
700  resource_unload(&texture->resource);
701 }
702 
704 {
705  unsigned int sub_count = texture->level_count * texture->layer_count;
706  struct wined3d_texture_sub_resource *sub_resource;
707  unsigned int i;
708 
709  for (i = 0; i < sub_count; ++i)
710  {
711  sub_resource = &texture->sub_resources[i];
712  if (sub_resource->parent)
713  {
714  TRACE("sub-resource %u.\n", i);
715  sub_resource->parent_ops->wined3d_object_destroyed(sub_resource->parent);
716  sub_resource->parent = NULL;
717  }
718  }
719 }
720 
721 static void wined3d_texture_create_dc(void *object)
722 {
723  const struct wined3d_texture_idx *idx = object;
724  struct wined3d_context *context = NULL;
725  unsigned int sub_resource_idx, level;
726  const struct wined3d_format *format;
727  unsigned int row_pitch, slice_pitch;
728  struct wined3d_texture *texture;
729  struct wined3d_dc_info *dc_info;
730  struct wined3d_bo_address data;
732  struct wined3d_device *device;
734 
735  TRACE("texture %p, sub_resource_idx %u.\n", idx->texture, idx->sub_resource_idx);
736 
737  texture = idx->texture;
738  sub_resource_idx = idx->sub_resource_idx;
739  level = sub_resource_idx % texture->level_count;
740  device = texture->resource.device;
741 
742  format = texture->resource.format;
743  if (!format->ddi_format)
744  {
745  WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id));
746  return;
747  }
748 
749  if (!texture->dc_info)
750  {
751  unsigned int sub_count = texture->level_count * texture->layer_count;
752 
753  if (!(texture->dc_info = heap_calloc(sub_count, sizeof(*texture->dc_info))))
754  {
755  ERR("Failed to allocate DC info.\n");
756  return;
757  }
758  }
759 
760  if (device->d3d_initialized)
761  context = context_acquire(device, NULL, 0);
762 
763  wined3d_texture_load_location(texture, sub_resource_idx, context, texture->resource.map_binding);
764  wined3d_texture_invalidate_location(texture, sub_resource_idx, ~texture->resource.map_binding);
765  wined3d_texture_get_pitch(texture, level, &row_pitch, &slice_pitch);
766  wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
767  desc.pMemory = context_map_bo_address(context, &data,
768  texture->sub_resources[sub_resource_idx].size,
770 
771  if (context)
772  context_release(context);
773 
774  desc.Format = format->ddi_format;
775  desc.Width = wined3d_texture_get_level_width(texture, level);
776  desc.Height = wined3d_texture_get_level_height(texture, level);
777  desc.Pitch = row_pitch;
778  desc.hDeviceDc = CreateCompatibleDC(NULL);
779  desc.pColorTable = NULL;
780 
781  status = D3DKMTCreateDCFromMemory(&desc);
782  DeleteDC(desc.hDeviceDc);
783  if (status)
784  {
785  WARN("Failed to create DC, status %#x.\n", status);
786  return;
787  }
788 
789  dc_info = &texture->dc_info[sub_resource_idx];
790  dc_info->dc = desc.hDc;
791  dc_info->bitmap = desc.hBitmap;
792 
793  TRACE("Created DC %p, bitmap %p for texture %p, %u.\n", dc_info->dc, dc_info->bitmap, texture, sub_resource_idx);
794 }
795 
796 static void wined3d_texture_destroy_dc(void *object)
797 {
798  const struct wined3d_texture_idx *idx = object;
799  D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
800  struct wined3d_context *context = NULL;
801  struct wined3d_texture *texture;
802  struct wined3d_dc_info *dc_info;
803  struct wined3d_bo_address data;
804  unsigned int sub_resource_idx;
805  struct wined3d_device *device;
807 
808  texture = idx->texture;
809  sub_resource_idx = idx->sub_resource_idx;
810  device = texture->resource.device;
811  dc_info = &texture->dc_info[sub_resource_idx];
812 
813  if (!dc_info->dc)
814  {
815  ERR("Sub-resource {%p, %u} has no DC.\n", texture, sub_resource_idx);
816  return;
817  }
818 
819  TRACE("dc %p, bitmap %p.\n", dc_info->dc, dc_info->bitmap);
820 
821  destroy_desc.hDc = dc_info->dc;
822  destroy_desc.hBitmap = dc_info->bitmap;
823  if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc)))
824  ERR("Failed to destroy dc, status %#x.\n", status);
825  dc_info->dc = NULL;
826  dc_info->bitmap = NULL;
827 
828  if (device->d3d_initialized)
829  context = context_acquire(device, NULL, 0);
830 
831  wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
833 
834  if (context)
835  context_release(context);
836 }
837 
839 {
840  unsigned int sub_count = texture->level_count * texture->layer_count;
841  struct wined3d_device *device = texture->resource.device;
842  struct wined3d_renderbuffer_entry *entry, *entry2;
843  const struct wined3d_gl_info *gl_info = NULL;
844  struct wined3d_context *context = NULL;
845  struct wined3d_dc_info *dc_info;
846  GLuint buffer_object;
847  unsigned int i;
848 
849  TRACE("texture %p.\n", texture);
850 
851  for (i = 0; i < sub_count; ++i)
852  {
853  if (!(buffer_object = texture->sub_resources[i].buffer_object))
854  continue;
855 
856  TRACE("Deleting buffer object %u.\n", buffer_object);
857 
858  /* We may not be able to get a context in wined3d_texture_cleanup() in
859  * general, but if a buffer object was previously created we can. */
860  if (!context)
861  {
862  context = context_acquire(device, NULL, 0);
863  gl_info = context->gl_info;
864  }
865 
866  GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
867  }
868 
869  if (!context && !list_empty(&texture->renderbuffers))
870  {
871  context = context_acquire(device, NULL, 0);
872  gl_info = context->gl_info;
873  }
874 
875  LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry)
876  {
877  TRACE("Deleting renderbuffer %u.\n", entry->id);
878  context_gl_resource_released(device, entry->id, TRUE);
879  gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
880  heap_free(entry);
881  }
882 
883  if (context)
884  context_release(context);
885 
886  if ((dc_info = texture->dc_info))
887  {
888  for (i = 0; i < sub_count; ++i)
889  {
890  if (dc_info[i].dc)
891  {
892  struct wined3d_texture_idx texture_idx = {texture, i};
893 
894  wined3d_texture_destroy_dc(&texture_idx);
895  }
896  }
897  heap_free(dc_info);
898  }
899 
900  if (texture->overlay_info)
901  {
902  for (i = 0; i < sub_count; ++i)
903  {
904  struct wined3d_overlay_info *info = &texture->overlay_info[i];
905  struct wined3d_overlay_info *overlay, *cur;
906 
907  list_remove(&info->entry);
908  LIST_FOR_EACH_ENTRY_SAFE(overlay, cur, &info->overlays, struct wined3d_overlay_info, entry)
909  {
910  list_remove(&overlay->entry);
911  }
912  }
913  heap_free(texture->overlay_info);
914  }
916 }
917 
919 {
920  texture->swapchain = swapchain;
922 }
923 
924 /* Context activation is done by the caller. */
926  struct wined3d_context *context, BOOL srgb)
927 {
928  const struct wined3d_gl_info *gl_info = context->gl_info;
929  const struct wined3d_format *format = texture->resource.format;
930  const struct color_fixup_desc fixup = format->color_fixup;
931  struct gl_texture *gl_tex;
932  GLenum target;
933 
934  TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
935 
936  if (!needs_separate_srgb_gl_texture(context, texture))
937  srgb = FALSE;
938 
939  /* sRGB mode cache for preload() calls outside drawprim. */
940  if (srgb)
941  texture->flags |= WINED3D_TEXTURE_IS_SRGB;
942  else
943  texture->flags &= ~WINED3D_TEXTURE_IS_SRGB;
944 
945  gl_tex = wined3d_texture_get_gl_texture(texture, srgb);
946  target = texture->target;
947 
948  if (gl_tex->name)
949  {
950  context_bind_texture(context, target, gl_tex->name);
951  return;
952  }
953 
954  gl_info->gl_ops.gl.p_glGenTextures(1, &gl_tex->name);
955  checkGLcall("glGenTextures");
956  TRACE("Generated texture %d.\n", gl_tex->name);
957 
958  if (!gl_tex->name)
959  {
960  ERR("Failed to generate a texture name.\n");
961  return;
962  }
963 
964  /* Initialise the state of the texture object to the OpenGL defaults, not
965  * the wined3d defaults. */
966  gl_tex->sampler_desc.address_u = WINED3D_TADDRESS_WRAP;
967  gl_tex->sampler_desc.address_v = WINED3D_TADDRESS_WRAP;
968  gl_tex->sampler_desc.address_w = WINED3D_TADDRESS_WRAP;
969  memset(gl_tex->sampler_desc.border_color, 0, sizeof(gl_tex->sampler_desc.border_color));
970  gl_tex->sampler_desc.mag_filter = WINED3D_TEXF_LINEAR;
971  gl_tex->sampler_desc.min_filter = WINED3D_TEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
972  gl_tex->sampler_desc.mip_filter = WINED3D_TEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
973  gl_tex->sampler_desc.lod_bias = 0.0f;
974  gl_tex->sampler_desc.min_lod = -1000.0f;
975  gl_tex->sampler_desc.max_lod = 1000.0f;
976  gl_tex->sampler_desc.max_anisotropy = 1;
977  gl_tex->sampler_desc.compare = FALSE;
978  gl_tex->sampler_desc.comparison_func = WINED3D_CMP_LESSEQUAL;
979  if (context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
980  gl_tex->sampler_desc.srgb_decode = TRUE;
981  else
982  gl_tex->sampler_desc.srgb_decode = srgb;
983  gl_tex->base_level = 0;
984  wined3d_texture_set_dirty(texture);
985 
986  context_bind_texture(context, target, gl_tex->name);
987 
988  /* For a new texture we have to set the texture levels after binding the
989  * texture. Beware that texture rectangles do not support mipmapping, but
990  * set the maxmiplevel if we're relying on the partial
991  * GL_ARB_texture_non_power_of_two emulation with texture rectangles.
992  * (I.e., do not care about cond_np2 here, just look for
993  * GL_TEXTURE_RECTANGLE_ARB.) */
994  if (target != GL_TEXTURE_RECTANGLE_ARB)
995  {
996  TRACE("Setting GL_TEXTURE_MAX_LEVEL to %u.\n", texture->level_count - 1);
997  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count - 1);
998  checkGLcall("glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, texture->level_count)");
999  }
1000 
1001  if (target == GL_TEXTURE_CUBE_MAP_ARB)
1002  {
1003  /* Cubemaps are always set to clamp, regardless of the sampler state. */
1004  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1005  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1006  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1007  }
1008 
1009  if (texture->flags & WINED3D_TEXTURE_COND_NP2)
1010  {
1011  /* Conditinal non power of two textures use a different clamping
1012  * default. If we're using the GL_WINE_normalized_texrect partial
1013  * driver emulation, we're dealing with a GL_TEXTURE_2D texture which
1014  * has the address mode set to repeat - something that prevents us
1015  * from hitting the accelerated codepath. Thus manually set the GL
1016  * state. The same applies to filtering. Even if the texture has only
1017  * one mip level, the default LINEAR_MIPMAP_LINEAR filter causes a SW
1018  * fallback on macos. */
1019  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1020  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1021  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1022  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1023  checkGLcall("glTexParameteri");
1024  gl_tex->sampler_desc.address_u = WINED3D_TADDRESS_CLAMP;
1025  gl_tex->sampler_desc.address_v = WINED3D_TADDRESS_CLAMP;
1026  gl_tex->sampler_desc.mag_filter = WINED3D_TEXF_POINT;
1027  gl_tex->sampler_desc.min_filter = WINED3D_TEXF_POINT;
1028  gl_tex->sampler_desc.mip_filter = WINED3D_TEXF_NONE;
1029  }
1030 
1032  {
1033  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
1034  checkGLcall("glTexParameteri(GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY)");
1035  }
1036 
1037  if (!is_identity_fixup(fixup) && can_use_texture_swizzle(gl_info, format))
1038  {
1039  static const GLenum swizzle_source[] =
1040  {
1041  GL_ZERO, /* CHANNEL_SOURCE_ZERO */
1042  GL_ONE, /* CHANNEL_SOURCE_ONE */
1043  GL_RED, /* CHANNEL_SOURCE_X */
1044  GL_GREEN, /* CHANNEL_SOURCE_Y */
1045  GL_BLUE, /* CHANNEL_SOURCE_Z */
1046  GL_ALPHA, /* CHANNEL_SOURCE_W */
1047  };
1048  struct
1049  {
1050  GLint x, y, z, w;
1051  }
1052  swizzle;
1053 
1054  swizzle.x = swizzle_source[fixup.x_source];
1055  swizzle.y = swizzle_source[fixup.y_source];
1056  swizzle.z = swizzle_source[fixup.z_source];
1057  swizzle.w = swizzle_source[fixup.w_source];
1058  gl_info->gl_ops.gl.p_glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, &swizzle.x);
1059  checkGLcall("glTexParameteriv(GL_TEXTURE_SWIZZLE_RGBA)");
1060  }
1061 }
1062 
1063 /* Context activation is done by the caller. */
1065  struct wined3d_context *context, BOOL srgb)
1066 {
1067  /* We don't need a specific texture unit, but after binding the texture
1068  * the current unit is dirty. Read the unit back instead of switching to
1069  * 0, this avoids messing around with the state manager's GL states. The
1070  * current texture unit should always be a valid one.
1071  *
1072  * To be more specific, this is tricky because we can implicitly be
1073  * called from sampler() in state.c. This means we can't touch anything
1074  * other than whatever happens to be the currently active texture, or we
1075  * would risk marking already applied sampler states dirty again. */
1076  if (context->active_texture < ARRAY_SIZE(context->rev_tex_unit_map))
1077  {
1078  DWORD active_sampler = context->rev_tex_unit_map[context->active_texture];
1079  if (active_sampler != WINED3D_UNMAPPED_STAGE)
1080  context_invalidate_state(context, STATE_SAMPLER(active_sampler));
1081  }
1082  /* FIXME: Ideally we'd only do this when touching a binding that's used by
1083  * a shader. */
1086 
1087  wined3d_texture_bind(texture, context, srgb);
1088 }
1089 
1090 /* Context activation is done by the caller (state handler). */
1091 /* This function relies on the correct texture being bound and loaded. */
1093  const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context *context)
1094 {
1095  const struct wined3d_gl_info *gl_info = context->gl_info;
1096  GLenum target = texture->target;
1097  struct gl_texture *gl_tex;
1098  DWORD state;
1099 
1100  TRACE("texture %p, sampler_desc %p, context %p.\n", texture, sampler_desc, context);
1101 
1102  gl_tex = wined3d_texture_get_gl_texture(texture, texture->flags & WINED3D_TEXTURE_IS_SRGB);
1103 
1104  state = sampler_desc->address_u;
1105  if (state != gl_tex->sampler_desc.address_u)
1106  {
1107  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_S,
1108  gl_info->wrap_lookup[state - WINED3D_TADDRESS_WRAP]);
1109  gl_tex->sampler_desc.address_u = state;
1110  }
1111 
1112  state = sampler_desc->address_v;
1113  if (state != gl_tex->sampler_desc.address_v)
1114  {
1115  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_T,
1116  gl_info->wrap_lookup[state - WINED3D_TADDRESS_WRAP]);
1117  gl_tex->sampler_desc.address_v = state;
1118  }
1119 
1120  state = sampler_desc->address_w;
1121  if (state != gl_tex->sampler_desc.address_w)
1122  {
1123  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_WRAP_R,
1124  gl_info->wrap_lookup[state - WINED3D_TADDRESS_WRAP]);
1125  gl_tex->sampler_desc.address_w = state;
1126  }
1127 
1128  if (memcmp(gl_tex->sampler_desc.border_color, sampler_desc->border_color,
1129  sizeof(gl_tex->sampler_desc.border_color)))
1130  {
1131  gl_info->gl_ops.gl.p_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, &sampler_desc->border_color[0]);
1132  memcpy(gl_tex->sampler_desc.border_color, sampler_desc->border_color,
1133  sizeof(gl_tex->sampler_desc.border_color));
1134  }
1135 
1136  state = sampler_desc->mag_filter;
1137  if (state != gl_tex->sampler_desc.mag_filter)
1138  {
1139  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, wined3d_gl_mag_filter(state));
1140  gl_tex->sampler_desc.mag_filter = state;
1141  }
1142 
1143  if (sampler_desc->min_filter != gl_tex->sampler_desc.min_filter
1144  || sampler_desc->mip_filter != gl_tex->sampler_desc.mip_filter)
1145  {
1146  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
1147  wined3d_gl_min_mip_filter(sampler_desc->min_filter, sampler_desc->mip_filter));
1148  gl_tex->sampler_desc.min_filter = sampler_desc->min_filter;
1149  gl_tex->sampler_desc.mip_filter = sampler_desc->mip_filter;
1150  }
1151 
1152  state = sampler_desc->max_anisotropy;
1153  if (state != gl_tex->sampler_desc.max_anisotropy)
1154  {
1156  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_MAX_ANISOTROPY, state);
1157  else
1158  WARN("Anisotropic filtering not supported.\n");
1159  gl_tex->sampler_desc.max_anisotropy = state;
1160  }
1161 
1162  if (!sampler_desc->srgb_decode != !gl_tex->sampler_desc.srgb_decode
1163  && (context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)
1164  && gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
1165  {
1166  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
1167  sampler_desc->srgb_decode ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT);
1168  gl_tex->sampler_desc.srgb_decode = sampler_desc->srgb_decode;
1169  }
1170 
1171  if (!sampler_desc->compare != !gl_tex->sampler_desc.compare)
1172  {
1173  if (sampler_desc->compare)
1174  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
1175  else
1176  gl_info->gl_ops.gl.p_glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
1177  gl_tex->sampler_desc.compare = sampler_desc->compare;
1178  }
1179 
1180  checkGLcall("Texture parameter application");
1181 
1182  if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
1183  {
1184  gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
1185  GL_TEXTURE_LOD_BIAS_EXT, sampler_desc->lod_bias);
1186  checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
1187  }
1188 }
1189 
1191 {
1192  ULONG refcount;
1193 
1194  TRACE("texture %p, swapchain %p.\n", texture, texture->swapchain);
1195 
1196  if (texture->swapchain)
1197  return wined3d_swapchain_incref(texture->swapchain);
1198 
1199  refcount = InterlockedIncrement(&texture->resource.ref);
1200  TRACE("%p increasing refcount to %u.\n", texture, refcount);
1201 
1202  return refcount;
1203 }
1204 
1206 {
1208  resource_cleanup(&texture->resource);
1210  wined3d_texture_cleanup(texture);
1211 }
1212 
1213 static void wined3d_texture_destroy_object(void *object)
1214 {
1215  wined3d_texture_cleanup(object);
1216  heap_free(object);
1217 }
1218 
1220 {
1221  ULONG refcount;
1222 
1223  TRACE("texture %p, swapchain %p.\n", texture, texture->swapchain);
1224 
1225  if (texture->swapchain)
1226  return wined3d_swapchain_decref(texture->swapchain);
1227 
1228  refcount = InterlockedDecrement(&texture->resource.ref);
1229  TRACE("%p decreasing refcount to %u.\n", texture, refcount);
1230 
1231  if (!refcount)
1232  {
1233  /* Wait for the texture to become idle if it's using user memory,
1234  * since the application is allowed to free that memory once the
1235  * texture is destroyed. Note that this implies that
1236  * wined3d_texture_destroy_object() can't access that memory either. */
1237  if (texture->user_memory)
1240  texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
1241  resource_cleanup(&texture->resource);
1242  wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture);
1243  }
1244 
1245  return refcount;
1246 }
1247 
1249 {
1250  TRACE("texture %p.\n", texture);
1251 
1252  return &texture->resource;
1253 }
1254 
1255 static BOOL color_key_equal(const struct wined3d_color_key *c1, struct wined3d_color_key *c2)
1256 {
1259 }
1260 
1261 /* Context activation is done by the caller */
1263  struct wined3d_context *context, BOOL srgb)
1264 {
1265  UINT sub_count = texture->level_count * texture->layer_count;
1266  const struct wined3d_d3d_info *d3d_info = context->d3d_info;
1267  DWORD flag;
1268  UINT i;
1269 
1270  TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
1271 
1272  if (!needs_separate_srgb_gl_texture(context, texture))
1273  srgb = FALSE;
1274 
1275  if (srgb)
1277  else
1279 
1280  if (!d3d_info->shader_color_key
1281  && (!(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
1282  != !(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
1283  || (texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY
1284  && !color_key_equal(&texture->async.gl_color_key, &texture->async.src_blt_color_key))))
1285  {
1286  unsigned int sub_count = texture->level_count * texture->layer_count;
1287  unsigned int i;
1288 
1289  TRACE("Reloading because of color key value change.\n");
1290  for (i = 0; i < sub_count; i++)
1291  {
1292  if (!wined3d_texture_load_location(texture, i, context, texture->resource.map_binding))
1293  ERR("Failed to load location %s.\n", wined3d_debug_location(texture->resource.map_binding));
1294  else
1295  wined3d_texture_invalidate_location(texture, i, ~texture->resource.map_binding);
1296  }
1297 
1298  texture->async.gl_color_key = texture->async.src_blt_color_key;
1299  }
1300 
1301  if (texture->flags & flag)
1302  {
1303  TRACE("Texture %p not dirty, nothing to do.\n", texture);
1304  return;
1305  }
1306 
1307  /* Reload the surfaces if the texture is marked dirty. */
1308  for (i = 0; i < sub_count; ++i)
1309  {
1310  if (!wined3d_texture_load_location(texture, i, context,
1312  ERR("Failed to load location (srgb %#x).\n", srgb);
1313  }
1314  texture->flags |= flag;
1315 }
1316 
1318 {
1319  TRACE("texture %p.\n", texture);
1320 
1321  return texture->resource.parent;
1322 }
1323 
1325  unsigned int level, const struct wined3d_box *box)
1326 {
1327  const struct wined3d_format *format = texture->resource.format;
1328  unsigned int width_mask, height_mask, width, height, depth;
1329 
1330  width = wined3d_texture_get_level_width(texture, level);
1331  height = wined3d_texture_get_level_height(texture, level);
1332  depth = wined3d_texture_get_level_depth(texture, level);
1333 
1334  if (box->left >= box->right || box->right > width
1335  || box->top >= box->bottom || box->bottom > height
1336  || box->front >= box->back || box->back > depth)
1337  {
1338  WARN("Box %s is invalid.\n", debug_box(box));
1339  return WINEDDERR_INVALIDRECT;
1340  }
1341 
1342  if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
1343  {
1344  /* This assumes power of two block sizes, but NPOT block sizes would
1345  * be silly anyway.
1346  *
1347  * This also assumes that the format's block depth is 1. */
1348  width_mask = format->block_width - 1;
1349  height_mask = format->block_height - 1;
1350 
1351  if ((box->left & width_mask) || (box->top & height_mask)
1352  || (box->right & width_mask && box->right != width)
1353  || (box->bottom & height_mask && box->bottom != height))
1354  {
1355  WARN("Box %s is misaligned for %ux%u blocks.\n",
1356  debug_box(box), format->block_width, format->block_height);
1357  return WINED3DERR_INVALIDCALL;
1358  }
1359  }
1360 
1361  return WINED3D_OK;
1362 }
1363 
1365  unsigned int level, unsigned int *row_pitch, unsigned int *slice_pitch)
1366 {
1367  const struct wined3d_resource *resource = &texture->resource;
1368  unsigned int width = wined3d_texture_get_level_width(texture, level);
1369  unsigned int height = wined3d_texture_get_level_height(texture, level);
1370 
1371  if (texture->row_pitch)
1372  {
1373  *row_pitch = texture->row_pitch;
1374  *slice_pitch = texture->slice_pitch;
1375  return;
1376  }
1377 
1378  wined3d_format_calculate_pitch(resource->format, resource->device->surface_alignment,
1379  width, height, row_pitch, slice_pitch);
1380 }
1381 
1383 {
1384  DWORD old = texture->lod;
1385 
1386  TRACE("texture %p, lod %u.\n", texture, lod);
1387 
1388  /* The d3d9:texture test shows that SetLOD is ignored on non-managed
1389  * textures. The call always returns 0, and GetLOD always returns 0. */
1390  if (!wined3d_resource_access_is_managed(texture->resource.access))
1391  {
1392  TRACE("Ignoring LOD on texture with resource access %s.\n",
1393  wined3d_debug_resource_access(texture->resource.access));
1394  return 0;
1395  }
1396 
1397  if (lod >= texture->level_count)
1398  lod = texture->level_count - 1;
1399 
1400  if (texture->lod != lod)
1401  {
1402  struct wined3d_device *device = texture->resource.device;
1403 
1405  texture->lod = lod;
1406 
1407  texture->texture_rgb.base_level = ~0u;
1408  texture->texture_srgb.base_level = ~0u;
1409  if (texture->resource.bind_count)
1411  device->state.sampler_states[texture->sampler][WINED3D_SAMP_MAX_MIP_LEVEL]);
1412  }
1413 
1414  return old;
1415 }
1416 
1418 {
1419  TRACE("texture %p, returning %u.\n", texture, texture->lod);
1420 
1421  return texture->lod;
1422 }
1423 
1425 {
1426  TRACE("texture %p, returning %u.\n", texture, texture->level_count);
1427 
1428  return texture->level_count;
1429 }
1430 
1432  DWORD flags, const struct wined3d_color_key *color_key)
1433 {
1434  struct wined3d_device *device = texture->resource.device;
1435  static const DWORD all_flags = WINED3D_CKEY_DST_BLT | WINED3D_CKEY_DST_OVERLAY
1437 
1438  TRACE("texture %p, flags %#x, color_key %p.\n", texture, flags, color_key);
1439 
1440  if (flags & ~all_flags)
1441  {
1442  WARN("Invalid flags passed, returning WINED3DERR_INVALIDCALL.\n");
1443  return WINED3DERR_INVALIDCALL;
1444  }
1445 
1446  wined3d_cs_emit_set_color_key(device->cs, texture, flags, color_key);
1447 
1448  return WINED3D_OK;
1449 }
1450 
1451 /* In D3D the depth stencil dimensions have to be greater than or equal to the
1452  * render target dimensions. With FBOs, the dimensions have to be an exact match. */
1453 /* TODO: We should synchronize the renderbuffer's content with the texture's content. */
1454 /* Context activation is done by the caller. */
1456  unsigned int level, const struct wined3d_rendertarget_info *rt)
1457 {
1459  const struct wined3d_gl_info *gl_info;
1460  unsigned int src_width, src_height;
1461  unsigned int width, height;
1462  GLuint renderbuffer = 0;
1463 
1464  gl_info = &texture->resource.device->adapter->gl_info;
1465  if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
1466  return;
1467 
1468  if (rt && rt->resource->format->id != WINED3DFMT_NULL)
1469  {
1470  struct wined3d_texture *rt_texture;
1471  unsigned int rt_level;
1472 
1473  if (rt->resource->type == WINED3D_RTYPE_BUFFER)
1474  {
1475  FIXME("Unsupported resource type %s.\n", debug_d3dresourcetype(rt->resource->type));
1476  return;
1477  }
1478  rt_texture = wined3d_texture_from_resource(rt->resource);
1479  rt_level = rt->sub_resource_idx % rt_texture->level_count;
1480 
1481  width = wined3d_texture_get_level_pow2_width(rt_texture, rt_level);
1482  height = wined3d_texture_get_level_pow2_height(rt_texture, rt_level);
1483  }
1484  else
1485  {
1486  width = wined3d_texture_get_level_pow2_width(texture, level);
1487  height = wined3d_texture_get_level_pow2_height(texture, level);
1488  }
1489 
1490  src_width = wined3d_texture_get_level_pow2_width(texture, level);
1491  src_height = wined3d_texture_get_level_pow2_height(texture, level);
1492 
1493  /* A depth stencil smaller than the render target is not valid */
1494  if (width > src_width || height > src_height)
1495  return;
1496 
1497  /* Remove any renderbuffer set if the sizes match */
1498  if (width == src_width && height == src_height)
1499  {
1500  texture->current_renderbuffer = NULL;
1501  return;
1502  }
1503 
1504  /* Look if we've already got a renderbuffer of the correct dimensions */
1505  LIST_FOR_EACH_ENTRY(entry, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry)
1506  {
1507  if (entry->width == width && entry->height == height)
1508  {
1509  renderbuffer = entry->id;
1510  texture->current_renderbuffer = entry;
1511  break;
1512  }
1513  }
1514 
1515  if (!renderbuffer)
1516  {
1517  gl_info->fbo_ops.glGenRenderbuffers(1, &renderbuffer);
1518  gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
1519  gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER,
1520  texture->resource.format->glInternal, width, height);
1521 
1522  entry = heap_alloc(sizeof(*entry));
1523  entry->width = width;
1524  entry->height = height;
1525  entry->id = renderbuffer;
1526  list_add_head(&texture->renderbuffers, &entry->entry);
1527 
1528  texture->current_renderbuffer = entry;
1529  }
1530 
1531  checkGLcall("set_compatible_renderbuffer");
1532 }
1533 
1535  enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type,
1536  UINT multisample_quality, void *mem, UINT pitch)
1537 {
1538  struct wined3d_device *device = texture->resource.device;
1539  const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
1540  const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, texture->resource.usage);
1541  UINT resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
1542  struct wined3d_texture_sub_resource *sub_resource;
1543  DWORD valid_location = 0;
1544  BOOL create_dib = FALSE;
1545 
1546  TRACE("texture %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, "
1547  "mem %p, pitch %u.\n",
1548  texture, width, height, debug_d3dformat(format_id), multisample_type, multisample_quality, mem, pitch);
1549 
1550  if (!resource_size)
1551  return WINED3DERR_INVALIDCALL;
1552 
1553  if (texture->level_count * texture->layer_count > 1)
1554  {
1555  WARN("Texture has multiple sub-resources, not supported.\n");
1556  return WINED3DERR_INVALIDCALL;
1557  }
1558 
1559  if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
1560  {
1561  WARN("Not supported on %s.\n", debug_d3dresourcetype(texture->resource.type));
1562  return WINED3DERR_INVALIDCALL;
1563  }
1564 
1565  if (texture->resource.map_count)
1566  {
1567  WARN("Texture is mapped.\n");
1568  return WINED3DERR_INVALIDCALL;
1569  }
1570 
1571  /* We have no way of supporting a pitch that is not a multiple of the pixel
1572  * byte width short of uploading the texture row-by-row.
1573  * Fortunately that's not an issue since D3D9Ex doesn't allow a custom pitch
1574  * for user-memory textures (it always expects packed data) while DirectDraw
1575  * requires a 4-byte aligned pitch and doesn't support texture formats
1576  * larger than 4 bytes per pixel nor any format using 3 bytes per pixel.
1577  * This check is here to verify that the assumption holds. */
1578  if (pitch % texture->resource.format->byte_count)
1579  {
1580  WARN("Pitch unsupported, not a multiple of the texture format byte width.\n");
1581  return WINED3DERR_INVALIDCALL;
1582  }
1583 
1584  if (device->d3d_initialized)
1585  wined3d_cs_emit_unload_resource(device->cs, &texture->resource);
1587 
1588  sub_resource = &texture->sub_resources[0];
1589  if (texture->dc_info && texture->dc_info[0].dc)
1590  {
1591  struct wined3d_texture_idx texture_idx = {texture, 0};
1592 
1594  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
1595  create_dib = TRUE;
1596  }
1597 
1599 
1600  if ((texture->row_pitch = pitch))
1601  texture->slice_pitch = height * pitch;
1602  else
1603  /* User memory surfaces don't have the regular surface alignment. */
1604  wined3d_format_calculate_pitch(format, 1, width, height,
1605  &texture->row_pitch, &texture->slice_pitch);
1606 
1607  texture->resource.format = format;
1608  texture->resource.multisample_type = multisample_type;
1609  texture->resource.multisample_quality = multisample_quality;
1610  texture->resource.width = width;
1611  texture->resource.height = height;
1612  texture->resource.size = texture->slice_pitch;
1613  sub_resource->size = texture->slice_pitch;
1614  sub_resource->locations = WINED3D_LOCATION_DISCARDED;
1615 
1616  if (multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
1617  texture->target = GL_TEXTURE_2D_MULTISAMPLE;
1618  else
1619  texture->target = GL_TEXTURE_2D;
1620 
1621  if (((width & (width - 1)) || (height & (height - 1))) && !gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO]
1623  {
1625  texture->pow2_width = texture->pow2_height = 1;
1626  while (texture->pow2_width < width)
1627  texture->pow2_width <<= 1;
1628  while (texture->pow2_height < height)
1629  texture->pow2_height <<= 1;
1630  }
1631  else
1632  {
1634  texture->pow2_width = width;
1635  texture->pow2_height = height;
1636  }
1637 
1638  if ((texture->user_memory = mem))
1639  {
1640  texture->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
1641  valid_location = WINED3D_LOCATION_USER_MEMORY;
1642  }
1643  else
1644  {
1646  valid_location = WINED3D_LOCATION_SYSMEM;
1647  }
1648 
1649  /* The format might be changed to a format that needs conversion.
1650  * If the surface didn't use PBOs previously but could now, don't
1651  * change it - whatever made us not use PBOs might come back, e.g.
1652  * color keys. */
1653  if (texture->resource.map_binding == WINED3D_LOCATION_BUFFER && !wined3d_texture_use_pbo(texture, gl_info))
1654  texture->resource.map_binding = WINED3D_LOCATION_SYSMEM;
1655 
1656  wined3d_texture_validate_location(texture, 0, valid_location);
1657  wined3d_texture_invalidate_location(texture, 0, ~valid_location);
1658 
1659  if (create_dib)
1660  {
1661  struct wined3d_texture_idx texture_idx = {texture, 0};
1662 
1663  wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx);
1664  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
1665  }
1666 
1667  return WINED3D_OK;
1668 }
1669 
1670 /* Context activation is done by the caller. */
1672  unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
1673 {
1674  struct wined3d_texture_sub_resource *sub_resource;
1675 
1676  sub_resource = &texture->sub_resources[sub_resource_idx];
1677  if (sub_resource->buffer_object)
1678  return;
1679 
1680  GL_EXTCALL(glGenBuffers(1, &sub_resource->buffer_object));
1681  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sub_resource->buffer_object));
1682  GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sub_resource->size, NULL, GL_STREAM_DRAW));
1683  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
1684  checkGLcall("Create buffer object");
1685 
1686  TRACE("Created buffer object %u for texture %p, sub-resource %u.\n",
1687  sub_resource->buffer_object, texture, sub_resource_idx);
1688 }
1689 
1691 {
1692  unsigned int sub_count = texture->level_count * texture->layer_count;
1693  unsigned int i;
1694 
1697  texture->async.flags &= ~WINED3D_TEXTURE_ASYNC_COLOR_KEY;
1698  for (i = 0; i < sub_count; ++i)
1699  {
1702  }
1703 }
1704 
1705 /* Context activation is done by the caller. */
1707 {
1709  const struct wined3d_format *format = texture->resource.format;
1710  const struct wined3d_d3d_info *d3d_info = context->d3d_info;
1711  const struct wined3d_gl_info *gl_info = context->gl_info;
1712  const struct wined3d_color_key_conversion *conversion;
1713  GLenum internal;
1714 
1715  TRACE("texture %p, context %p, format %s.\n", texture, context, debug_d3dformat(format->id));
1716 
1717  if (!d3d_info->shader_color_key
1718  && !(texture->async.flags & WINED3D_TEXTURE_ASYNC_COLOR_KEY)
1719  != !(texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT))
1720  {
1722 
1723  if (texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
1724  texture->async.flags |= WINED3D_TEXTURE_ASYNC_COLOR_KEY;
1725  }
1726 
1727  if (texture->flags & alloc_flag)
1728  return;
1729 
1730  if (format->conv_byte_count)
1731  {
1732  texture->flags |= WINED3D_TEXTURE_CONVERTED;
1733  }
1734  else if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
1735  {
1736  texture->flags |= WINED3D_TEXTURE_CONVERTED;
1737  format = wined3d_get_format(gl_info, conversion->dst_format, texture->resource.usage);
1738  TRACE("Using format %s for color key conversion.\n", debug_d3dformat(format->id));
1739  }
1740 
1741  wined3d_texture_bind_and_dirtify(texture, context, srgb);
1742 
1743  if (srgb)
1744  internal = format->glGammaInternal;
1745  else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
1747  internal = format->rtInternal;
1748  else
1749  internal = format->glInternal;
1750 
1751  if (!internal)
1752  FIXME("No GL internal format for format %s.\n", debug_d3dformat(format->id));
1753 
1754  TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType);
1755 
1756  if (wined3d_texture_use_immutable_storage(texture, gl_info))
1757  wined3d_texture_allocate_gl_immutable_storage(texture, internal, gl_info);
1758  else
1759  wined3d_texture_allocate_gl_mutable_storage(texture, internal, format, gl_info);
1760  texture->flags |= alloc_flag;
1761 }
1762 
1764  const struct wined3d_gl_info *gl_info, BOOL multisample)
1765 {
1766  const struct wined3d_format *format = texture->resource.format;
1767 
1768  if (multisample)
1769  {
1770  DWORD samples;
1771 
1772  if (texture->rb_multisample)
1773  return;
1774 
1775  samples = wined3d_texture_get_gl_sample_count(texture);
1776 
1777  gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_multisample);
1778  gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_multisample);
1779  gl_info->fbo_ops.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
1780  format->glInternal, texture->resource.width, texture->resource.height);
1781  checkGLcall("glRenderbufferStorageMultisample()");
1782  TRACE("Created multisample rb %u.\n", texture->rb_multisample);
1783  }
1784  else
1785  {
1786  if (texture->rb_resolved)
1787  return;
1788 
1789  gl_info->fbo_ops.glGenRenderbuffers(1, &texture->rb_resolved);
1790  gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, texture->rb_resolved);
1791  gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, format->glInternal,
1792  texture->resource.width, texture->resource.height);
1793  checkGLcall("glRenderbufferStorage()");
1794  TRACE("Created resolved rb %u.\n", texture->rb_resolved);
1795  }
1796 }
1797 
1798 /* Context activation is done by the caller. Context may be NULL in
1799  * WINED3D_NO3D mode. */
1802 {
1803  switch (location)
1804  {
1806  if (texture->resource.heap_memory)
1807  return TRUE;
1808 
1810  return FALSE;
1811  return TRUE;
1812 
1814  if (!texture->user_memory)
1815  ERR("Map binding is set to WINED3D_LOCATION_USER_MEMORY but surface->user_memory is NULL.\n");
1816  return TRUE;
1817 
1819  wined3d_texture_prepare_buffer_object(texture, sub_resource_idx, context->gl_info);
1820  return TRUE;
1821 
1823  wined3d_texture_prepare_texture(texture, context, FALSE);
1824  return TRUE;
1825 
1827  wined3d_texture_prepare_texture(texture, context, TRUE);
1828  return TRUE;
1829 
1832  ERR("Texture %p does not have a drawable.\n", texture);
1833  return TRUE;
1834 
1836  wined3d_texture_prepare_rb(texture, context->gl_info, TRUE);
1837  return TRUE;
1838 
1840  wined3d_texture_prepare_rb(texture, context->gl_info, FALSE);
1841  return TRUE;
1842 
1843  default:
1844  ERR("Invalid location %s.\n", wined3d_debug_location(location));
1845  return FALSE;
1846  }
1847 }
1848 
1849 static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(struct wined3d_texture *texture,
1850  unsigned int sub_resource_idx)
1851 {
1852  UINT sub_count = texture->level_count * texture->layer_count;
1853 
1854  TRACE("texture %p, sub_resource_idx %u.\n", texture, sub_resource_idx);
1855 
1856  if (sub_resource_idx >= sub_count)
1857  {
1858  WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count);
1859  return NULL;
1860  }
1861 
1862  return &texture->sub_resources[sub_resource_idx];
1863 }
1864 
1866  UINT layer, const struct wined3d_box *dirty_region)
1867 {
1868  TRACE("texture %p, layer %u, dirty_region %s.\n", texture, layer, debug_box(dirty_region));
1869 
1870  if (layer >= texture->layer_count)
1871  {
1872  WARN("Invalid layer %u specified.\n", layer);
1873  return WINED3DERR_INVALIDCALL;
1874  }
1875 
1876  if (dirty_region)
1877  WARN("Ignoring dirty_region %s.\n", debug_box(dirty_region));
1878 
1879  wined3d_cs_emit_add_dirty_texture_region(texture->resource.device->cs, texture, layer);
1880 
1881  return WINED3D_OK;
1882 }
1883 
1884 /* This call just uploads data, the caller is responsible for binding the
1885  * correct texture. */
1886 /* Context activation is done by the caller. */
1888  struct wined3d_context *context, const struct wined3d_format *format, const struct wined3d_box *src_box,
1889  const struct wined3d_const_bo_address *data, unsigned int src_row_pitch, unsigned int src_slice_pitch,
1890  unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, BOOL srgb)
1891 {
1892  const struct wined3d_gl_info *gl_info = context->gl_info;
1893  unsigned int update_w = src_box->right - src_box->left;
1894  unsigned int update_h = src_box->bottom - src_box->top;
1895  unsigned int update_d = src_box->back - src_box->front;
1896  struct wined3d_bo_address bo;
1897  void *converted_mem = NULL;
1898  struct wined3d_format f;
1899  unsigned int level;
1900  GLenum target;
1901 
1902  TRACE("texture %p, sub_resource_idx %u, context %p, format %s, src_box %s, data {%#x:%p}, "
1903  "src_row_pitch %#x, src_slice_pitch %#x, dst_x %u, dst_y %u, dst_z %u, srgb %#x.\n",
1904  texture, sub_resource_idx, context, debug_d3dformat(format->id), debug_box(src_box),
1905  data->buffer_object, data->addr, src_row_pitch, src_slice_pitch, dst_x, dst_y, dst_z, srgb);
1906 
1907  if (texture->sub_resources[sub_resource_idx].map_count)
1908  {
1909  WARN("Uploading a texture that is currently mapped, setting WINED3D_TEXTURE_PIN_SYSMEM.\n");
1910  texture->flags |= WINED3D_TEXTURE_PIN_SYSMEM;
1911  }
1912 
1914  {
1915  update_h *= format->height_scale.numerator;
1916  update_h /= format->height_scale.denominator;
1917  }
1918 
1919  target = wined3d_texture_get_sub_resource_target(texture, sub_resource_idx);
1920  level = sub_resource_idx % texture->level_count;
1921 
1922  switch (target)
1923  {
1924  case GL_TEXTURE_1D_ARRAY:
1925  dst_y = sub_resource_idx / texture->level_count;
1926  update_h = 1;
1927  break;
1928  case GL_TEXTURE_2D_ARRAY:
1929  dst_z = sub_resource_idx / texture->level_count;
1930  update_d = 1;
1931  break;
1934  FIXME("Not supported for multisample textures.\n");
1935  return;
1936  }
1937 
1938  bo.buffer_object = data->buffer_object;
1939  bo.addr = (BYTE *)data->addr + src_box->front * src_slice_pitch;
1940  if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
1941  {
1942  bo.addr += (src_box->top / format->block_height) * src_row_pitch;
1943  bo.addr += (src_box->left / format->block_width) * format->block_byte_count;
1944  }
1945  else
1946  {
1947  bo.addr += src_box->top * src_row_pitch;
1948  bo.addr += src_box->left * format->byte_count;
1949  }
1950 
1951  if (format->upload)
1952  {
1953  unsigned int dst_row_pitch, dst_slice_pitch;
1954  void *src_mem;
1955 
1956  if (texture->resource.format_flags & WINED3DFMT_FLAG_BLOCKS)
1957  ERR("Converting a block-based format.\n");
1958 
1959  f = *format;
1960  f.byte_count = format->conv_byte_count;
1961  format = &f;
1962 
1963  wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch);
1964 
1965  if (!(converted_mem = heap_calloc(update_d, dst_slice_pitch)))
1966  {
1967  ERR("Failed to allocate upload buffer.\n");
1968  return;
1969  }
1970 
1971  src_mem = context_map_bo_address(context, &bo, src_slice_pitch,
1973  format->upload(src_mem, converted_mem, src_row_pitch, src_slice_pitch,
1974  dst_row_pitch, dst_slice_pitch, update_w, update_h, update_d);
1976 
1977  bo.buffer_object = 0;
1978  bo.addr = converted_mem;
1979  src_row_pitch = dst_row_pitch;
1980  src_slice_pitch = dst_slice_pitch;
1981  }
1982 
1983  if (bo.buffer_object)
1984  {
1985  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bo.buffer_object));
1986  checkGLcall("glBindBuffer");
1987  }
1988 
1990  {
1991  unsigned int dst_row_pitch, dst_slice_pitch;
1992  const BYTE *addr = bo.addr;
1993  GLenum internal;
1994 
1995  if (srgb)
1996  internal = format->glGammaInternal;
1997  else if (texture->resource.usage & WINED3DUSAGE_RENDERTARGET
1999  internal = format->rtInternal;
2000  else
2001  internal = format->glInternal;
2002 
2003  wined3d_format_calculate_pitch(format, 1, update_w, update_h, &dst_row_pitch, &dst_slice_pitch);
2004 
2005  TRACE("Uploading compressed data, target %#x, level %u, x %u, y %u, z %u, "
2006  "w %u, h %u, d %u, format %#x, image_size %#x, addr %p.\n",
2007  target, level, dst_x, dst_y, dst_z, update_w, update_h,
2008  update_d, internal, dst_slice_pitch, addr);
2009 
2010  if (target == GL_TEXTURE_1D)
2011  {
2012  GL_EXTCALL(glCompressedTexSubImage1D(target, level, dst_x,
2013  update_w, internal, dst_row_pitch, addr));
2014  }
2015  else if (dst_row_pitch == src_row_pitch)
2016  {
2017  if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
2018  {
2019  GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_x, dst_y, dst_z,
2020  update_w, update_h, update_d, internal, dst_slice_pitch * update_d, addr));
2021  }
2022  else
2023  {
2024  GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_x, dst_y,
2025  update_w, update_h, internal, dst_slice_pitch, addr));
2026  }
2027  }
2028  else
2029  {
2030  unsigned int row_count = (update_h + format->block_height - 1) / format->block_height;
2031  unsigned int row, y, z;
2032 
2033  /* glCompressedTexSubImage2D() ignores pixel store state, so we
2034  * can't use the unpack row length like for glTexSubImage2D. */
2035  for (z = dst_z; z < dst_z + update_d; ++z)
2036  {
2037  for (row = 0, y = dst_y; row < row_count; ++row)
2038  {
2039  if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
2040  {
2041  GL_EXTCALL(glCompressedTexSubImage3D(target, level, dst_x, y, z,
2042  update_w, format->block_height, 1, internal, dst_row_pitch, addr));
2043  }
2044  else
2045  {
2046  GL_EXTCALL(glCompressedTexSubImage2D(target, level, dst_x, y,
2047  update_w, format->block_height, internal, dst_row_pitch, addr));
2048  }
2049 
2050  y += format->block_height;
2051  addr += src_row_pitch;
2052  }
2053  }
2054  }
2055  checkGLcall("Upload compressed texture data");
2056  }
2057  else
2058  {
2059  TRACE("Uploading data, target %#x, level %u, x %u, y %u, z %u, "
2060  "w %u, h %u, d %u, format %#x, type %#x, addr %p.\n",
2061  target, level, dst_x, dst_y, dst_z, update_w, update_h,
2062  update_d, format->glFormat, format->glType, bo.addr);
2063 
2064  gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_row_pitch / format->byte_count);
2065  if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_3D)
2066  {
2067  GL_EXTCALL(glTexSubImage3D(target, level, dst_x, dst_y, dst_z,
2068  update_w, update_h, update_d, format->glFormat, format->glType, bo.addr));
2069  }
2070  else if (target == GL_TEXTURE_1D)
2071  {
2072  gl_info->gl_ops.gl.p_glTexSubImage1D(target, level, dst_x,
2073  update_w, format->glFormat, format->glType, bo.addr);
2074  }
2075  else
2076  {
2077  gl_info->gl_ops.gl.p_glTexSubImage2D(target, level, dst_x, dst_y,
2078  update_w, update_h, format->glFormat, format->glType, bo.addr);
2079  }
2080  gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
2081  checkGLcall("Upload texture data");
2082  }
2083 
2084  if (bo.buffer_object)
2085  {
2086  GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
2087  checkGLcall("glBindBuffer");
2088  }
2089  heap_free(converted_mem);
2090 
2091  if (gl_info->quirks & WINED3D_QUIRK_FBO_TEX_UPDATE)
2092  {
2093  struct wined3d_device *device = texture->resource.device;
2094  unsigned int i;
2095 
2096  for (i = 0; i < device->context_count; ++i)
2097  {
2098  context_texture_update(device->contexts[i], texture);
2099  }
2100  }
2101 }
2102 
2103 /* Context activation is done by the caller. Context may be NULL in ddraw-only mode. */
2106 {
2107  TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
2108  texture, sub_resource_idx, context, wined3d_debug_location(location));
2109 
2110  switch (location)
2111  {
2115  return texture2d_load_sysmem(texture, sub_resource_idx, context, location);
2116 
2118  return texture2d_load_drawable(texture, sub_resource_idx, context);
2119 
2122  return texture2d_load_renderbuffer(texture, sub_resource_idx, context, location);
2123 
2126  return texture2d_load_texture(texture, sub_resource_idx, context,
2127  location == WINED3D_LOCATION_TEXTURE_SRGB);
2128 
2129  default:
2130  ERR("Don't know how to handle location %#x.\n", location);
2131  return FALSE;
2132  }
2133 }
2134 
2135 static const struct wined3d_texture_ops texture2d_ops =
2136 {
2138 };
2139 
2141 {
2142  return texture_from_resource(resource);
2143 }
2144 
2146 {
2148 }
2149 
2151 {
2153 }
2154 
2156 {
2157  struct wined3d_texture *texture = texture_from_resource(resource);
2158  struct wined3d_context *context;
2159 
2160  context = context_acquire(resource->device, NULL, 0);
2161  wined3d_texture_load(texture, context, texture->flags & WINED3D_TEXTURE_IS_SRGB);
2162  context_release(context);
2163 }
2164 
2166 {
2167  struct wined3d_texture *texture = texture_from_resource(resource);
2168  UINT sub_count = texture->level_count * texture->layer_count;
2169  struct wined3d_renderbuffer_entry *entry, *entry2;
2170  struct wined3d_device *device = resource->device;
2171  const struct wined3d_gl_info *gl_info;
2172  struct wined3d_context *context;
2173  UINT i;
2174 
2175  TRACE("texture %p.\n", texture);
2176 
2177  context = context_acquire(device, NULL, 0);
2178  gl_info = context->gl_info;
2179 
2180  for (i = 0; i < sub_count; ++i)
2181  {
2182  struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[i];
2183 
2184  if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
2185  && wined3d_texture_load_location(texture, i, context, resource->map_binding))
2186  {
2187  wined3d_texture_invalidate_location(texture, i, ~resource->map_binding);
2188  }
2189  else
2190  {
2191  /* We should only get here on device reset/teardown for implicit
2192  * resources. */
2193  if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
2194  || resource->type != WINED3D_RTYPE_TEXTURE_2D)
2195  ERR("Discarding %s %p sub-resource %u with resource access %s.\n",
2196  debug_d3dresourcetype(resource->type), resource, i,
2200  }
2201 
2202  if (sub_resource->buffer_object)
2203  wined3d_texture_remove_buffer_object(texture, i, context->gl_info);
2204  }
2205 
2206  LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture->renderbuffers, struct wined3d_renderbuffer_entry, entry)
2207  {
2208  context_gl_resource_released(device, entry->id, TRUE);
2209  gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
2210  list_remove(&entry->entry);
2211  heap_free(entry);
2212  }
2213  list_init(&texture->renderbuffers);
2214  texture->current_renderbuffer = NULL;
2215 
2216  context_release(context);
2217 
2220 }
2221 
2223  struct wined3d_map_desc *map_desc, const struct wined3d_box *box, DWORD flags)
2224 {
2225  const struct wined3d_format *format = resource->format;
2226  struct wined3d_texture_sub_resource *sub_resource;
2227  struct wined3d_device *device = resource->device;
2228  unsigned int fmt_flags = resource->format_flags;
2229  struct wined3d_context *context = NULL;
2230  struct wined3d_texture *texture;
2231  struct wined3d_bo_address data;
2232  unsigned int texture_level;
2233  BYTE *base_memory;
2234  BOOL ret;
2235 
2236  TRACE("resource %p, sub_resource_idx %u, map_desc %p, box %s, flags %#x.\n",
2237  resource, sub_resource_idx, map_desc, debug_box(box), flags);
2238 
2239  texture = texture_from_resource(resource);
2240  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
2241  return E_INVALIDARG;
2242 
2243  texture_level = sub_resource_idx % texture->level_count;
2244  if (box && FAILED(wined3d_texture_check_box_dimensions(texture, texture_level, box)))
2245  {
2246  WARN("Map box is invalid.\n");
2247  if (((fmt_flags & WINED3DFMT_FLAG_BLOCKS) && !(resource->access & WINED3D_RESOURCE_ACCESS_CPU))
2248  || resource->type != WINED3D_RTYPE_TEXTURE_2D)
2249  return WINED3DERR_INVALIDCALL;
2250  }
2251 
2252  if (texture->flags & WINED3D_TEXTURE_DC_IN_USE)
2253  {
2254  WARN("DC is in use.\n");
2255  return WINED3DERR_INVALIDCALL;
2256  }
2257 
2258  if (sub_resource->map_count)
2259  {
2260  WARN("Sub-resource is already mapped.\n");
2261  return WINED3DERR_INVALIDCALL;
2262  }
2263 
2264  if (device->d3d_initialized)
2265  context = context_acquire(device, NULL, 0);
2266 
2267  if (flags & WINED3D_MAP_DISCARD)
2268  {
2269  TRACE("WINED3D_MAP_DISCARD flag passed, marking %s as up to date.\n",
2270  wined3d_debug_location(resource->map_binding));
2271  if ((ret = wined3d_texture_prepare_location(texture, sub_resource_idx, context, resource->map_binding)))
2272  wined3d_texture_validate_location(texture, sub_resource_idx, resource->map_binding);
2273  }
2274  else
2275  {
2276  if (resource->usage & WINED3DUSAGE_DYNAMIC)
2277  WARN_(d3d_perf)("Mapping a dynamic texture without WINED3D_MAP_DISCARD.\n");
2278  ret = wined3d_texture_load_location(texture, sub_resource_idx, context, resource->map_binding);
2279  }
2280 
2281  if (!ret)
2282  {
2283  ERR("Failed to prepare location.\n");
2284  context_release(context);
2285  return E_OUTOFMEMORY;
2286  }
2287 
2288  if (flags & WINED3D_MAP_WRITE
2289  && (!(flags & WINED3D_MAP_NO_DIRTY_UPDATE) || (resource->usage & WINED3DUSAGE_DYNAMIC)))
2290  wined3d_texture_invalidate_location(texture, sub_resource_idx, ~resource->map_binding);
2291 
2292  wined3d_texture_get_memory(texture, sub_resource_idx, &data, resource->map_binding);
2293  base_memory = context_map_bo_address(context, &data, sub_resource->size, GL_PIXEL_UNPACK_BUFFER, flags);
2294  TRACE("Base memory pointer %p.\n", base_memory);
2295 
2296  if (context)
2297  context_release(context);
2298 
2299  if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
2300  {
2301  map_desc->row_pitch = wined3d_texture_get_level_width(texture, texture_level) * format->byte_count;
2302  map_desc->slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * map_desc->row_pitch;
2303  }
2304  else
2305  {
2306  wined3d_texture_get_pitch(texture, texture_level, &map_desc->row_pitch, &map_desc->slice_pitch);
2307  }
2308 
2309  if (!box)
2310  {
2311  map_desc->data = base_memory;
2312  }
2313  else
2314  {
2315  if ((fmt_flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BROKEN_PITCH)) == WINED3DFMT_FLAG_BLOCKS)
2316  {
2317  /* Compressed textures are block based, so calculate the offset of
2318  * the block that contains the top-left pixel of the mapped box. */
2319  map_desc->data = base_memory
2320  + (box->front * map_desc->slice_pitch)
2321  + ((box->top / format->block_height) * map_desc->row_pitch)
2322  + ((box->left / format->block_width) * format->block_byte_count);
2323  }
2324  else
2325  {
2326  map_desc->data = base_memory
2327  + (box->front * map_desc->slice_pitch)
2328  + (box->top * map_desc->row_pitch)
2329  + (box->left * format->byte_count);
2330  }
2331  }
2332 
2333  if (texture->swapchain && texture->swapchain->front_buffer == texture)
2334  {
2335  RECT *r = &texture->swapchain->front_buffer_update;
2336 
2337  if (!box)
2338  SetRect(r, 0, 0, resource->width, resource->height);
2339  else
2340  SetRect(r, box->left, box->top, box->right, box->bottom);
2341  TRACE("Mapped front buffer %s.\n", wine_dbgstr_rect(r));
2342  }
2343 
2344  ++resource->map_count;
2345  ++sub_resource->map_count;
2346 
2347  TRACE("Returning memory %p, row pitch %u, slice pitch %u.\n",
2348  map_desc->data, map_desc->row_pitch, map_desc->slice_pitch);
2349 
2350  return WINED3D_OK;
2351 }
2352 
2354  struct wined3d_map_info *info, DWORD flags)
2355 {
2356  const struct wined3d_format *format = resource->format;
2357  struct wined3d_texture_sub_resource *sub_resource;
2358  unsigned int fmt_flags = resource->format_flags;
2359  struct wined3d_texture *texture;
2360  unsigned int texture_level;
2361 
2362  texture = texture_from_resource(resource);
2363  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
2364  return E_INVALIDARG;
2365 
2366  texture_level = sub_resource_idx % texture->level_count;
2367 
2368  if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
2369  {
2370  info->row_pitch = wined3d_texture_get_level_width(texture, texture_level) * format->byte_count;
2371  info->slice_pitch = wined3d_texture_get_level_height(texture, texture_level) * info->row_pitch;
2372  }
2373  else
2374  {
2375  wined3d_texture_get_pitch(texture, texture_level, &info->row_pitch, &info->slice_pitch);
2376  }
2377 
2378  info->size = info->slice_pitch * wined3d_texture_get_level_depth(texture, texture_level);
2379 
2380  return WINED3D_OK;
2381 }
2382 
2384 {
2385  struct wined3d_texture_sub_resource *sub_resource;
2386  struct wined3d_device *device = resource->device;
2387  struct wined3d_context *context = NULL;
2388  struct wined3d_texture *texture;
2389  struct wined3d_bo_address data;
2390 
2391  TRACE("resource %p, sub_resource_idx %u.\n", resource, sub_resource_idx);
2392 
2393  texture = texture_from_resource(resource);
2394  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
2395  return E_INVALIDARG;
2396 
2397  if (!sub_resource->map_count)
2398  {
2399  WARN("Trying to unmap unmapped sub-resource.\n");
2400  if (texture->flags & WINED3D_TEXTURE_DC_IN_USE)
2401  return WINED3D_OK;
2402  return WINEDDERR_NOTLOCKED;
2403  }
2404 
2405  if (device->d3d_initialized)
2406  context = context_acquire(device, NULL, 0);
2407 
2408  wined3d_texture_get_memory(texture, sub_resource_idx, &data, texture->resource.map_binding);
2410 
2411  if (context)
2412  context_release(context);
2413 
2414  if (texture->swapchain && texture->swapchain->front_buffer == texture)
2415  {
2416  if (!(sub_resource->locations & (WINED3D_LOCATION_DRAWABLE | WINED3D_LOCATION_TEXTURE_RGB)))
2417  texture->swapchain->swapchain_ops->swapchain_frontbuffer_updated(texture->swapchain);
2418  }
2419 
2420  --sub_resource->map_count;
2421  if (!--resource->map_count && texture->update_map_binding)
2423 
2424  return WINED3D_OK;
2425 }
2426 
2428 {
2436 };
2437 
2438 /* Context activation is done by the caller. */
2440  const struct wined3d_context *context, const struct wined3d_bo_address *data)
2441 {
2442  const struct wined3d_format *format = texture->resource.format;
2443  const struct wined3d_gl_info *gl_info = context->gl_info;
2444 
2445  if (format->conv_byte_count)
2446  {
2447  FIXME("Attempting to download a converted texture, format %s.\n",
2448  debug_d3dformat(format->id));
2449  return;
2450  }
2451 
2452  if (data->buffer_object)
2453  {
2454  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
2455  checkGLcall("glBindBuffer");
2456  }
2457 
2458  gl_info->gl_ops.gl.p_glGetTexImage(texture->target, sub_resource_idx,
2459  format->glFormat, format->glType, data->addr);
2460  checkGLcall("glGetTexImage");
2461 
2462  if (data->buffer_object)
2463  {
2464  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
2465  checkGLcall("glBindBuffer");
2466  }
2467 }
2468 
2469 /* Context activation is done by the caller. */
2472 {
2473  struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
2474  unsigned int row_pitch, slice_pitch;
2475 
2476  TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
2477  texture, sub_resource_idx, context, wined3d_debug_location(location));
2478 
2479  if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
2480  return FALSE;
2481 
2482  switch (location)
2483  {
2486  if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
2487  {
2488  struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
2489  struct wined3d_box src_box;
2490 
2491  data.addr += sub_resource->offset;
2492  wined3d_texture_bind_and_dirtify(texture, context,
2493  location == WINED3D_LOCATION_TEXTURE_SRGB);
2494  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
2495  wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
2496  wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
2497  &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
2498  }
2499  else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
2500  {
2501  struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
2502  struct wined3d_box src_box;
2503 
2504  wined3d_texture_bind_and_dirtify(texture, context,
2505  location == WINED3D_LOCATION_TEXTURE_SRGB);
2506  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
2507  wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
2508  wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
2509  &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
2510  }
2511  else
2512  {
2513  FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
2514  return FALSE;
2515  }
2516  break;
2517 
2519  if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
2520  {
2521  struct wined3d_bo_address data = {0, texture->resource.heap_memory};
2522 
2523  data.addr += sub_resource->offset;
2524  if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
2525  wined3d_texture_bind_and_dirtify(texture, context, FALSE);
2526  else
2527  wined3d_texture_bind_and_dirtify(texture, context, TRUE);
2528 
2529  texture1d_download_data(texture, sub_resource_idx, context, &data);
2530  ++texture->download_count;
2531  }
2532  else
2533  {
2534  FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
2535  wined3d_debug_location(sub_resource->locations));
2536  return FALSE;
2537  }
2538  break;
2539 
2541  if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
2542  {
2543  struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
2544 
2545  if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
2546  wined3d_texture_bind_and_dirtify(texture, context, FALSE);
2547  else
2548  wined3d_texture_bind_and_dirtify(texture, context, TRUE);
2549 
2550  texture1d_download_data(texture, sub_resource_idx, context, &data);
2551  }
2552  else
2553  {
2554  FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
2555  wined3d_debug_location(sub_resource->locations));
2556  return FALSE;
2557  }
2558  break;
2559 
2560  default:
2561  FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
2562  wined3d_debug_location(sub_resource->locations));
2563  return FALSE;
2564  }
2565 
2566  return TRUE;
2567 }
2568 
2569 static const struct wined3d_texture_ops texture1d_ops =
2570 {
2572 };
2573 
2575  unsigned int layer_count, unsigned int level_count, DWORD flags, struct wined3d_device *device,
2576  void *parent, const struct wined3d_parent_ops *parent_ops, const struct wined3d_texture_ops *texture_ops)
2577 {
2578  struct wined3d_device_parent *device_parent = device->device_parent;
2579  const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
2580  unsigned int sub_count, i, j, size, offset = 0;
2581  unsigned int pow2_width, pow2_height;
2582  const struct wined3d_format *format;
2583  HRESULT hr;
2584 
2585  TRACE("texture %p, resource_type %s, format %s, multisample_type %#x, multisample_quality %#x, "
2586  "usage %s, access %s, width %u, height %u, depth %u, layer_count %u, level_count %u, "
2587  "flags %#x, device %p, parent %p, parent_ops %p, texture_ops %p.\n",
2590  wined3d_debug_resource_access(desc->access), desc->width, desc->height, desc->depth,
2591  layer_count, level_count, flags, device, parent, parent_ops, texture_ops);
2592 
2593  if (!desc->width || !desc->height || !desc->depth)
2594  return WINED3DERR_INVALIDCALL;
2595 
2597  {
2598  if (layer_count != 1)
2599  {
2600  ERR("Invalid layer count for volume texture.\n");
2601  return E_INVALIDARG;
2602  }
2603 
2604  if (!gl_info->supported[EXT_TEXTURE3D])
2605  {
2606  WARN("OpenGL implementation does not support 3D textures.\n");
2607  return WINED3DERR_INVALIDCALL;
2608  }
2609  }
2610 
2611  if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1
2612  && !gl_info->supported[EXT_TEXTURE_ARRAY])
2613  {
2614  WARN("OpenGL implementation does not support array textures.\n");
2615  return WINED3DERR_INVALIDCALL;
2616  }
2617 
2618  /* TODO: It should only be possible to create textures for formats
2619  * that are reported as supported. */
2620  if (WINED3DFMT_UNKNOWN >= desc->format)
2621  {
2622  WARN("Texture cannot be created with a format of WINED3DFMT_UNKNOWN.\n");
2623  return WINED3DERR_INVALIDCALL;
2624  }
2625 
2627  || desc->usage & WINED3DUSAGE_SCRATCH))
2628  {
2629  WARN("Attempted to create a dynamic texture with access %s and usage %s.\n",
2631  return WINED3DERR_INVALIDCALL;
2632  }
2633 
2635  && (flags & WINED3D_TEXTURE_CREATE_MAPPABLE))
2636  WARN("Creating a mappable texture that doesn't specify dynamic usage.\n");
2638  FIXME("Trying to create a CPU accessible render target.\n");
2639 
2640  pow2_width = desc->width;
2641  pow2_height = desc->height;
2642  if (((desc->width & (desc->width - 1)) || (desc->height & (desc->height - 1)) || (desc->depth & (desc->depth - 1)))
2644  {
2645  /* level_count == 0 returns an error as well. */
2646  if (level_count != 1 || layer_count != 1 || desc->resource_type == WINED3D_RTYPE_TEXTURE_3D)
2647  {
2648  if (!(desc->usage & WINED3DUSAGE_SCRATCH))
2649  {
2650  WARN("Attempted to create a mipmapped/cube/array/volume NPOT "
2651  "texture without unconditional NPOT support.\n");
2652  return WINED3DERR_INVALIDCALL;
2653  }
2654 
2655  WARN("Creating a scratch mipmapped/cube/array NPOT texture despite lack of HW support.\n");
2656  }
2657  texture->flags |= WINED3D_TEXTURE_COND_NP2;
2658 
2661  {
2662  const struct wined3d_format *format = wined3d_get_format(gl_info, desc->format, desc->usage);
2663 
2664  /* TODO: Add support for non-power-of-two compressed textures. */
2665  if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D]
2667  {
2668  FIXME("Compressed or height scaled non-power-of-two (%ux%u) textures are not supported.\n",
2669  desc->width, desc->height);
2670  return WINED3DERR_NOTAVAILABLE;
2671  }
2672 
2673  /* Find the nearest pow2 match. */
2674  pow2_width = pow2_height = 1;
2675  while (pow2_width < desc->width)
2676  pow2_width <<= 1;
2677  while (pow2_height < desc->height)
2678  pow2_height <<= 1;
2680  }
2681  }
2682  texture->pow2_width = pow2_width;
2683  texture->pow2_height = pow2_height;
2684 
2685  if ((pow2_width > gl_info->limits.texture_size || pow2_height > gl_info->limits.texture_size)
2686  && (desc->usage & WINED3DUSAGE_TEXTURE))
2687  {
2688  /* One of four options:
2689  * 1: Do the same as we do with NPOT and scale the texture. (Any
2690  * texture ops would require the texture to be scaled which is
2691  * potentially slow.)
2692  * 2: Set the texture to the maximum size (bad idea).
2693  * 3: WARN and return WINED3DERR_NOTAVAILABLE.
2694  * 4: Create the surface, but allow it to be used only for DirectDraw
2695  * Blts. Some apps (e.g. Swat 3) create textures with a height of
2696  * 16 and a width > 3000 and blt 16x16 letter areas from them to
2697  * the render target. */
2698  if (desc->access & WINED3D_RESOURCE_ACCESS_GPU)
2699  {
2700  WARN("Dimensions (%ux%u) exceed the maximum texture size.\n", pow2_width, pow2_height);
2701  return WINED3DERR_NOTAVAILABLE;
2702  }
2703 
2704  /* We should never use this surface in combination with OpenGL. */
2705  TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height);
2706  }
2707 
2708  format = wined3d_get_format(&device->adapter->gl_info, desc->format, desc->usage);
2709  for (i = 0; i < layer_count; ++i)
2710  {
2711  for (j = 0; j < level_count; ++j)
2712  {
2713  unsigned int idx = i * level_count + j;
2714 
2715  size = wined3d_format_calculate_size(format, device->surface_alignment,
2716  max(1, desc->width >> j), max(1, desc->height >> j), max(1, desc->depth >> j));
2717  texture->sub_resources[idx].offset = offset;
2718  texture->sub_resources[idx].size = size;
2719  offset += size;
2720  }
2721  offset = (offset + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1);
2722  }
2723 
2724  if (!offset)
2725  return WINED3DERR_INVALIDCALL;
2726 
2727  if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
2728  desc->multisample_type, desc->multisample_quality, desc->usage, desc->access,
2729  desc->width, desc->height, desc->depth, offset, parent, parent_ops, &texture_resource_ops)))
2730  {
2731  static unsigned int once;
2732 
2733  /* DXTn 3D textures are not supported. Do not write the ERR for them. */
2734  if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3
2735  || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5)
2737  && desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !once++)
2738  ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n");
2739 
2740  WARN("Failed to initialize resource, returning %#x\n", hr);
2741  return hr;
2742  }
2744  if ((flags & WINED3D_TEXTURE_CREATE_MAPPABLE) || desc->format == WINED3DFMT_D16_LOCKABLE)
2746 
2747  texture->texture_ops = texture_ops;
2748 
2749  texture->layer_count = layer_count;
2750  texture->level_count = level_count;
2751  texture->lod = 0;
2755  if (flags & (WINED3D_TEXTURE_CREATE_GET_DC | WINED3D_TEXTURE_CREATE_GET_DC_LENIENT))
2756  texture->flags |= WINED3D_TEXTURE_GET_DC;
2757  if (flags & WINED3D_TEXTURE_CREATE_DISCARD)
2758  texture->flags |= WINED3D_TEXTURE_DISCARD;
2760  {
2761  if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP))
2762  WARN("Format doesn't support mipmaps generation, "
2763  "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n");
2764  else
2766  }
2767 
2768  list_init(&texture->renderbuffers);
2769 
2770  switch (desc->resource_type)
2771  {
2773  if (layer_count > 1)
2774  texture->target = GL_TEXTURE_1D_ARRAY;
2775  else
2776  texture->target = GL_TEXTURE_1D;
2777  break;
2778 
2780  if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
2781  {
2782  texture->target = GL_TEXTURE_CUBE_MAP_ARB;
2783  }
2784  else if (desc->multisample_type && gl_info->supported[ARB_TEXTURE_MULTISAMPLE])
2785  {
2786  if (layer_count > 1)
2788  else
2789  texture->target = GL_TEXTURE_2D_MULTISAMPLE;
2790  }
2791  else
2792  {
2793  if (layer_count > 1)
2794  texture->target = GL_TEXTURE_2D_ARRAY;
2795  else
2796  texture->target = GL_TEXTURE_2D;
2797  }
2798  break;
2799 
2801  texture->target = GL_TEXTURE_3D;
2802  break;
2803 
2804  default:
2805  ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
2807  return WINED3DERR_INVALIDCALL;
2808  }
2809 
2810  /* Precalculated scaling for 'faked' non power of two texture coords. */
2811  if (texture->resource.gl_type == WINED3D_GL_RES_TYPE_TEX_RECT)
2812  {
2813  texture->pow2_matrix[0] = (float)desc->width;
2814  texture->pow2_matrix[5] = (float)desc->height;
2816  texture->target = GL_TEXTURE_RECTANGLE_ARB;
2817  }
2818  else if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
2819  {
2820  texture->pow2_matrix[0] = (((float)desc->width) / ((float)pow2_width));
2821  texture->pow2_matrix[5] = (((float)desc->height) / ((float)pow2_height));
2823  }
2824  else
2825  {
2826  texture->pow2_matrix[0] = 1.0f;
2827  texture->pow2_matrix[5] = 1.0f;
2828  }
2829  texture->pow2_matrix[10] = 1.0f;
2830  texture->pow2_matrix[15] = 1.0f;
2831  TRACE("x scale %.8e, y scale %.8e.\n", texture->pow2_matrix[0], texture->pow2_matrix[5]);
2832 
2833  if (wined3d_texture_use_pbo(texture, gl_info))
2834  texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
2835 
2837  && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
2838  || !wined3d_texture_use_pbo(texture, gl_info))
2839  {
2841  {
2843  return E_OUTOFMEMORY;
2844  }
2845  }
2846 
2847  sub_count = level_count * layer_count;
2848  if (sub_count / layer_count != level_count)
2849  {
2851  return E_OUTOFMEMORY;
2852  }
2853 
2854  if (desc->usage & WINED3DUSAGE_OVERLAY)
2855  {
2856  if (!(texture->overlay_info = heap_calloc(sub_count, sizeof(*texture->overlay_info))))
2857  {
2859  return E_OUTOFMEMORY;
2860  }
2861 
2862  for (i = 0; i < sub_count; ++i)
2863  {
2864  list_init(&texture->overlay_info[i].entry);
2865  list_init(&texture->overlay_info[i].overlays);
2866  }
2867  }
2868 
2869  /* Generate all sub-resources. */
2870  for (i = 0; i < sub_count; ++i)
2871  {
2872  struct wined3d_texture_sub_resource *sub_resource;
2873 
2874  sub_resource = &texture->sub_resources[i];
2875  sub_resource->locations = WINED3D_LOCATION_DISCARDED;
2877  && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
2878  {
2881  }
2882 
2883  if (FAILED(hr = device_parent->ops->texture_sub_resource_created(device_parent,
2884  desc->resource_type, texture, i, &sub_resource->parent, &sub_resource->parent_ops)))
2885  {
2886  WARN("Failed to create sub-resource parent, hr %#x.\n", hr);
2887  sub_resource->parent = NULL;
2889  return hr;
2890  }
2891 
2892  TRACE("parent %p, parent_ops %p.\n", sub_resource->parent, sub_resource->parent_ops);
2893 
2894  TRACE("Created sub-resource %u (level %u, layer %u).\n",
2895  i, i % texture->level_count, i / texture->level_count);
2896 
2897  if ((desc->usage & WINED3DUSAGE_OWNDC) || (device->wined3d->flags & WINED3D_NO3D))
2898  {
2899  struct wined3d_texture_idx texture_idx = {texture, i};
2900 
2901  wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx);
2902  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
2903  if (!texture->dc_info || !texture->dc_info[i].dc)
2904  {
2906  return WINED3DERR_INVALIDCALL;
2907  }
2908  }
2909  }
2910 
2911  return WINED3D_OK;
2912 }
2913 
2914 /* Context activation is done by the caller. */
2916  const struct wined3d_context *context, const struct wined3d_bo_address *data)
2917 {
2918  const struct wined3d_format *format = texture->resource.format;
2919  const struct wined3d_gl_info *gl_info = context->gl_info;
2920 
2921  if (format->conv_byte_count)
2922  {
2923  FIXME("Attempting to download a converted volume, format %s.\n",
2924  debug_d3dformat(format->id));
2925  return;
2926  }
2927 
2928  if (data->buffer_object)
2929  {
2930  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, data->buffer_object));
2931  checkGLcall("glBindBuffer");
2932  }
2933 
2934  gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_3D, sub_resource_idx,
2935  format->glFormat, format->glType, data->addr);
2936  checkGLcall("glGetTexImage");
2937 
2938  if (data->buffer_object)
2939  {
2940  GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
2941  checkGLcall("glBindBuffer");
2942  }
2943 
2944 }
2945 
2946 /* Context activation is done by the caller. */
2948  struct wined3d_context *context, BOOL dest_is_srgb)
2949 {
2950  struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
2951  unsigned int row_pitch, slice_pitch;
2952  struct wined3d_bo_address data;
2953  struct wined3d_box src_box;
2954 
2955  /* Optimisations are possible, but the effort should be put into either
2956  * implementing EXT_SRGB_DECODE in the driver or finding out why we
2957  * picked the wrong copy for the original upload and fixing that.
2958  *
2959  * Also keep in mind that we want to avoid using resource.heap_memory
2960  * for DEFAULT pool surfaces. */
2961  WARN_(d3d_perf)("Performing slow rgb/srgb volume transfer.\n");
2962  data.buffer_object = 0;
2963  if (!(data.addr = heap_alloc(sub_resource->size)))
2964  return;
2965 
2966  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
2967  wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
2968  wined3d_texture_bind_and_dirtify(texture, context, !dest_is_srgb);
2969  texture3d_download_data(texture, sub_resource_idx, context, &data);
2970  wined3d_texture_bind_and_dirtify(texture, context, dest_is_srgb);
2971  wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
2972  &src_box, wined3d_const_bo_address(&data), row_pitch, slice_pitch, 0, 0, 0, FALSE);
2973 
2974  heap_free(data.addr);
2975 }
2976 
2977 /* Context activation is done by the caller. */
2980 {
2981  struct wined3d_texture_sub_resource *sub_resource = &texture->sub_resources[sub_resource_idx];
2982  unsigned int row_pitch, slice_pitch;
2983 
2984  if (!wined3d_texture_prepare_location(texture, sub_resource_idx, context, location))
2985  return FALSE;
2986 
2987  switch (location)
2988  {
2991  if (sub_resource->locations & WINED3D_LOCATION_SYSMEM)
2992  {
2993  struct wined3d_const_bo_address data = {0, texture->resource.heap_memory};
2994  struct wined3d_box src_box;
2995 
2996  data.addr += sub_resource->offset;
2997  wined3d_texture_bind_and_dirtify(texture, context,
2998  location == WINED3D_LOCATION_TEXTURE_SRGB);
2999  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
3000  wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
3001  wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
3002  &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
3003  }
3004  else if (sub_resource->locations & WINED3D_LOCATION_BUFFER)
3005  {
3006  struct wined3d_const_bo_address data = {sub_resource->buffer_object, NULL};
3007  struct wined3d_box src_box;
3008 
3009  wined3d_texture_bind_and_dirtify(texture, context,
3010  location == WINED3D_LOCATION_TEXTURE_SRGB);
3011  wined3d_texture_get_pitch(texture, sub_resource_idx, &row_pitch, &slice_pitch);
3012  wined3d_texture_get_level_box(texture, sub_resource_idx % texture->level_count, &src_box);
3013  wined3d_texture_upload_data(texture, sub_resource_idx, context, texture->resource.format,
3014  &src_box, &data, row_pitch, slice_pitch, 0, 0, 0, FALSE);
3015  }
3016  else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
3017  {
3018  texture3d_srgb_transfer(texture, sub_resource_idx, context, TRUE);
3019  }
3020  else if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_SRGB)
3021  {
3022  texture3d_srgb_transfer(texture, sub_resource_idx, context, FALSE);
3023  }
3024  else
3025  {
3026  FIXME("Implement texture loading from %s.\n", wined3d_debug_location(sub_resource->locations));
3027  return FALSE;
3028  }
3029  break;
3030 
3032  if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
3033  {
3034  struct wined3d_bo_address data = {0, texture->resource.heap_memory};
3035 
3036  data.addr += sub_resource->offset;
3037  if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
3038  wined3d_texture_bind_and_dirtify(texture, context, FALSE);
3039  else
3040  wined3d_texture_bind_and_dirtify(texture, context, TRUE);
3041 
3042  texture3d_download_data(texture, sub_resource_idx, context, &data);
3043  ++texture->download_count;
3044  }
3045  else
3046  {
3047  FIXME("Implement WINED3D_LOCATION_SYSMEM loading from %s.\n",
3048  wined3d_debug_location(sub_resource->locations));
3049  return FALSE;
3050  }
3051  break;
3052 
3054  if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
3055  {
3056  struct wined3d_bo_address data = {sub_resource->buffer_object, NULL};
3057 
3058  if (sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB)
3059  wined3d_texture_bind_and_dirtify(texture, context, FALSE);
3060  else
3061  wined3d_texture_bind_and_dirtify(texture, context, TRUE);
3062 
3063  texture3d_download_data(texture, sub_resource_idx, context, &data);
3064  }
3065  else
3066  {
3067  FIXME("Implement WINED3D_LOCATION_BUFFER loading from %s.\n",
3068  wined3d_debug_location(sub_resource->locations));
3069  return FALSE;
3070  }
3071  break;
3072 
3073  default:
3074  FIXME("Implement %s loading from %s.\n", wined3d_debug_location(location),
3075  wined3d_debug_location(sub_resource->locations));
3076  return FALSE;
3077  }
3078 
3079  return TRUE;
3080 }
3081 
3082 static const struct wined3d_texture_ops texture3d_ops =
3083 {
3085 };
3086 
3087 HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
3088  const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx,
3089  const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
3090 {
3091  struct wined3d_box src_box = {src_rect->left, src_rect->top, src_rect->right, src_rect->bottom, 0, 1};
3092  struct wined3d_box dst_box = {dst_rect->left, dst_rect->top, dst_rect->right, dst_rect->bottom, 0, 1};
3093  unsigned int dst_format_flags, src_format_flags = 0;
3094  HRESULT hr;
3095 
3096  TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_rect %s, src_texture %p, "
3097  "src_sub_resource_idx %u, src_rect %s, flags %#x, fx %p, filter %s.\n",
3098  dst_texture, dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), src_texture,
3099  src_sub_resource_idx, wine_dbgstr_rect(src_rect), flags, fx, debug_d3dtexturefiltertype(filter));
3100 
3101  if (dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count
3102  || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
3103  return WINED3DERR_INVALIDCALL;
3104 
3105  if (src_sub_resource_idx >= src_texture->level_count * src_texture->layer_count
3106  || src_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
3107  return WINED3DERR_INVALIDCALL;
3108 
3109  dst_format_flags = dst_texture->resource.format_flags;
3110  if (FAILED(hr = wined3d_texture_check_box_dimensions(dst_texture,
3111  dst_sub_resource_idx % dst_texture->level_count, &dst_box)))
3112  return hr;
3113 
3114  src_format_flags = src_texture->resource.format_flags;
3115  if (FAILED(hr = wined3d_texture_check_box_dimensions(src_texture,
3116  src_sub_resource_idx % src_texture->level_count, &src_box)))
3117  return hr;
3118 
3119  if (dst_texture->sub_resources[dst_sub_resource_idx].map_count
3120  || src_texture->sub_resources[src_sub_resource_idx].map_count)
3121  {
3122  WARN("Sub-resource is busy, returning WINEDDERR_SURFACEBUSY.\n");
3123  return WINEDDERR_SURFACEBUSY;
3124  }
3125 
3126  if ((src_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
3127  != (dst_format_flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
3128  {
3129  WARN("Rejecting depth/stencil blit between incompatible formats.\n");
3130  return WINED3DERR_INVALIDCALL;
3131  }
3132 
3133  wined3d_cs_emit_blt_sub_resource(dst_texture->resource.device->cs, &dst_texture->resource, dst_sub_resource_idx,
3134  &dst_box, &src_texture->resource, src_sub_resource_idx, &src_box, flags, fx, filter);
3135 
3136  return WINED3D_OK;
3137 }
3138 
3140  unsigned int sub_resource_idx, LONG *x, LONG *y)
3141 {
3142  struct wined3d_overlay_info *overlay;
3143 
3144  TRACE("texture %p, sub_resource_idx %u, x %p, y %p.\n", texture, sub_resource_idx, x, y);
3145 
3146  if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY)
3147  || sub_resource_idx >= texture->level_count * texture->layer_count)
3148  {
3149  WARN("Invalid sub-resource specified.\n");
3151  }
3152 
3153  overlay = &texture->overlay_info[sub_resource_idx];
3154  if (!overlay->dst_texture)
3155  {
3156  TRACE("Overlay not visible.\n");
3157  *x = 0;
3158  *y = 0;
3160  }
3161 
3162  *x = overlay->dst_rect.left;
3163  *y = overlay->dst_rect.top;
3164 
3165  TRACE("Returning position %d, %d.\n", *x, *y);
3166 
3167  return WINED3D_OK;
3168 }
3169 
3171  unsigned int sub_resource_idx, LONG x, LONG y)
3172 {
3173  struct wined3d_overlay_info *overlay;
3174  LONG w, h;
3175 
3176  TRACE("texture %p, sub_resource_idx %u, x %d, y %d.\n", texture, sub_resource_idx, x, y);
3177 
3178  if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY)
3179  || sub_resource_idx >= texture->level_count * texture->layer_count)
3180  {
3181  WARN("Invalid sub-resource specified.\n");
3183  }
3184 
3185  overlay = &texture->overlay_info[sub_resource_idx];
3186  w = overlay->dst_rect.right - overlay->dst_rect.left;
3187  h = overlay->dst_rect.bottom - overlay->dst_rect.top;
3188  SetRect(&overlay->dst_rect, x, y, x + w, y + h);
3189 
3190  return WINED3D_OK;
3191 }
3192 
3194  const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
3195  const RECT *dst_rect, DWORD flags)
3196 {
3197  struct wined3d_overlay_info *overlay;
3198  unsigned int level, dst_level;
3199 
3200  TRACE("texture %p, sub_resource_idx %u, src_rect %s, dst_texture %p, "
3201  "dst_sub_resource_idx %u, dst_rect %s, flags %#x.\n",
3202  texture, sub_resource_idx, wine_dbgstr_rect(src_rect), dst_texture,
3203  dst_sub_resource_idx, wine_dbgstr_rect(dst_rect), flags);
3204 
3205  if (!(texture->resource.usage & WINED3DUSAGE_OVERLAY) || texture->resource.type != WINED3D_RTYPE_TEXTURE_2D
3206  || sub_resource_idx >= texture->level_count * texture->layer_count)
3207  {
3208  WARN("Invalid sub-resource specified.\n");
3210  }
3211 
3212  if (!dst_texture || dst_texture->resource.type != WINED3D_RTYPE_TEXTURE_2D
3213  || dst_sub_resource_idx >= dst_texture->level_count * dst_texture->layer_count)
3214  {
3215  WARN("Invalid destination sub-resource specified.\n");
3216  return WINED3DERR_INVALIDCALL;
3217  }
3218 
3219  overlay = &texture->overlay_info[sub_resource_idx];
3220 
3221  level = sub_resource_idx % texture->level_count;
3222  if (src_rect)
3223  overlay->src_rect = *src_rect;
3224  else
3225  SetRect(&overlay->src_rect, 0, 0,
3226  wined3d_texture_get_level_width(texture, level),
3227  wined3d_texture_get_level_height(texture, level));
3228 
3229  dst_level = dst_sub_resource_idx % dst_texture->level_count;
3230  if (dst_rect)
3231  overlay->dst_rect = *dst_rect;
3232  else
3233  SetRect(&overlay->dst_rect, 0, 0,
3234  wined3d_texture_get_level_width(dst_texture, dst_level),
3235  wined3d_texture_get_level_height(dst_texture, dst_level));
3236 
3237  if (overlay->dst_texture && (overlay->dst_texture != dst_texture
3238  || overlay->dst_sub_resource_idx != dst_sub_resource_idx || flags & WINEDDOVER_HIDE))
3239  {
3240  overlay->dst_texture = NULL;
3241  list_remove(&overlay->entry);
3242  }
3243 
3244  if (flags & WINEDDOVER_SHOW)
3245  {
3246  if (overlay->dst_texture != dst_texture || overlay->dst_sub_resource_idx != dst_sub_resource_idx)
3247  {
3248  overlay->dst_texture = dst_texture;
3249  overlay->dst_sub_resource_idx = dst_sub_resource_idx;
3250  list_add_tail(&texture->overlay_info[dst_sub_resource_idx].overlays, &overlay->entry);
3251  }
3252  }
3253  else if (flags & WINEDDOVER_HIDE)
3254  {
3255  /* Tests show that the rectangles are erased on hide. */
3256  SetRectEmpty(&overlay->src_rect);
3257  SetRectEmpty(&overlay->dst_rect);
3258  overlay->dst_texture = NULL;
3259  }
3260 
3261  return WINED3D_OK;
3262 }
3263 
3265 {
3266  unsigned int sub_count = texture->level_count * texture->layer_count;
3267 
3268  TRACE("texture %p, sub_resource_idx %u.\n", texture, sub_resource_idx);
3269 
3270  if (sub_resource_idx >= sub_count)
3271  {
3272  WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count);
3273  return NULL;
3274  }
3275 
3276  return texture->sub_resources[sub_resource_idx].parent;
3277 }
3278 
3280  unsigned int sub_resource_idx, void *parent)
3281 {
3282  unsigned int sub_count = texture->level_count * texture->layer_count;
3283 
3284  TRACE("texture %p, sub_resource_idx %u, parent %p.\n", texture, sub_resource_idx, parent);
3285 
3286  if (sub_resource_idx >= sub_count)
3287  {
3288  WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count);
3289  return;
3290  }
3291 
3292  texture->sub_resources[sub_resource_idx].parent = parent;
3293 }
3294 
3296  unsigned int sub_resource_idx, struct wined3d_sub_resource_desc *desc)
3297 {
3298  unsigned int sub_count = texture->level_count * texture->layer_count;
3299  const struct wined3d_resource *resource;
3300  unsigned int level_idx;
3301 
3302  TRACE("texture %p, sub_resource_idx %u, desc %p.\n", texture, sub_resource_idx, desc);
3303 
3304  if (sub_resource_idx >= sub_count)
3305  {
3306  WARN("sub_resource_idx %u >= sub_count %u.\n", sub_resource_idx, sub_count);
3307  return WINED3DERR_INVALIDCALL;
3308  }
3309 
3310  resource = &texture->resource;
3311  desc->format = resource->format->id;
3312  desc->multisample_type = resource->multisample_type;
3313  desc->multisample_quality = resource->multisample_quality;
3314  desc->usage = resource->usage;
3315  desc->access = resource->access;
3316 
3317  level_idx = sub_resource_idx % texture->level_count;
3318  desc->width = wined3d_texture_get_level_width(texture, level_idx);
3319  desc->height = wined3d_texture_get_level_height(texture, level_idx);
3320  desc->depth = wined3d_texture_get_level_depth(texture, level_idx);
3321  desc->size = texture->sub_resources[sub_resource_idx].size;
3322 
3323  return WINED3D_OK;
3324 }
3325 
3327  UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data,
3328  void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
3329 {
3330  const struct wined3d_texture_ops *texture_ops;
3331  struct wined3d_texture *object;
3332  HRESULT hr;
3333 
3334  TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, data %p, "
3335  "parent %p, parent_ops %p, texture %p.\n",
3336  device, desc, layer_count, level_count, flags, data, parent, parent_ops, texture);
3337 
3338  if (!layer_count)
3339  {
3340  WARN("Invalid layer count.\n");
3341  return E_INVALIDARG;
3342  }
3343  if ((desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count != 6)
3344  {
3345  ERR("Invalid layer count %u for legacy cubemap.\n", layer_count);
3346  layer_count = 6;
3347  }
3348 
3349  if (!level_count)
3350  {
3351  WARN("Invalid level count.\n");
3352  return WINED3DERR_INVALIDCALL;
3353  }
3354 
3356  {
3357  const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info,
3358  desc->format, desc->usage);
3359 
3362  {
3363  WARN("Unsupported quality level %u requested for WINED3D_MULTISAMPLE_NON_MASKABLE.\n",
3364  desc->multisample_quality);
3365  return WINED3DERR_NOTAVAILABLE;
3366  }
3368  && (!(format->multisample_types & 1u << (desc->multisample_type - 1))
3369  || desc->multisample_quality))
3370  {
3371  WARN("Unsupported multisample type %u quality %u requested.\n", desc->multisample_type,
3372  desc->multisample_quality);
3373  return WINED3DERR_NOTAVAILABLE;
3374  }
3375  }
3376 
3377  switch (desc->resource_type)
3378  {
3380  texture_ops = &texture1d_ops;
3381  break;
3383  texture_ops = &texture2d_ops;
3384  break;
3386  texture_ops = &texture3d_ops;
3387  break;
3388  default:
3389  ERR("Invalid resource type %s.\n", debug_d3dresourcetype(desc->resource_type));
3390  return WINED3DERR_INVALIDCALL;
3391  }
3392 
3393  if (!(object = heap_alloc_zero(FIELD_OFFSET(struct wined3d_texture,
3394  sub_resources[level_count * layer_count]))))
3395  return E_OUTOFMEMORY;
3396 
3397  if (FAILED(hr = wined3d_texture_init(object, desc, layer_count,
3398  level_count, flags, device, parent, parent_ops, texture_ops)))
3399  {
3400  WARN("Failed to initialize texture, returning %#x.\n", hr);
3401  heap_free(object);
3402  return hr;
3403  }
3404 
3405  /* FIXME: We'd like to avoid ever allocating system memory for the texture
3406  * in this case. */
3407  if (data)
3408  {
3409  unsigned int sub_count = level_count * layer_count;
3410  unsigned int i;
3411 
3412  for (i = 0; i < sub_count; ++i)
3413  {
3414  if (!data[i].data)
3415  {
3416  WARN("Invalid sub-resource data specified for sub-resource %u.\n", i);
3418  heap_free(object);
3419  return E_INVALIDARG;
3420  }
3421  }
3422 
3423  for (i = 0; i < sub_count; ++i)
3424  {
3426  i, NULL, data[i].data, data[i].row_pitch, data[i].slice_pitch, 0);
3427  }
3428  }
3429 
3430  TRACE("Created texture %p.\n", object);
3431  *texture = object;
3432 
3433  return WINED3D_OK;
3434 }
3435 
3437 {
3438  struct wined3d_device *device = texture->resource.device;
3439  struct wined3d_texture_sub_resource *sub_resource;
3440  struct wined3d_dc_info *dc_info;
3441 
3442  TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
3443 
3444  if (!(texture->flags & WINED3D_TEXTURE_GET_DC))
3445  {
3446  WARN("Texture does not support GetDC\n");
3447  /* Don't touch the DC */
3448  return WINED3DERR_INVALIDCALL;
3449  }
3450 
3451  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
3452  return WINED3DERR_INVALIDCALL;
3453 
3454  if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
3455  {
3456  WARN("Not supported on %s resources.\n", debug_d3dresourcetype(texture->resource.type));
3457  return WINED3DERR_INVALIDCALL;
3458  }
3459 
3460  if (texture->resource.map_count && !(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
3461  return WINED3DERR_INVALIDCALL;
3462 
3463  if (!(dc_info = texture->dc_info) || !dc_info[sub_resource_idx].dc)
3464  {
3465  struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx};
3466 
3467  wined3d_cs_init_object(device->cs, wined3d_texture_create_dc, &texture_idx);
3468  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
3469  if (!(dc_info = texture->dc_info) || !dc_info[sub_resource_idx].dc)
3470  return WINED3DERR_INVALIDCALL;
3471  }
3472 
3473  if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
3474  texture->flags |= WINED3D_TEXTURE_DC_IN_USE;
3475  ++texture->resource.map_count;
3476  ++sub_resource->map_count;
3477 
3478  *dc = dc_info[sub_resource_idx].dc;
3479  TRACE("Returning dc %p.\n", *dc);
3480 
3481  return WINED3D_OK;
3482 }
3483 
3485 {
3486  struct wined3d_device *device = texture->resource.device;
3487  struct wined3d_texture_sub_resource *sub_resource;
3488  struct wined3d_dc_info *dc_info;
3489 
3490  TRACE("texture %p, sub_resource_idx %u, dc %p.\n", texture, sub_resource_idx, dc);
3491 
3492  if (!(sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx)))
3493  return WINED3DERR_INVALIDCALL;
3494 
3495  if (texture->resource.type != WINED3D_RTYPE_TEXTURE_2D)
3496  {
3497  WARN("Not supported on %s resources.\n", debug_d3dresourcetype(texture->resource.type));
3498  return WINED3DERR_INVALIDCALL;
3499  }
3500 
3502  return WINED3DERR_INVALIDCALL;
3503 
3504  if (!(dc_info = texture->dc_info) || dc_info[sub_resource_idx].dc != dc)
3505  {
3506  WARN("Application tries to release invalid DC %p, sub-resource DC is %p.\n",
3507  dc, dc_info ? dc_info[sub_resource_idx].dc : NULL);
3508  return WINED3DERR_INVALIDCALL;
3509  }
3510 
3511  if (!(texture->resource.usage & WINED3DUSAGE_OWNDC) && !(device->wined3d->flags & WINED3D_NO3D))
3512  {
3513  struct wined3d_texture_idx texture_idx = {texture, sub_resource_idx};
3514 
3516  device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
3517  }
3518 
3519  --sub_resource->map_count;
3520  if (!--texture->resource.map_count && texture->update_map_binding)
3522  if (!(texture->flags & WINED3D_TEXTURE_GET_DC_LENIENT))
3523  texture->flags &= ~WINED3D_TEXTURE_DC_IN_USE;
3524 
3525  return WINED3D_OK;
3526 }
3527 
3528 void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
3529  unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_texture *src_texture,
3530  unsigned int src_sub_resource_idx, const struct wined3d_box *src_box)
3531 {
3532  unsigned int src_row_pitch, src_slice_pitch;
3533  unsigned int update_w, update_h, update_d;
3534  unsigned int src_level, dst_level;
3535  struct wined3d_context *context;
3536  struct wined3d_bo_address data;
3537 
3538  TRACE("dst_texture %p, dst_sub_resource_idx %u, dst_x %u, dst_y %u, dst_z %u, "
3539  "src_texture %p, src_sub_resource_idx %u, src_box %s.\n",
3540  dst_texture, dst_sub_resource_idx, dst_x, dst_y, dst_z,
3541  src_texture, src_sub_resource_idx, debug_box(src_box));
3542 
3543  context = context_acquire(dst_texture->resource.device, NULL, 0);
3544 
3545  /* Only load the sub-resource for partial updates. For newly allocated
3546  * textures the texture wouldn't be the current location, and we'd upload
3547  * zeroes just to overwrite them again. */
3548  update_w = src_box->right - src_box->left;
3549  update_h = src_box->bottom - src_box->top;
3550  update_d = src_box->back - src_box->front;
3551  dst_level = dst_sub_resource_idx % dst_texture->level_count;
3552  if (update_w == wined3d_texture_get_level_width(dst_texture, dst_level)
3553  && update_h == wined3d_texture_get_level_height(dst_texture, dst_level)
3554  && update_d == wined3d_texture_get_level_depth(dst_texture, dst_level))
3555  wined3d_texture_prepare_texture(dst_texture, context, FALSE);
3556  else
3557  wined3d_texture_load_location(dst_texture, dst_sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
3558  wined3d_texture_bind_and_dirtify(dst_texture, context, FALSE);
3559 
3560  src_level = src_sub_resource_idx % src_texture->level_count;
3561  wined3d_texture_get_memory(src_texture, src_sub_resource_idx, &data,
3562  src_texture->sub_resources[src_sub_resource_idx].locations);
3563  wined3d_texture_get_pitch(src_texture, src_level, &src_row_pitch, &src_slice_pitch);
3564 
3565  wined3d_texture_upload_data(dst_texture, dst_sub_resource_idx, context, src_texture->resource.format,
3566  src_box, wined3d_const_bo_address(&data), src_row_pitch, src_slice_pitch, dst_x, dst_y, dst_z, FALSE);
3567 
3568  context_release(context);
3569 
3570  wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
3571  wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
3572 }
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
enum wined3d_format_id format
Definition: wined3d.h:1767
#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
enum wined3d_resource_type type
unsigned int sysmem_count
ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain)
Definition: swapchain.c:113
static void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture)
Definition: texture.c:703
enum wined3d_multisample_type multisample_type
const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion(const struct wined3d_texture *texture, BOOL need_alpha_ck)
Definition: utils.c:1007
#define HDC
Definition: msvc.h:22
static struct wined3d_texture_sub_resource * wined3d_texture_get_sub_resource(struct wined3d_texture *texture, unsigned int sub_resource_idx)
Definition: texture.c:1849
#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
void *CDECL wined3d_texture_get_parent(const struct wined3d_texture *texture)
Definition: texture.c:1317
GLint level
Definition: gl.h:1546
ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
Definition: texture.c:1219
GLint GLint GLsizei width
Definition: gl.h:1546
void wined3d_texture_upload_from_texture(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box)
Definition: texture.c:3528
unsigned short x_source
unsigned int pow2_width
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:563
#define max(a, b)
Definition: svc.c:63
unsigned int sub_resource_idx
Definition: texture.c:36
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define TRUE
Definition: types.h:120
void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *texture, HWND window, RECT *rect)
Definition: texture.c:69
static unsigned int wined3d_texture_get_level_height(const struct wined3d_texture *texture, unsigned int level)
#define GL_RED
Definition: gl.h:480
static void wined3d_texture_unload_gl_texture(struct wined3d_texture *texture)
Definition: texture.c:661
#define GL_ONE
Definition: gl.h:375
#define WINED3DUSAGE_OVERLAY
Definition: wined3d.h:930
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
static void wined3d_texture_prepare_rb(struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info, BOOL multisample)
Definition: texture.c:1763
GLenum wined3d_texture_get_gl_buffer(const struct wined3d_texture *texture)
Definition: texture.c:91
static void cube_coords_float(const RECT *r, UINT w, UINT h, struct wined3d_rect_f *f)
Definition: texture.c:144
static BOOL needs_separate_srgb_gl_texture(const struct wined3d_context *context, const struct wined3d_texture *texture)
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
Definition: gl.h:1795
unsigned int multisample_quality
Definition: wined3d.h:1756
GLuint renderbuffer
Definition: glext.h:6989
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
void wined3d_texture_invalidate_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, DWORD location)
Definition: texture.c:310
UINT left
Definition: wined3d.h:1840
#define WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS
Definition: wined3d.h:1562
struct wined3d_resource * resource
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
#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:2598
#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
void texture2d_get_blt_info(const struct wined3d_texture *texture, unsigned int sub_resource_idx, const RECT *rect, struct wined3d_blt_info *info)
Definition: texture.c:152
long x
Definition: polytest.cpp:48
#define RESOURCE_ALIGNMENT
Definition: http.c:6587
HRESULT CDECL wined3d_texture_set_overlay_position(struct wined3d_texture *texture, unsigned int sub_resource_idx, LONG x, LONG y)
Definition: texture.c:3170
struct wined3d_swapchain * swapchain
#define WINED3D_CKEY_SRC_BLT
Definition: wined3d.h:1336
struct wined3d_context ** contexts
HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT width, UINT height, enum wined3d_format_id format_id, enum wined3d_multisample_type multisample_type, UINT multisample_quality, void *mem, UINT pitch)
Definition: texture.c:1534
static unsigned int wined3d_texture_get_level_width(const struct wined3d_texture *texture, unsigned int level)
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf)
unsigned short w_source
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
unsigned int height
Definition: wined3d.h:1760
static void wined3d_texture_remove_buffer_object(struct wined3d_texture *texture, unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
Definition: texture.c:471
static void texture_resource_preload(struct wined3d_resource *resource)
Definition: texture.c:2155
unsigned int access
#define GL_FALSE
Definition: gl.h:173
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLAPI void GLAPIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data)
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:2947
#define WINED3DUSAGE_DYNAMIC
Definition: wined3d.h:916
UINT back
Definition: wined3d.h:1845
#define GL_NEAREST
Definition: gl.h:678
#define GL_ALPHA
Definition: gl.h:483
#define WINED3D_TEXTURE_POW2_MAT_IDENT
const struct wined3d_renderbuffer_entry * current_renderbuffer
HRESULT CDECL wined3d_texture_update_overlay(struct wined3d_texture *texture, unsigned int sub_resource_idx, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, DWORD flags)
Definition: texture.c:3193
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)
uint8_t entry
Definition: isohybrid.c:63
#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
GLintptr offset
Definition: glext.h:5920
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:335
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
Definition: list.h:96
#define GL_TEXTURE_SWIZZLE_RGBA
Definition: glext.h:2032
struct wined3d_vec3 texcoords[4]
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z
Definition: gl.h:1794
LONG top
Definition: windef.h:297
static unsigned int wined3d_texture_get_level_depth(const struct wined3d_texture *texture, unsigned int level)
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:3773
const char * debug_box(const struct wined3d_box *box)
Definition: utils.c:3881
#define WINED3D_LOCATION_BUFFER
struct wined3d_resource resource
HDC dc
Definition: cylfrac.c:34
void wined3d_cs_init_object(struct wined3d_cs *cs, void(*callback)(void *object), void *object)
Definition: cs.c:1912
#define WINED3DUSAGE_DEPTHSTENCIL
Definition: wined3d.h:909
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource)
Definition: cs.c:2000
#define CHAR_BIT
Definition: urlcache.c:57
#define WINED3D_RESOURCE_ACCESS_MAP_W
Definition: wined3d.h:58
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble * u
Definition: glfuncs.h:88
UINT front
Definition: wined3d.h:1844
DWORD color_space_low_value
Definition: wined3d.h:1980
#define WINED3D_TEXTURE_ASYNC_COLOR_KEY
static void wined3d_texture_destroy_object(void *object)
Definition: texture.c:1213
void context_invalidate_state(struct wined3d_context *context, DWORD state)
Definition: context.c:1638
static HRESULT texture_resource_sub_resource_unmap(struct wined3d_resource *resource, unsigned int sub_resource_idx)
Definition: texture.c:2383
void wined3d_cs_destroy_object(struct wined3d_cs *cs, void(*callback)(void *object), void *object)
Definition: cs.c:1907
void resource_unload(struct wined3d_resource *resource)
Definition: resource.c:247
LONG left
Definition: windef.h:296
enum wined3d_multisample_type multisample_type
Definition: wined3d.h:1755
static void wined3d_texture_cleanup(struct wined3d_texture *texture)
Definition: texture.c:838
void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint name)
Definition: context.c:2503
#define WINED3D_TEXTURE_COND_NP2
static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
Definition: texture.c:2104
UINT top
Definition: wined3d.h:1841
GLuint coords
Definition: glext.h:7368
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
HRESULT CDECL wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc)
Definition: texture.c:3436
LONG right
Definition: windef.h:298
#define GL_STREAM_DRAW
Definition: glext.h:347
static void wined3d_texture_unload(struct wined3d_resource *resource)
Definition: texture.c:2165
static void wined3d_texture_evict_sysmem(struct wined3d_texture *texture)
Definition: texture.c:260
unsigned int format_flags
BOOL wined3d_texture_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
Definition: texture.c:380
& rect
Definition: startmenu.cpp:1413
#define GL_UNPACK_ROW_LENGTH
Definition: gl.h:634
struct wined3d_resource *CDECL wined3d_texture_get_resource(struct wined3d_texture *texture)
Definition: texture.c:1248
void wined3d_texture_set_map_binding(struct wined3d_texture *texture, DWORD map_binding)
Definition: texture.c:513
GLint wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP+1]
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define WINED3D_TEXTURE_CREATE_GET_DC
Definition: wined3d.h:1561
const struct wined3d_format * format
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
struct wined3d * wined3d
unsigned int row_pitch
HRESULT CDECL wined3d_texture_get_overlay_position(const struct wined3d_texture *texture, unsigned int sub_resource_idx, LONG *x, LONG *y)
Definition: texture.c:3139
static void wined3d_resource_wait_idle(struct wined3d_resource *resource)
INT INT y
Definition: msvc.h:62
static void wined3d_texture_prepare_buffer_object(struct wined3d_texture *texture, unsigned int sub_resource_idx, const struct wined3d_gl_info *gl_info)
Definition: texture.c:1671
struct wined3d_state state
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)
const GLint const GLsizei GLsizei
Definition: dispatch.h:5271
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
D3DDDIFORMAT ddi_format
static BOOL texture1d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
Definition: texture.c:2470
#define GL_TEXTURE_CUBE_MAP_ARB
Definition: glext.h:1230
enum wined3d_format_id format
Definition: wined3d.h:1754
#define WINED3D_RESOURCE_ACCESS_CPU
Definition: wined3d.h:56
#define WARN_ON(c)
Definition: module.h:255
#define GL_TEXTURE_2D_MULTISAMPLE
Definition: glext.h:1939
#define WINED3D_TEXTURE_SRGB_ALLOCATED
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define WINED3D_TEXTURE_CREATE_DISCARD
Definition: wined3d.h:1559
#define GL_TEXTURE_RECTANGLE_ARB
Definition: glext.h:1614
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static void texture1d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, const struct wined3d_context *context, const struct wined3d_bo_address *data)
Definition: texture.c:2439
#define GL_TEXTURE_WRAP_R
Definition: gl.h:1518
static void create_dib(STGMEDIUM *med)
Definition: ole2.c:217
#define WINED3D_TEXTURE_IS_SRGB
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define WINED3D_TEXTURE_GENERATE_MIPMAPS
struct wined3d_texture::wined3d_texture_async async
unsigned int slice_pitch
Definition: wined3d.h:1835
#define GL_TEXTURE_1D
Definition: gl.h:644
const char * wined3d_debug_location(DWORD location)
Definition: utils.c:6306
enum wined3d_format_id dst_format
struct wined3d_texture::wined3d_overlay_info * overlay_info
#define WINED3D_TEXTURE_GET_DC_LENIENT
long LONG
Definition: pedump.c:60
wined3d_texture_filter_type
Definition: wined3d.h:692
Definition: devices.h:37
void wined3d_texture_get_memory(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_bo_address *data, DWORD locations)
Definition: texture.c:436
#define WINED3D_LOCATION_RB_MULTISAMPLE
#define GL_FRONT
Definition: gl.h:270
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X
Definition: gl.h:1790
#define GL_ZERO
Definition: gl.h:374
#define WINED3D_CKEY_SRC_OVERLAY
Definition: wined3d.h:1337
#define WINED3DFMT_FLAG_TEXTURE
static void gltexture_delete(struct wined3d_device *device, const struct wined3d_gl_info *gl_info, struct gl_texture *tex)
Definition: texture.c:521
static BOOL wined3d_resource_access_is_managed(unsigned int access)
#define FIXME(fmt,...)
Definition: debug.h:110
BOOL supported[WINED3D_GL_EXT_COUNT]
unsigned int idx
Definition: utils.c:41
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
Definition: gl.h:1793
#define ORM_BACKBUFFER
#define WINED3D_LOCATION_RB_RESOLVED
#define E_INVALIDARG
Definition: ddrawi.h:101
GLdouble GLdouble z
Definition: glext.h:5874
void wined3d_texture_load(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
Definition: texture.c:1262
const struct builtin_class_descr * desc
Definition: regcontrol.c:48
struct color_fixup_desc color_fixup
static GLenum wined3d_gl_min_mip_filter(enum wined3d_texture_filter_type min_filter, enum wined3d_texture_filter_type mip_filter)
enum wined3d_texture_filter_type mip_filter
Definition: wined3d.h:2022
#define GL_TEXTURE_3D
Definition: gl.h:1515
#define GL_PIXEL_UNPACK_BUFFER
Definition: glext.h:477
DWORD rev_tex_unit_map[MAX_GL_FRAGMENT_SAMPLERS+MAX_VERTEX_SAMPLERS]
smooth NULL
Definition: ftsmooth.c:416
struct wined3d_device * device
#define GL_TEXTURE_WRAP_T
Definition: gl.h:647
struct wined3d_adapter * adapter
#define WINED3D_LOCATION_DRAWABLE
#define WINEDDOVER_SHOW
Definition: wined3d.h:1404
#define WINED3D_TEXTURE_GET_DC
GLuint id
unsigned short z_source
DWORD CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod)
Definition: texture.c:1382
static void wined3d_texture_allocate_gl_immutable_storage(struct wined3d_texture *texture, GLenum gl_internal_format, const struct wined3d_gl_info *gl_info)
Definition: texture.c:620
unsigned int download_count
DWORD CDECL wined3d_texture_get_lod(const struct wined3d_texture *texture)
Definition: texture.c:1417
void context_release(struct wined3d_context *context)
Definition: context.c:1559
void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, enum wined3d_sampler_state state, DWORD value)
Definition: cs.c:1560
#define WINED3DUSAGE_LEGACY_CUBEMAP
Definition: wined3d.h:926
BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD dst_location)
Definition: surface.c:1794
void wined3d_texture_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
Definition: texture.c:1706
void wined3d_texture_set_swapchain(struct wined3d_texture *texture, struct wined3d_swapchain *swapchain)
Definition: texture.c:918
HRESULT CDECL wined3d_texture_create(struct wined3d_device *device, const struct wined3d_resource_desc *desc, UINT layer_count, UINT level_count, DWORD flags, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
Definition: texture.c:3326
unsigned int multisample_quality
Definition: wined3d.h:1769
static void texture3d_download_data(struct wined3d_texture *texture, unsigned int sub_resource_idx, const struct wined3d_context *context, const struct wined3d_bo_address *data)
Definition: texture.c:2915
#define GL_TEXTURE_MIN_FILTER
Definition: gl.h:649
#define STATE_GRAPHICS_SHADER_RESOURCE_BINDING
static BOOL wined3d_texture_use_pbo(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
Definition: texture.c:47
UINT right
Definition: wined3d.h:1842
static const struct wined3d_texture_ops texture1d_ops
Definition: texture.c:2569
static void wined3d_texture_create_dc(void *object)
Definition: texture.c:721
#define WINED3D_TEXTURE_DC_IN_USE
void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id)
Definition: context.c:1628
GLenum GLuint GLint GLint layer
Definition: glext.h:7007
#define GL_EXTCALL(f)
static void wined3d_texture_set_dirty(struct wined3d_texture *texture)
Definition: texture.c:305
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
HRESULT CDECL wined3d_texture_blt(struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, struct wined3d_texture *src_texture, unsigned int src_sub_resource_idx, const RECT *src_rect, DWORD flags, const struct wined3d_blt_fx *fx, enum wined3d_texture_filter_type filter)
Definition: texture.c:3087
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:3295
GLfloat f
Definition: glext.h:7540
#define WINED3D_MAP_DISCARD
Definition: wined3d.h:944
static BOOL texture3d_load_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD location)
Definition: texture.c:2978
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
BOOL texture2d_load_renderbuffer(struct wined3d_texture *texture, unsigned int sub_resource_idx, struct wined3d_context *context, DWORD dst_location)
Definition: surface.c:2037
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean flag
Definition: glfuncs.h:72
void wined3d_texture_validate_location(struct wined3d_texture *texture, unsigned int sub_resource_idx, DWORD location)
Definition: texture.c:286
#define GL_DECODE_EXT
Definition: glext.h:5290
#define WINED3D_LOCATION_USER_MEMORY
void wined3d_resource_update_draw_binding(struct wined3d_resource *resource)
Definition: resource.c:561
GLAPI void GLAPIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
r parent
Definition: btrfs.c:2659
if(!(yy_init))
Definition: macro.lex.yy.c:717
#define WINED3D_MAP_READ
Definition: wined3d.h:948
static const struct wined3d_texture_ops texture3d_ops
Definition: texture.c:3082
GLenum GLuint texture
Definition: glext.h:6295
#define GL_TEXTURE_COMPARE_MODE_ARB
Definition: glext.h:1371
LONG HRESULT
Definition: typedefs.h:77
#define WINED3D_TEXTURE_RGB_VALID
#define GL_TEXTURE_WRAP_S
Definition: gl.h:646
BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource)
Definition: resource.c:477
struct wined3d_cs * cs
const char * debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
Definition: utils.c:4480
#define WINED3DUSAGE_RENDERTARGET
Definition: wined3d.h:908
unsigned int width
Definition: wined3d.h:1759
#define WINED3D_RESOURCE_ACCESS_MAP_R
Definition: wined3d.h:57
GLAPI void GLAPIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data)
unsigned int UINT
Definition: ndis.h:50
const char * wine_dbgstr_rect(const RECT *rect)
#define WINED3D_OK
Definition: wined3d.h:37
static BOOL is_identity_fixup(struct color_fixup_desc fixup)
void(* upload)(const BYTE *src, BYTE *dst, unsigned int src_row_pitch, unsigned int src_slice_pitch, unsigned int dst_row_pitch, unsigned dst_slice_pitch, unsigned int width, unsigned int height, unsigned int depth)
#define for
Definition: utility.h:88
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT bottom
Definition: wined3d.h:1843
#define WINEDDERR_OVERLAYNOTVISIBLE
Definition: wined3d.h:53
float border_color[4]
Definition: wined3d.h:2019
UINT width
static DWORD wined3d_resource_access_from_location(DWORD location)
Definition: texture.c:119
struct wined3d_texture * texture
Definition: texture.c:35
#define WINED3DFMT_FLAG_GEN_MIPMAP
BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource)
Definition: resource.c:540
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define GL_NONE
Definition: gl.h:465
#define GL_TEXTURE_1D_ARRAY
Definition: glext.h:533
GLbitfield flags
Definition: glext.h:7161
#define GL_TEXTURE_2D_ARRAY
Definition: glext.h:535
#define WINED3D_MAP_NO_DIRTY_UPDATE
Definition: wined3d.h:946
void *CDECL wined3d_texture_get_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx)
Definition: texture.c:3264
static struct wined3d_texture * texture_from_resource(struct wined3d_resource *resource)
#define WINED3D_TEXTURE_NORMALIZED_COORDS
void wined3d_cs_emit_add_dirty_texture_region(struct wined3d_cs *cs, struct wined3d_texture *texture, unsigned int layer)
Definition: cs.c:2351
HRESULT CDECL wined3d_texture_add_dirty_region(struct wined3d_texture *texture, UINT layer, const struct wined3d_box *dirty_region)
Definition: texture.c:1865
unsigned int max_anisotropy
Definition: wined3d.h:2027
static void wined3d_texture_force_reload(struct wined3d_texture *texture)
Definition: texture.c:1690
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
int ret
static const struct wined3d_resource_ops texture_resource_ops
Definition: texture.c:2427
GLenum const GLvoid * addr
Definition: glext.h:9621
enum wined3d_texture_filter_type min_filter
Definition: wined3d.h:2021
#define InterlockedDecrement
Definition: armddk.h:52
#define WINED3D_MAP_WRITE
Definition: wined3d.h:947
#define WINED3D_LOCATION_SYSMEM
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y
Definition: gl.h:1792
void wined3d_texture_bind_and_dirtify(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
Definition: texture.c:1064
#define GL_BLUE
Definition: gl.h:482
#define WINED3D_TEXTURE_DISCARD
struct wined3d_sampler_desc sampler_desc
enum wined3d_format_id id
static struct gl_texture * wined3d_texture_get_gl_texture(struct wined3d_texture *texture, BOOL srgb)
static int state
Definition: maze.c:121
void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture, WORD flags, const struct wined3d_color_key *color_key)
Definition: cs.c:1679
enum wined3d_resource_type resource_type
Definition: wined3d.h:1753
static void wined3d_texture_get_level_box(const struct wined3d_texture *texture, unsigned int level, struct wined3d_box *box)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static unsigned int wined3d_texture_get_level_pow2_height(const struct wined3d_texture *texture, unsigned int level)
unsigned char BYTE
Definition: mem.h:68
GLsizei const GLint * locations
Definition: glext.h:10542
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigned int alignment, unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch)
Definition: utils.c:3818
ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture)
Definition: texture.c:1190
const struct wined3d_device_parent_ops * ops
Definition: wined3d.h:2134
static IHTMLWindow2 * window
Definition: events.c:77
unsigned int usage
Definition: wined3d.h:1757
unsigned int pow2_height
#define STATE_COMPUTE_SHADER_RESOURCE_BINDING
#define WINED3D_UNMAPPED_STAGE
#define WINED3DFMT_FLAG_HEIGHT_SCALE
wined3d_multisample_type
Definition: wined3d.h:561
#define WINED3D_TEXTURE_RGB_ALLOCATED
enum wined3d_texture_filter_type mag_filter
Definition: wined3d.h:2020
#define WINED3D_RESOURCE_ACCESS_GPU
Definition: wined3d.h:55
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
const struct wined3d_parent_ops * parent_ops
#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY
Definition: glext.h:1941
#define location(file, line)
Definition: kmtest.h:18
unsigned char surface_alignment
struct wined3d_texture::wined3d_texture_sub_resource sub_resources[1]
unsigned int slice_pitch
#define STATE_SAMPLER(num)
wined3d_format_id
Definition: wined3d.h:105
#define ERR(fmt,...)
Definition: debug.h:109
static ULONG texture_resource_incref(struct wined3d_resource *resource)
Definition: texture.c:2145
struct wined3d_context * context_acquire(const struct wined3d_device *device, struct wined3d_texture *texture, unsigned int sub_resource_idx)
Definition: context.c:4218
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
static void wined3d_texture_update_map_binding(struct wined3d_texture *texture)
Definition: texture.c:486
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
#define WINEDDERR_NOTLOCKED
Definition: wined3d.h:50
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
enum wined3d_texture_address address_u
Definition: wined3d.h:2016
#define WINED3D_QUIRK_FBO_TEX_UPDATE
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X
Definition: gl.h:1791
#define WINED3D_TEXTURE_CONVERTED
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
#define InterlockedIncrement
Definition: armddk.h:53
HRESULT CDECL wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc)
Definition: texture.c:3484
unsigned int GLuint
Definition: