]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_sampler_state.cpp
Initial vogl checkin
[vogl] / src / voglcommon / vogl_sampler_state.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 // File: vogl_sampler_state.cpp
27 #include "vogl_common.h"
28 #include "vogl_sampler_state.h"
29
30 vogl_sampler_state::vogl_sampler_state()
31     : m_is_valid(false)
32 {
33     VOGL_FUNC_TRACER
34 }
35
36 vogl_sampler_state::~vogl_sampler_state()
37 {
38     VOGL_FUNC_TRACER
39 }
40
41 bool vogl_sampler_state::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target)
42 {
43     VOGL_FUNC_TRACER
44
45     VOGL_NOTE_UNUSED(remapper);
46     VOGL_CHECK_GL_ERROR;
47     (void)target;
48
49     clear();
50
51     VOGL_ASSERT(handle <= cUINT32_MAX);
52
53     m_snapshot_handle = static_cast<uint32>(handle);
54
55     bool any_gl_errors = false;
56
57 #define GET_INT(pname)                                                            \
58     do                                                                            \
59     {                                                                             \
60         int values[4] = { 0, 0, 0, 0 };                                           \
61         GL_ENTRYPOINT(glGetSamplerParameteriv)(m_snapshot_handle, pname, values); \
62         if (vogl_check_gl_error())                                                 \
63             any_gl_errors = true;                                                 \
64         m_params.insert(pname, 0, values, sizeof(values[0]));                     \
65     } while (0)
66 #define GET_FLOAT(pname)                                                          \
67     do                                                                            \
68     {                                                                             \
69         float values[4] = { 0, 0, 0, 0 };                                         \
70         GL_ENTRYPOINT(glGetSamplerParameterfv)(m_snapshot_handle, pname, values); \
71         if (vogl_check_gl_error())                                                 \
72             any_gl_errors = true;                                                 \
73         m_params.insert(pname, 0, values, sizeof(values[0]));                     \
74     } while (0)
75
76     GET_INT(GL_TEXTURE_MAG_FILTER);
77     GET_INT(GL_TEXTURE_MIN_FILTER);
78     GET_FLOAT(GL_TEXTURE_MIN_LOD);
79     GET_FLOAT(GL_TEXTURE_MAX_LOD);
80     GET_INT(GL_TEXTURE_WRAP_S);
81     GET_INT(GL_TEXTURE_WRAP_T);
82     GET_INT(GL_TEXTURE_WRAP_R);
83     GET_FLOAT(GL_TEXTURE_BORDER_COLOR);
84     GET_INT(GL_TEXTURE_COMPARE_MODE);
85     GET_INT(GL_TEXTURE_COMPARE_FUNC);
86
87     if (context_info.supports_extension("GL_EXT_texture_filter_anisotropic"))
88     {
89         GET_FLOAT(GL_TEXTURE_MAX_ANISOTROPY_EXT);
90     }
91
92     if (context_info.supports_extension("GL_EXT_texture_sRGB_decode"))
93     {
94         GET_INT(GL_TEXTURE_SRGB_DECODE_EXT);
95     }
96
97 #undef GET_INT
98 #undef GET_FLOAT
99
100     if (any_gl_errors)
101     {
102         clear();
103
104         vogl_error_printf("%s: GL error while enumerating sampler %" PRIu64 "'s' params\n", VOGL_METHOD_NAME, (uint64_t)handle);
105         return false;
106     }
107
108     m_is_valid = true;
109
110     return true;
111 }
112
113 bool vogl_sampler_state::set_sampler_parameter(GLuint handle, GLenum pname) const
114 {
115     VOGL_FUNC_TRACER
116
117     const vogl_state_data *pData = m_params.find(pname);
118     if (!pData)
119         return false;
120
121     enum
122     {
123         cMaxElements = 16
124     };
125     if (pData->get_num_elements() > cMaxElements)
126     {
127         VOGL_ASSERT_ALWAYS;
128         return false;
129     }
130
131     if ((pData->get_data_type() == cSTFloat) || (pData->get_data_type() == cSTDouble))
132     {
133         float fvals[cMaxElements];
134         pData->get_float(fvals);
135         if (pData->get_num_elements() == 1)
136             GL_ENTRYPOINT(glSamplerParameterf)(handle, pname, fvals[0]);
137         else
138             GL_ENTRYPOINT(glSamplerParameterfv)(handle, pname, fvals);
139     }
140     else
141     {
142         int ivals[cMaxElements];
143         pData->get_int(ivals);
144         if (pData->get_num_elements() == 1)
145             GL_ENTRYPOINT(glSamplerParameteri)(handle, pname, ivals[0]);
146         else
147             GL_ENTRYPOINT(glSamplerParameteriv)(handle, pname, ivals);
148     }
149
150     return !vogl_check_gl_error();
151 }
152
153 bool vogl_sampler_state::restore(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 &handle) const
154 {
155     VOGL_FUNC_TRACER
156
157     if (!m_is_valid)
158         return false;
159
160     VOGL_CHECK_GL_ERROR;
161
162     if (!handle)
163     {
164         GLuint handle32 = 0;
165         GL_ENTRYPOINT(glGenSamplers)(1, &handle32);
166         if ((vogl_check_gl_error()) || (!handle32))
167             return false;
168         handle = handle32;
169
170         remapper.declare_handle(VOGL_NAMESPACE_SAMPLERS, m_snapshot_handle, handle, GL_NONE);
171         VOGL_ASSERT(remapper.remap_handle(VOGL_NAMESPACE_SAMPLERS, m_snapshot_handle) == handle);
172     }
173
174     bool any_failures = false;
175
176 #define SET_INT(pname)                                                  \
177     do                                                                  \
178     {                                                                   \
179         if (!set_sampler_parameter(static_cast<GLuint>(handle), pname)) \
180             any_failures = true;                                        \
181     } while (0)
182 #define SET_FLOAT(pname)                                                \
183     do                                                                  \
184     {                                                                   \
185         if (!set_sampler_parameter(static_cast<GLuint>(handle), pname)) \
186             any_failures = true;                                        \
187     } while (0)
188
189     SET_INT(GL_TEXTURE_MAG_FILTER);
190     SET_INT(GL_TEXTURE_MIN_FILTER);
191     SET_FLOAT(GL_TEXTURE_MIN_LOD);
192     SET_FLOAT(GL_TEXTURE_MAX_LOD);
193     SET_INT(GL_TEXTURE_WRAP_S);
194     SET_INT(GL_TEXTURE_WRAP_T);
195     SET_INT(GL_TEXTURE_WRAP_R);
196     SET_FLOAT(GL_TEXTURE_BORDER_COLOR);
197     SET_INT(GL_TEXTURE_COMPARE_MODE);
198     SET_INT(GL_TEXTURE_COMPARE_FUNC);
199
200     if (context_info.supports_extension("GL_EXT_texture_filter_anisotropic"))
201     {
202         SET_FLOAT(GL_TEXTURE_MAX_ANISOTROPY_EXT);
203     }
204
205     if (context_info.supports_extension("GL_EXT_texture_sRGB_decode"))
206     {
207         SET_INT(GL_TEXTURE_SRGB_DECODE_EXT);
208     }
209
210     if (any_failures)
211     {
212         vogl_warning_printf("%s: One or more sampler params could not be set on trace sampler %u, replay sampler %" PRIu64 "\n", VOGL_METHOD_NAME,
213                            m_snapshot_handle, (uint64_t)handle);
214     }
215
216     return true;
217 }
218
219 bool vogl_sampler_state::remap_handles(vogl_handle_remapper &remapper)
220 {
221     VOGL_FUNC_TRACER
222
223     if (!m_is_valid)
224         return false;
225
226     m_snapshot_handle = static_cast<GLuint>(remapper.remap_handle(VOGL_NAMESPACE_SAMPLERS, m_snapshot_handle));
227
228     return true;
229 }
230
231 void vogl_sampler_state::clear()
232 {
233     VOGL_FUNC_TRACER
234
235     m_snapshot_handle = 0;
236     m_params.clear();
237     m_is_valid = false;
238 }
239
240 bool vogl_sampler_state::serialize(json_node &node, vogl_blob_manager &blob_manager) const
241 {
242     VOGL_FUNC_TRACER
243
244     if (!m_is_valid)
245         return false;
246
247     node.add_key_value("handle", m_snapshot_handle);
248
249     return m_params.serialize(node.add_object("params"), blob_manager);
250 }
251
252 bool vogl_sampler_state::deserialize(const json_node &node, const vogl_blob_manager &blob_manager)
253 {
254     VOGL_FUNC_TRACER
255
256     clear();
257
258     m_snapshot_handle = node.value_as_uint32("handle");
259
260     const json_node *pParams_node = node.find_child_object("params");
261     if ((!pParams_node) || (!m_params.deserialize(*pParams_node, blob_manager)))
262     {
263         clear();
264         return false;
265     }
266
267     m_is_valid = true;
268
269     return true;
270 }
271
272 bool vogl_sampler_state::compare_restorable_state(const vogl_gl_object_state &rhs_obj) const
273 {
274     VOGL_FUNC_TRACER
275
276     if ((!m_is_valid) || (!rhs_obj.is_valid()))
277         return false;
278
279     if (rhs_obj.get_type() != cGLSTSampler)
280         return false;
281
282     const vogl_sampler_state &rhs = static_cast<const vogl_sampler_state &>(rhs_obj);
283
284     if (this == &rhs)
285         return true;
286
287     return m_params == rhs.m_params;
288 }