ReactOS  0.4.14-dev-98-gb0d4763
sampler.c
Go to the documentation of this file.
1 /*
2  * Copyright 2012, 2015 Henri Verbeet for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  */
19 
20 #include "config.h"
21 #include "wine/port.h"
22 
23 #include "wined3d_private.h"
24 
26 
28 {
29  ULONG refcount = InterlockedIncrement(&sampler->refcount);
30 
31  TRACE("%p increasing refcount to %u.\n", sampler, refcount);
32 
33  return refcount;
34 }
35 
36 static void wined3d_sampler_destroy_object(void *object)
37 {
38  struct wined3d_sampler *sampler = object;
39  const struct wined3d_gl_info *gl_info;
40  struct wined3d_context *context;
41 
42  if (sampler->name)
43  {
44  context = context_acquire(sampler->device, NULL, 0);
45  gl_info = context->gl_info;
46  GL_EXTCALL(glDeleteSamplers(1, &sampler->name));
48  }
49 
51 }
52 
54 {
55  ULONG refcount = InterlockedDecrement(&sampler->refcount);
56 
57  TRACE("%p decreasing refcount to %u.\n", sampler, refcount);
58 
59  if (!refcount)
60  {
61  sampler->parent_ops->wined3d_object_destroyed(sampler->parent);
63  }
64 
65  return refcount;
66 }
67 
69 {
70  TRACE("sampler %p.\n", sampler);
71 
72  return sampler->parent;
73 }
74 
75 static void wined3d_sampler_cs_init(void *object)
76 {
77  struct wined3d_sampler *sampler = object;
78  const struct wined3d_sampler_desc *desc;
79  const struct wined3d_gl_info *gl_info;
80  struct wined3d_context *context;
81 
82  context = context_acquire(sampler->device, NULL, 0);
83  gl_info = context->gl_info;
84 
85  desc = &sampler->desc;
86  GL_EXTCALL(glGenSamplers(1, &sampler->name));
87  GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_S,
88  gl_info->wrap_lookup[desc->address_u - WINED3D_TADDRESS_WRAP]));
89  GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_T,
90  gl_info->wrap_lookup[desc->address_v - WINED3D_TADDRESS_WRAP]));
91  GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_WRAP_R,
92  gl_info->wrap_lookup[desc->address_w - WINED3D_TADDRESS_WRAP]));
93  GL_EXTCALL(glSamplerParameterfv(sampler->name, GL_TEXTURE_BORDER_COLOR, &desc->border_color[0]));
94  GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAG_FILTER,
95  wined3d_gl_mag_filter(desc->mag_filter)));
96  GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MIN_FILTER,
97  wined3d_gl_min_mip_filter(desc->min_filter, desc->mip_filter)));
98  GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_LOD_BIAS, desc->lod_bias));
99  GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MIN_LOD, desc->min_lod));
100  GL_EXTCALL(glSamplerParameterf(sampler->name, GL_TEXTURE_MAX_LOD, desc->max_lod));
101  if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC])
102  GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_MAX_ANISOTROPY, desc->max_anisotropy));
103  if (desc->compare)
105  GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_COMPARE_FUNC,
106  wined3d_gl_compare_func(desc->comparison_func)));
107  if ((context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)
108  && gl_info->supported[EXT_TEXTURE_SRGB_DECODE] && !desc->srgb_decode)
109  GL_EXTCALL(glSamplerParameteri(sampler->name, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT));
110  checkGLcall("sampler creation");
111 
112  TRACE("Created sampler %u.\n", sampler->name);
113 
115 }
116 
118  const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
119 {
120  sampler->refcount = 1;
121  sampler->device = device;
122  sampler->parent = parent;
123  sampler->parent_ops = parent_ops;
124  sampler->desc = *desc;
125 
126  if (device->adapter->gl_info.supported[ARB_SAMPLER_OBJECTS])
128 }
129 
131  void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler)
132 {
133  struct wined3d_sampler *object;
134 
135  TRACE("device %p, desc %p, parent %p, sampler %p.\n", device, desc, parent, sampler);
136 
137  if (desc->address_u < WINED3D_TADDRESS_WRAP || desc->address_u > WINED3D_TADDRESS_MIRROR_ONCE
138  || desc->address_v < WINED3D_TADDRESS_WRAP || desc->address_v > WINED3D_TADDRESS_MIRROR_ONCE
139  || desc->address_w < WINED3D_TADDRESS_WRAP || desc->address_w > WINED3D_TADDRESS_MIRROR_ONCE)
140  return WINED3DERR_INVALIDCALL;
141 
142  if (desc->mag_filter < WINED3D_TEXF_POINT || desc->mag_filter > WINED3D_TEXF_LINEAR
143  || desc->min_filter < WINED3D_TEXF_POINT || desc->min_filter > WINED3D_TEXF_LINEAR
144  || desc->mip_filter > WINED3D_TEXF_LINEAR)
145  return WINED3DERR_INVALIDCALL;
146 
147  if (!(object = heap_alloc_zero(sizeof(*object))))
148  return E_OUTOFMEMORY;
149 
151 
152  TRACE("Created sampler %p.\n", object);
153  *sampler = object;
154 
155  return WINED3D_OK;
156 }
157 
159  const struct wined3d_sampler_desc *desc, const struct wined3d_gl_info *gl_info)
160 {
161  struct gl_texture *gl_tex;
162  unsigned int base_level;
163 
164  if (texture->flags & WINED3D_TEXTURE_COND_NP2)
165  base_level = 0;
166  else if (desc->mip_filter == WINED3D_TEXF_NONE)
167  base_level = texture->lod;
168  else
169  base_level = min(max(desc->mip_base_level, texture->lod), texture->level_count - 1);
170 
172  if (base_level != gl_tex->base_level)
173  {
174  /* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap
175  * (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest
176  * mipmap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL
177  * corresponds to GL_TEXTURE_BASE_LEVEL. */
178  gl_info->gl_ops.gl.p_glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, base_level);
179  gl_tex->base_level = base_level;
180  }
181 }
182 
183 /* This function relies on the correct texture being bound and loaded. */
185  struct wined3d_texture *texture, const struct wined3d_context *context)
186 {
187  const struct wined3d_gl_info *gl_info = context->gl_info;
188 
189  if (gl_info->supported[ARB_SAMPLER_OBJECTS])
190  {
191  GL_EXTCALL(glBindSampler(unit, sampler->name));
192  checkGLcall("bind sampler");
193  }
194  else if (texture)
195  {
197  }
198  else
199  {
200  ERR("Could not apply sampler state.\n");
201  }
202 
203  if (texture)
204  texture_apply_base_level(texture, &sampler->desc, gl_info);
205 }
#define WINED3DERR_INVALIDCALL
Definition: wined3d.h:48
#define max(a, b)
Definition: svc.c:63
#define GL_COMPARE_R_TO_TEXTURE
Definition: glext.h:326
static void wined3d_sampler_destroy_object(void *object)
Definition: sampler.c:36
struct opengl_funcs gl_ops
static void wined3d_sampler_init(struct wined3d_sampler *sampler, struct wined3d_device *device, const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
Definition: sampler.c:117
#define GL_TEXTURE_SRGB_DECODE_EXT
Definition: glext.h:5289
Definition: http.c:6587
#define GL_TEXTURE_LOD_BIAS
Definition: glext.h:295
const struct wined3d_parent_ops * parent_ops
void wined3d_sampler_bind(struct wined3d_sampler *sampler, unsigned int unit, struct wined3d_texture *texture, const struct wined3d_context *context)
Definition: sampler.c:184
static void texture_apply_base_level(struct wined3d_texture *texture, const struct wined3d_sampler_desc *desc, const struct wined3d_gl_info *gl_info)
Definition: sampler.c:158
static void wined3d_sampler_cs_init(void *object)
Definition: sampler.c:75
HRESULT CDECL wined3d_sampler_create(struct wined3d_device *device, const struct wined3d_sampler_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler)
Definition: sampler.c:130
void wined3d_cs_init_object(struct wined3d_cs *cs, void(*callback)(void *object), void *object)
Definition: cs.c:1890
#define GL_TEXTURE_MAX_LOD
Definition: gl.h:1502
void wined3d_cs_destroy_object(struct wined3d_cs *cs, void(*callback)(void *object), void *object)
Definition: cs.c:1885
void wined3d_texture_apply_sampler_desc(struct wined3d_texture *texture, const struct wined3d_sampler_desc *sampler_desc, const struct wined3d_context *context)
Definition: texture.c:896
#define WINED3D_TEXTURE_COND_NP2
#define GL_TEXTURE_WRAP_R
Definition: gl.h:1518
#define WINED3D_TEXTURE_IS_SRGB
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
Definition: devices.h:37
GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f)
Definition: state.c:345
BOOL supported[WINED3D_GL_EXT_COUNT]
png_const_structrp png_const_inforp int * unit
Definition: png.h:2161
const struct builtin_class_descr * desc
Definition: regcontrol.c:48
static GLenum wined3d_gl_min_mip_filter(enum wined3d_texture_filter_type min_filter, enum wined3d_texture_filter_type mip_filter)
smooth NULL
Definition: ftsmooth.c:416
#define GL_TEXTURE_WRAP_T
Definition: gl.h:647
void context_release(struct wined3d_context *context)
Definition: context.c:1571
#define GL_TEXTURE_MIN_FILTER
Definition: gl.h:649
void *CDECL wined3d_sampler_get_parent(const struct wined3d_sampler *sampler)
Definition: sampler.c:68
#define GL_EXTCALL(f)
#define TRACE(s)
Definition: solgame.cpp:4
r parent
Definition: btrfs.c:2897
GLenum GLuint texture
Definition: glext.h:6295
LONG HRESULT
Definition: typedefs.h:77
#define GL_TEXTURE_WRAP_S
Definition: gl.h:646
ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
Definition: sampler.c:53
#define WINED3D_OK
Definition: wined3d.h:37
struct wined3d_device * device
#define InterlockedDecrement
Definition: armddk.h:52
static struct gl_texture * wined3d_texture_get_gl_texture(struct wined3d_texture *texture, BOOL srgb)
#define ERR(fmt,...)
Definition: debug.h:109
struct wined3d_context * context_acquire(const struct wined3d_device *device, struct wined3d_texture *texture, unsigned int sub_resource_idx)
Definition: context.c:4242
#define InterlockedIncrement
Definition: armddk.h:53
#define GL_TEXTURE_COMPARE_MODE
Definition: glext.h:299
#define GL_TEXTURE_MAG_FILTER
Definition: gl.h:648
#define CDECL
Definition: compat.h:21
unsigned int base_level
#define GL_TEXTURE_MAX_ANISOTROPY
Definition: wgl.h:4357
#define checkGLcall(A)
#define min(a, b)
Definition: monoChain.cc:55
#define GL_TEXTURE_BORDER_COLOR
Definition: gl.h:656
static GLenum wined3d_gl_mag_filter(enum wined3d_texture_filter_type mag_filter)
unsigned int ULONG
Definition: retypes.h:1
#define WINED3D_SRGB_READ_WRITE_CONTROL
Definition: wined3d.h:1324
const struct wined3d_gl_info * gl_info
#define GL_TEXTURE_COMPARE_FUNC
Definition: glext.h:300
ULONG CDECL wined3d_sampler_incref(struct wined3d_sampler *sampler)
Definition: sampler.c:27
void * object
Definition: jmemsys.h:48
WINE_DEFAULT_DEBUG_CHANNEL(d3d)
#define GL_TEXTURE_MIN_LOD
Definition: gl.h:1501
#define GL_TEXTURE_BASE_LEVEL
Definition: gl.h:1503
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
GLuint sampler
Definition: glext.h:7283
#define GL_SKIP_DECODE_EXT
Definition: glext.h:5291