2 * Copyright 2012, 2015 Henri Verbeet for CodeWeavers
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.
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.
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
21 #include "wine/port.h"
23 #include "wined3d_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
27 ULONG CDECL
wined3d_sampler_incref(struct wined3d_sampler
*sampler
)
29 ULONG refcount
= InterlockedIncrement(&sampler
->refcount
);
31 TRACE("%p increasing refcount to %u.\n", sampler
, refcount
);
36 ULONG CDECL
wined3d_sampler_decref(struct wined3d_sampler
*sampler
)
38 ULONG refcount
= InterlockedDecrement(&sampler
->refcount
);
39 const struct wined3d_gl_info
*gl_info
;
40 struct wined3d_context
*context
;
42 TRACE("%p decreasing refcount to %u.\n", sampler
, refcount
);
46 context
= context_acquire(sampler
->device
, NULL
);
47 gl_info
= context
->gl_info
;
48 GL_EXTCALL(glDeleteSamplers(1, &sampler
->name
));
49 context_release(context
);
51 HeapFree(GetProcessHeap(), 0, sampler
);
57 void * CDECL
wined3d_sampler_get_parent(const struct wined3d_sampler
*sampler
)
59 TRACE("sampler %p.\n", sampler
);
61 return sampler
->parent
;
64 static void wined3d_sampler_init(struct wined3d_sampler
*sampler
, struct wined3d_device
*device
,
65 const struct wined3d_sampler_desc
*desc
, void *parent
)
67 const struct wined3d_gl_info
*gl_info
;
68 struct wined3d_context
*context
;
70 sampler
->refcount
= 1;
71 sampler
->device
= device
;
72 sampler
->parent
= parent
;
73 sampler
->desc
= *desc
;
75 context
= context_acquire(device
, NULL
);
76 gl_info
= context
->gl_info
;
78 GL_EXTCALL(glGenSamplers(1, &sampler
->name
));
79 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_WRAP_S
,
80 gl_info
->wrap_lookup
[desc
->address_u
- WINED3D_TADDRESS_WRAP
]));
81 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_WRAP_T
,
82 gl_info
->wrap_lookup
[desc
->address_v
- WINED3D_TADDRESS_WRAP
]));
83 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_WRAP_R
,
84 gl_info
->wrap_lookup
[desc
->address_w
- WINED3D_TADDRESS_WRAP
]));
85 GL_EXTCALL(glSamplerParameterfv(sampler
->name
, GL_TEXTURE_BORDER_COLOR
, &desc
->border_color
[0]));
86 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_MAG_FILTER
,
87 wined3d_gl_mag_filter(desc
->mag_filter
)));
88 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_MIN_FILTER
,
89 wined3d_gl_min_mip_filter(desc
->min_filter
, desc
->mip_filter
)));
90 GL_EXTCALL(glSamplerParameterf(sampler
->name
, GL_TEXTURE_LOD_BIAS
, desc
->lod_bias
));
91 GL_EXTCALL(glSamplerParameterf(sampler
->name
, GL_TEXTURE_MIN_LOD
, desc
->min_lod
));
92 GL_EXTCALL(glSamplerParameterf(sampler
->name
, GL_TEXTURE_MAX_LOD
, desc
->max_lod
));
93 if (gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
])
94 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_MAX_ANISOTROPY_EXT
, desc
->max_anisotropy
));
96 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_COMPARE_MODE
, GL_COMPARE_R_TO_TEXTURE
));
97 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_COMPARE_FUNC
,
98 wined3d_gl_compare_func(desc
->comparison_func
)));
99 if ((context
->d3d_info
->wined3d_creation_flags
& WINED3D_SRGB_READ_WRITE_CONTROL
)
100 && gl_info
->supported
[EXT_TEXTURE_SRGB_DECODE
] && !desc
->srgb_decode
)
101 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_SRGB_DECODE_EXT
, GL_SKIP_DECODE_EXT
));
102 checkGLcall("sampler creation");
104 TRACE("Created sampler %u.\n", sampler
->name
);
106 context_release(context
);
109 HRESULT CDECL
wined3d_sampler_create(struct wined3d_device
*device
, const struct wined3d_sampler_desc
*desc
,
110 void *parent
, struct wined3d_sampler
**sampler
)
112 struct wined3d_sampler
*object
;
114 TRACE("device %p, desc %p, parent %p, sampler %p.\n", device
, desc
, parent
, sampler
);
116 if (!device
->adapter
->gl_info
.supported
[ARB_SAMPLER_OBJECTS
])
117 return WINED3DERR_INVALIDCALL
;
119 if (desc
->address_u
< WINED3D_TADDRESS_WRAP
|| desc
->address_u
> WINED3D_TADDRESS_MIRROR_ONCE
120 || desc
->address_v
< WINED3D_TADDRESS_WRAP
|| desc
->address_v
> WINED3D_TADDRESS_MIRROR_ONCE
121 || desc
->address_w
< WINED3D_TADDRESS_WRAP
|| desc
->address_w
> WINED3D_TADDRESS_MIRROR_ONCE
)
122 return WINED3DERR_INVALIDCALL
;
124 if (desc
->mag_filter
< WINED3D_TEXF_POINT
|| desc
->mag_filter
> WINED3D_TEXF_LINEAR
125 || desc
->min_filter
< WINED3D_TEXF_POINT
|| desc
->min_filter
> WINED3D_TEXF_LINEAR
126 || desc
->mip_filter
> WINED3D_TEXF_LINEAR
)
127 return WINED3DERR_INVALIDCALL
;
129 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
130 return E_OUTOFMEMORY
;
132 wined3d_sampler_init(object
, device
, desc
, parent
);
134 TRACE("Created sampler %p.\n", object
);