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 static void wined3d_sampler_destroy_object(void *object
)
38 struct wined3d_sampler
*sampler
= object
;
39 const struct wined3d_gl_info
*gl_info
;
40 struct wined3d_context
*context
;
42 context
= context_acquire(sampler
->device
, NULL
);
43 gl_info
= context
->gl_info
;
44 GL_EXTCALL(glDeleteSamplers(1, &sampler
->name
));
45 context_release(context
);
47 HeapFree(GetProcessHeap(), 0, sampler
);
50 ULONG CDECL
wined3d_sampler_decref(struct wined3d_sampler
*sampler
)
52 ULONG refcount
= InterlockedDecrement(&sampler
->refcount
);
54 TRACE("%p decreasing refcount to %u.\n", sampler
, refcount
);
57 wined3d_cs_emit_destroy_object(sampler
->device
->cs
, wined3d_sampler_destroy_object
, sampler
);
62 void * CDECL
wined3d_sampler_get_parent(const struct wined3d_sampler
*sampler
)
64 TRACE("sampler %p.\n", sampler
);
66 return sampler
->parent
;
69 static void wined3d_sampler_init(struct wined3d_sampler
*sampler
, struct wined3d_device
*device
,
70 const struct wined3d_sampler_desc
*desc
, void *parent
)
72 const struct wined3d_gl_info
*gl_info
;
73 struct wined3d_context
*context
;
75 sampler
->refcount
= 1;
76 sampler
->device
= device
;
77 sampler
->parent
= parent
;
78 sampler
->desc
= *desc
;
80 context
= context_acquire(device
, NULL
);
81 gl_info
= context
->gl_info
;
83 GL_EXTCALL(glGenSamplers(1, &sampler
->name
));
84 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_WRAP_S
,
85 gl_info
->wrap_lookup
[desc
->address_u
- WINED3D_TADDRESS_WRAP
]));
86 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_WRAP_T
,
87 gl_info
->wrap_lookup
[desc
->address_v
- WINED3D_TADDRESS_WRAP
]));
88 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_WRAP_R
,
89 gl_info
->wrap_lookup
[desc
->address_w
- WINED3D_TADDRESS_WRAP
]));
90 GL_EXTCALL(glSamplerParameterfv(sampler
->name
, GL_TEXTURE_BORDER_COLOR
, &desc
->border_color
[0]));
91 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_MAG_FILTER
,
92 wined3d_gl_mag_filter(desc
->mag_filter
)));
93 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_MIN_FILTER
,
94 wined3d_gl_min_mip_filter(desc
->min_filter
, desc
->mip_filter
)));
95 GL_EXTCALL(glSamplerParameterf(sampler
->name
, GL_TEXTURE_LOD_BIAS
, desc
->lod_bias
));
96 GL_EXTCALL(glSamplerParameterf(sampler
->name
, GL_TEXTURE_MIN_LOD
, desc
->min_lod
));
97 GL_EXTCALL(glSamplerParameterf(sampler
->name
, GL_TEXTURE_MAX_LOD
, desc
->max_lod
));
98 if (gl_info
->supported
[EXT_TEXTURE_FILTER_ANISOTROPIC
])
99 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_MAX_ANISOTROPY_EXT
, desc
->max_anisotropy
));
101 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_COMPARE_MODE
, GL_COMPARE_R_TO_TEXTURE
));
102 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_COMPARE_FUNC
,
103 wined3d_gl_compare_func(desc
->comparison_func
)));
104 if ((context
->d3d_info
->wined3d_creation_flags
& WINED3D_SRGB_READ_WRITE_CONTROL
)
105 && gl_info
->supported
[EXT_TEXTURE_SRGB_DECODE
] && !desc
->srgb_decode
)
106 GL_EXTCALL(glSamplerParameteri(sampler
->name
, GL_TEXTURE_SRGB_DECODE_EXT
, GL_SKIP_DECODE_EXT
));
107 checkGLcall("sampler creation");
109 TRACE("Created sampler %u.\n", sampler
->name
);
111 context_release(context
);
114 HRESULT CDECL
wined3d_sampler_create(struct wined3d_device
*device
, const struct wined3d_sampler_desc
*desc
,
115 void *parent
, struct wined3d_sampler
**sampler
)
117 struct wined3d_sampler
*object
;
119 TRACE("device %p, desc %p, parent %p, sampler %p.\n", device
, desc
, parent
, sampler
);
121 if (!device
->adapter
->gl_info
.supported
[ARB_SAMPLER_OBJECTS
])
122 return WINED3DERR_INVALIDCALL
;
124 if (desc
->address_u
< WINED3D_TADDRESS_WRAP
|| desc
->address_u
> WINED3D_TADDRESS_MIRROR_ONCE
125 || desc
->address_v
< WINED3D_TADDRESS_WRAP
|| desc
->address_v
> WINED3D_TADDRESS_MIRROR_ONCE
126 || desc
->address_w
< WINED3D_TADDRESS_WRAP
|| desc
->address_w
> WINED3D_TADDRESS_MIRROR_ONCE
)
127 return WINED3DERR_INVALIDCALL
;
129 if (desc
->mag_filter
< WINED3D_TEXF_POINT
|| desc
->mag_filter
> WINED3D_TEXF_LINEAR
130 || desc
->min_filter
< WINED3D_TEXF_POINT
|| desc
->min_filter
> WINED3D_TEXF_LINEAR
131 || desc
->mip_filter
> WINED3D_TEXF_LINEAR
)
132 return WINED3DERR_INVALIDCALL
;
134 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
135 return E_OUTOFMEMORY
;
137 wined3d_sampler_init(object
, device
, desc
, parent
);
139 TRACE("Created sampler %p.\n", object
);