Commit d66ecf6d authored by Niklas Haas's avatar Niklas Haas

spirv: work around libshaderc locale dependence

Do this by explicitly clearing LC_NUMERIC before calling into
libshaderc. I'm not entirely sure whether libshaderc or glslang is to
blame here, but either way, as long as it works - I'm happy.

This is not that big of a deal performance-wise since shader compilation
is infrequent, and it also doesn't need messy global initialization
since we can just stuff the locale_t in with the struct priv.
parent 99c5d39e
#include "spirv.h"
/*
* This file is part of libplacebo.
*
* libplacebo is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* libplacebo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with libplacebo. If not, see <http://www.gnu.org/licenses/>.
*/
#define _XOPEN_SOURCE 700
#include <stdlib.h>
#include <locale.h>
#ifdef __APPLE__
# include <string.h>
# include <xlocale.h>
#endif
#include <shaderc/shaderc.h>
#include "spirv.h"
struct priv {
shaderc_compiler_t compiler;
shaderc_compile_options_t opts;
locale_t cloc;
};
static void shaderc_uninit(struct spirv_compiler *spirv)
......@@ -12,12 +39,18 @@ static void shaderc_uninit(struct spirv_compiler *spirv)
struct priv *p = spirv->priv;
shaderc_compile_options_release(p->opts);
shaderc_compiler_release(p->compiler);
freelocale(p->cloc);
TA_FREEP(&spirv->priv);
}
static bool shaderc_init(struct spirv_compiler *spirv)
{
struct priv *p = spirv->priv = talloc_zero(spirv, struct priv);
p->cloc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
if (!p->cloc) {
PL_FATAL(spirv, "Failed initializing C locale?!");
goto error;
}
p->compiler = shaderc_compiler_initialize();
if (!p->compiler)
......@@ -69,6 +102,10 @@ static bool shaderc_compile(struct spirv_compiler *spirv, void *tactx,
{
struct priv *p = spirv->priv;
// Switch to C locale to work around libshaderc bugs
locale_t oldloc = uselocale((locale_t) 0);
uselocale(p->cloc);
shaderc_compilation_result_t res = compile(p, type, glsl, false);
int errs = shaderc_result_get_num_errors(res),
warn = shaderc_result_get_num_warnings(res);
......@@ -113,6 +150,7 @@ static bool shaderc_compile(struct spirv_compiler *spirv, void *tactx,
}
shaderc_result_release(res);
uselocale(oldloc);
return success;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment