mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 03:52:22 +02:00
vo_gpu: d3d11: use the SPIRV-Cross C API directly
When the D3D11 backend was first written, SPIRV-Cross only had a C++ API and no guarantee of API or ABI stability, so instead of using SPIRV-Cross directly, mpv used an unofficial C wrapper called crossc. Now that KhronosGroup/SPIRV-Cross#611 is resolved, SPIRV-Cross has an official C API that can be used instead, so remove crossc and use SPIRV-Cross directly.
This commit is contained in:
parent
fbe267150d
commit
cc38035841
@ -11,7 +11,7 @@ export PYTHON=/usr/bin/python3
|
|||||||
"$PYTHON" waf configure \
|
"$PYTHON" waf configure \
|
||||||
--check-c-compiler=gcc \
|
--check-c-compiler=gcc \
|
||||||
--disable-egl-angle-lib \
|
--disable-egl-angle-lib \
|
||||||
--enable-crossc \
|
--enable-spirv-cross \
|
||||||
--enable-d3d-hwaccel \
|
--enable-d3d-hwaccel \
|
||||||
--enable-d3d11 \
|
--enable-d3d11 \
|
||||||
--enable-egl-angle \
|
--enable-egl-angle \
|
||||||
|
@ -62,10 +62,11 @@ pacman -Sc --noconfirm
|
|||||||
ninja install
|
ninja install
|
||||||
)
|
)
|
||||||
|
|
||||||
# Compile crossc
|
# Compile SPIRV-Cross
|
||||||
(
|
(
|
||||||
git clone --depth=1 https://github.com/rossy/crossc && cd crossc
|
git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Cross && cd SPIRV-Cross
|
||||||
git submodule update --init
|
|
||||||
|
|
||||||
make -j4 install prefix=$MINGW_PREFIX
|
mkdir build && cd build
|
||||||
|
cmake -GNinja -DSPIRV_CROSS_SHARED=ON -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX ..
|
||||||
|
ninja install
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <d3d11sdklayers.h>
|
#include <d3d11sdklayers.h>
|
||||||
#include <dxgi1_2.h>
|
#include <dxgi1_2.h>
|
||||||
#include <d3dcompiler.h>
|
#include <d3dcompiler.h>
|
||||||
#include <crossc.h>
|
#include <spirv_cross_c.h>
|
||||||
|
|
||||||
#include "common/msg.h"
|
#include "common/msg.h"
|
||||||
#include "osdep/io.h"
|
#include "osdep/io.h"
|
||||||
@ -1255,19 +1255,23 @@ static bool compile_glsl(struct ra *ra, enum glsl_shader type,
|
|||||||
struct ra_d3d11 *p = ra->priv;
|
struct ra_d3d11 *p = ra->priv;
|
||||||
struct spirv_compiler *spirv = p->spirv;
|
struct spirv_compiler *spirv = p->spirv;
|
||||||
void *ta_ctx = talloc_new(NULL);
|
void *ta_ctx = talloc_new(NULL);
|
||||||
crossc_compiler *cross = NULL;
|
spvc_result sc_res = SPVC_SUCCESS;
|
||||||
|
spvc_context sc_ctx = NULL;
|
||||||
|
spvc_parsed_ir sc_ir = NULL;
|
||||||
|
spvc_compiler sc_compiler = NULL;
|
||||||
|
spvc_compiler_options sc_opts = NULL;
|
||||||
const char *hlsl = NULL;
|
const char *hlsl = NULL;
|
||||||
ID3DBlob *errors = NULL;
|
ID3DBlob *errors = NULL;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
int cross_shader_model;
|
int sc_shader_model;
|
||||||
if (p->fl >= D3D_FEATURE_LEVEL_11_0) {
|
if (p->fl >= D3D_FEATURE_LEVEL_11_0) {
|
||||||
cross_shader_model = 50;
|
sc_shader_model = 50;
|
||||||
} else if (p->fl >= D3D_FEATURE_LEVEL_10_1) {
|
} else if (p->fl >= D3D_FEATURE_LEVEL_10_1) {
|
||||||
cross_shader_model = 41;
|
sc_shader_model = 41;
|
||||||
} else {
|
} else {
|
||||||
cross_shader_model = 40;
|
sc_shader_model = 40;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t start_us = mp_time_us();
|
int64_t start_us = mp_time_us();
|
||||||
@ -1278,17 +1282,42 @@ static bool compile_glsl(struct ra *ra, enum glsl_shader type,
|
|||||||
|
|
||||||
int64_t shaderc_us = mp_time_us();
|
int64_t shaderc_us = mp_time_us();
|
||||||
|
|
||||||
cross = crossc_hlsl_create((uint32_t*)spv_module.start,
|
sc_res = spvc_context_create(&sc_ctx);
|
||||||
spv_module.len / sizeof(uint32_t));
|
if (sc_res != SPVC_SUCCESS)
|
||||||
|
|
||||||
crossc_hlsl_set_shader_model(cross, cross_shader_model);
|
|
||||||
crossc_set_flip_vert_y(cross, type == GLSL_SHADER_VERTEX);
|
|
||||||
|
|
||||||
hlsl = crossc_compile(cross);
|
|
||||||
if (!hlsl) {
|
|
||||||
MP_ERR(ra, "SPIRV-Cross failed: %s\n", crossc_strerror(cross));
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
sc_res = spvc_context_parse_spirv(sc_ctx, (SpvId *)spv_module.start,
|
||||||
|
spv_module.len / sizeof(SpvId), &sc_ir);
|
||||||
|
if (sc_res != SPVC_SUCCESS)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
sc_res = spvc_context_create_compiler(sc_ctx, SPVC_BACKEND_HLSL, sc_ir,
|
||||||
|
SPVC_CAPTURE_MODE_TAKE_OWNERSHIP,
|
||||||
|
&sc_compiler);
|
||||||
|
if (sc_res != SPVC_SUCCESS)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
sc_res = spvc_compiler_create_compiler_options(sc_compiler, &sc_opts);
|
||||||
|
if (sc_res != SPVC_SUCCESS)
|
||||||
|
goto done;
|
||||||
|
sc_res = spvc_compiler_options_set_uint(sc_opts,
|
||||||
|
SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL, sc_shader_model);
|
||||||
|
if (sc_res != SPVC_SUCCESS)
|
||||||
|
goto done;
|
||||||
|
if (type == GLSL_SHADER_VERTEX) {
|
||||||
|
// FLIP_VERTEX_Y is only valid for vertex shaders
|
||||||
|
sc_res = spvc_compiler_options_set_bool(sc_opts,
|
||||||
|
SPVC_COMPILER_OPTION_FLIP_VERTEX_Y, SPVC_TRUE);
|
||||||
|
if (sc_res != SPVC_SUCCESS)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
sc_res = spvc_compiler_install_compiler_options(sc_compiler, sc_opts);
|
||||||
|
if (sc_res != SPVC_SUCCESS)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
sc_res = spvc_compiler_compile(sc_compiler, &hlsl);
|
||||||
|
if (sc_res != SPVC_SUCCESS)
|
||||||
|
goto done;
|
||||||
|
|
||||||
int64_t cross_us = mp_time_us();
|
int64_t cross_us = mp_time_us();
|
||||||
|
|
||||||
@ -1312,7 +1341,11 @@ static bool compile_glsl(struct ra *ra, enum glsl_shader type,
|
|||||||
d3dcompile_us - cross_us);
|
d3dcompile_us - cross_us);
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
done:;
|
done:
|
||||||
|
if (sc_res != SPVC_SUCCESS) {
|
||||||
|
MP_MSG(ra, MSGL_ERR, "SPIRV-Cross failed: %s\n",
|
||||||
|
spvc_context_get_last_error_string(sc_ctx));
|
||||||
|
}
|
||||||
int level = success ? MSGL_DEBUG : MSGL_ERR;
|
int level = success ? MSGL_DEBUG : MSGL_ERR;
|
||||||
MP_MSG(ra, level, "GLSL source:\n");
|
MP_MSG(ra, level, "GLSL source:\n");
|
||||||
mp_log_source(ra->log, level, glsl);
|
mp_log_source(ra->log, level, glsl);
|
||||||
@ -1321,7 +1354,8 @@ done:;
|
|||||||
mp_log_source(ra->log, level, hlsl);
|
mp_log_source(ra->log, level, hlsl);
|
||||||
}
|
}
|
||||||
SAFE_RELEASE(errors);
|
SAFE_RELEASE(errors);
|
||||||
crossc_destroy(cross);
|
if (sc_ctx)
|
||||||
|
spvc_context_destroy(sc_ctx);
|
||||||
talloc_free(ta_ctx);
|
talloc_free(ta_ctx);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -1418,14 +1452,16 @@ static size_t vbuf_upload(struct ra *ra, void *data, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char cache_magic[4] = "RD11";
|
static const char cache_magic[4] = "RD11";
|
||||||
static const int cache_version = 2;
|
static const int cache_version = 3;
|
||||||
|
|
||||||
struct cache_header {
|
struct cache_header {
|
||||||
char magic[sizeof(cache_magic)];
|
char magic[sizeof(cache_magic)];
|
||||||
int cache_version;
|
int cache_version;
|
||||||
char compiler[SPIRV_NAME_MAX_LEN];
|
char compiler[SPIRV_NAME_MAX_LEN];
|
||||||
int spv_compiler_version;
|
int spv_compiler_version;
|
||||||
uint32_t cross_version;
|
unsigned spvc_compiler_major;
|
||||||
|
unsigned spvc_compiler_minor;
|
||||||
|
unsigned spvc_compiler_patch;
|
||||||
struct dll_version d3d_compiler_version;
|
struct dll_version d3d_compiler_version;
|
||||||
int feature_level;
|
int feature_level;
|
||||||
size_t vert_bytecode_len;
|
size_t vert_bytecode_len;
|
||||||
@ -1449,6 +1485,9 @@ static void load_cached_program(struct ra *ra,
|
|||||||
struct cache_header *header = (struct cache_header *)cache.start;
|
struct cache_header *header = (struct cache_header *)cache.start;
|
||||||
cache = bstr_cut(cache, sizeof(*header));
|
cache = bstr_cut(cache, sizeof(*header));
|
||||||
|
|
||||||
|
unsigned spvc_major, spvc_minor, spvc_patch;
|
||||||
|
spvc_get_version(&spvc_major, &spvc_minor, &spvc_patch);
|
||||||
|
|
||||||
if (strncmp(header->magic, cache_magic, sizeof(cache_magic)) != 0)
|
if (strncmp(header->magic, cache_magic, sizeof(cache_magic)) != 0)
|
||||||
return;
|
return;
|
||||||
if (header->cache_version != cache_version)
|
if (header->cache_version != cache_version)
|
||||||
@ -1457,7 +1496,11 @@ static void load_cached_program(struct ra *ra,
|
|||||||
return;
|
return;
|
||||||
if (header->spv_compiler_version != spirv->compiler_version)
|
if (header->spv_compiler_version != spirv->compiler_version)
|
||||||
return;
|
return;
|
||||||
if (header->cross_version != crossc_version())
|
if (header->spvc_compiler_major != spvc_major)
|
||||||
|
return;
|
||||||
|
if (header->spvc_compiler_minor != spvc_minor)
|
||||||
|
return;
|
||||||
|
if (header->spvc_compiler_patch != spvc_patch)
|
||||||
return;
|
return;
|
||||||
if (!dll_version_equal(header->d3d_compiler_version, p->d3d_compiler_ver))
|
if (!dll_version_equal(header->d3d_compiler_version, p->d3d_compiler_ver))
|
||||||
return;
|
return;
|
||||||
@ -1491,10 +1534,15 @@ static void save_cached_program(struct ra *ra, struct ra_renderpass *pass,
|
|||||||
struct ra_d3d11 *p = ra->priv;
|
struct ra_d3d11 *p = ra->priv;
|
||||||
struct spirv_compiler *spirv = p->spirv;
|
struct spirv_compiler *spirv = p->spirv;
|
||||||
|
|
||||||
|
unsigned spvc_major, spvc_minor, spvc_patch;
|
||||||
|
spvc_get_version(&spvc_major, &spvc_minor, &spvc_patch);
|
||||||
|
|
||||||
struct cache_header header = {
|
struct cache_header header = {
|
||||||
.cache_version = cache_version,
|
.cache_version = cache_version,
|
||||||
.spv_compiler_version = p->spirv->compiler_version,
|
.spv_compiler_version = p->spirv->compiler_version,
|
||||||
.cross_version = crossc_version(),
|
.spvc_compiler_major = spvc_major,
|
||||||
|
.spvc_compiler_minor = spvc_minor,
|
||||||
|
.spvc_compiler_patch = spvc_patch,
|
||||||
.d3d_compiler_version = p->d3d_compiler_ver,
|
.d3d_compiler_version = p->d3d_compiler_ver,
|
||||||
.feature_level = p->fl,
|
.feature_level = p->fl,
|
||||||
.vert_bytecode_len = vert_bc.len,
|
.vert_bytecode_len = vert_bc.len,
|
||||||
|
8
wscript
8
wscript
@ -747,13 +747,13 @@ video_output_features = [
|
|||||||
'deps': 'shaderc-shared || shaderc-static',
|
'deps': 'shaderc-shared || shaderc-static',
|
||||||
'func': check_true,
|
'func': check_true,
|
||||||
}, {
|
}, {
|
||||||
'name': '--crossc',
|
'name': '--spirv-cross',
|
||||||
'desc': 'libcrossc SPIR-V translator',
|
'desc': 'SPIRV-Cross SPIR-V shader converter',
|
||||||
'func': check_pkg_config('crossc'),
|
'func': check_pkg_config('spirv-cross-c-shared'),
|
||||||
}, {
|
}, {
|
||||||
'name': '--d3d11',
|
'name': '--d3d11',
|
||||||
'desc': 'Direct3D 11 video output',
|
'desc': 'Direct3D 11 video output',
|
||||||
'deps': 'win32-desktop && shaderc && crossc',
|
'deps': 'win32-desktop && shaderc && spirv-cross',
|
||||||
'func': check_cc(header_name=['d3d11_1.h', 'dxgi1_2.h']),
|
'func': check_cc(header_name=['d3d11_1.h', 'dxgi1_2.h']),
|
||||||
}, {
|
}, {
|
||||||
# We need MMAL/bcm_host/dispmanx APIs. Also, most RPI distros require
|
# We need MMAL/bcm_host/dispmanx APIs. Also, most RPI distros require
|
||||||
|
Loading…
Reference in New Issue
Block a user