1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 **************************************************************************/
26 // File: vogl_sampler_state.cpp
27 #include "vogl_common.h"
28 #include "vogl_sampler_state.h"
30 vogl_sampler_state::vogl_sampler_state()
36 vogl_sampler_state::~vogl_sampler_state()
41 bool vogl_sampler_state::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target)
45 VOGL_NOTE_UNUSED(remapper);
51 VOGL_ASSERT(handle <= cUINT32_MAX);
53 m_snapshot_handle = static_cast<uint32>(handle);
55 bool any_gl_errors = false;
57 #define GET_INT(pname) \
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])); \
66 #define GET_FLOAT(pname) \
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])); \
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);
87 if (context_info.supports_extension("GL_EXT_texture_filter_anisotropic"))
89 GET_FLOAT(GL_TEXTURE_MAX_ANISOTROPY_EXT);
92 if (context_info.supports_extension("GL_EXT_texture_sRGB_decode"))
94 GET_INT(GL_TEXTURE_SRGB_DECODE_EXT);
104 vogl_error_printf("%s: GL error while enumerating sampler %" PRIu64 "'s' params\n", VOGL_METHOD_NAME, (uint64_t)handle);
113 bool vogl_sampler_state::set_sampler_parameter(GLuint handle, GLenum pname) const
117 const vogl_state_data *pData = m_params.find(pname);
125 if (pData->get_num_elements() > cMaxElements)
131 if ((pData->get_data_type() == cSTFloat) || (pData->get_data_type() == cSTDouble))
133 float fvals[cMaxElements];
134 pData->get_float(fvals);
135 if (pData->get_num_elements() == 1)
136 GL_ENTRYPOINT(glSamplerParameterf)(handle, pname, fvals[0]);
138 GL_ENTRYPOINT(glSamplerParameterfv)(handle, pname, fvals);
142 int ivals[cMaxElements];
143 pData->get_int(ivals);
144 if (pData->get_num_elements() == 1)
145 GL_ENTRYPOINT(glSamplerParameteri)(handle, pname, ivals[0]);
147 GL_ENTRYPOINT(glSamplerParameteriv)(handle, pname, ivals);
150 return !vogl_check_gl_error();
153 bool vogl_sampler_state::restore(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 &handle) const
165 GL_ENTRYPOINT(glGenSamplers)(1, &handle32);
166 if ((vogl_check_gl_error()) || (!handle32))
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);
174 bool any_failures = false;
176 #define SET_INT(pname) \
179 if (!set_sampler_parameter(static_cast<GLuint>(handle), pname)) \
180 any_failures = true; \
182 #define SET_FLOAT(pname) \
185 if (!set_sampler_parameter(static_cast<GLuint>(handle), pname)) \
186 any_failures = true; \
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);
200 if (context_info.supports_extension("GL_EXT_texture_filter_anisotropic"))
202 SET_FLOAT(GL_TEXTURE_MAX_ANISOTROPY_EXT);
205 if (context_info.supports_extension("GL_EXT_texture_sRGB_decode"))
207 SET_INT(GL_TEXTURE_SRGB_DECODE_EXT);
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);
219 bool vogl_sampler_state::remap_handles(vogl_handle_remapper &remapper)
226 m_snapshot_handle = static_cast<GLuint>(remapper.remap_handle(VOGL_NAMESPACE_SAMPLERS, m_snapshot_handle));
231 void vogl_sampler_state::clear()
235 m_snapshot_handle = 0;
240 bool vogl_sampler_state::serialize(json_node &node, vogl_blob_manager &blob_manager) const
247 node.add_key_value("handle", m_snapshot_handle);
249 return m_params.serialize(node.add_object("params"), blob_manager);
252 bool vogl_sampler_state::deserialize(const json_node &node, const vogl_blob_manager &blob_manager)
258 m_snapshot_handle = node.value_as_uint32("handle");
260 const json_node *pParams_node = node.find_child_object("params");
261 if ((!pParams_node) || (!m_params.deserialize(*pParams_node, blob_manager)))
272 bool vogl_sampler_state::compare_restorable_state(const vogl_gl_object_state &rhs_obj) const
276 if ((!m_is_valid) || (!rhs_obj.is_valid()))
279 if (rhs_obj.get_type() != cGLSTSampler)
282 const vogl_sampler_state &rhs = static_cast<const vogl_sampler_state &>(rhs_obj);
287 return m_params == rhs.m_params;