diff --git a/meson.build b/meson.build index a73e49ff..b66c6dea 100644 --- a/meson.build +++ b/meson.build @@ -12,6 +12,7 @@ project('libplacebo', ['c', 'cpp'], 7, # API version { + '350': 'add pl_{opengl,vulkan,d3d11}_params.no_compute', '349': 'add pl_color_{primaries,system,transfer}_name(s)', '348': 'add pl_color_linearize and pl_color_delinearize', '347': 'add pl_gpu_limits.max_mapped_vram', diff --git a/src/d3d11/context.c b/src/d3d11/context.c index e0ba90f1..8a46354e 100644 --- a/src/d3d11/context.c +++ b/src/d3d11/context.c @@ -472,7 +472,7 @@ pl_d3d11 pl_d3d11_create(pl_log log, const struct pl_d3d11_params *params) PL_MSG(ctx, level, "Using a software adapter"); } - d3d11->gpu = pl_gpu_create_d3d11(ctx); + d3d11->gpu = pl_gpu_create_d3d11(ctx, params); if (!d3d11->gpu) goto error; diff --git a/src/d3d11/gpu.c b/src/d3d11/gpu.c index 05a08a32..50572d86 100644 --- a/src/d3d11/gpu.c +++ b/src/d3d11/gpu.c @@ -387,7 +387,8 @@ static struct pl_gpu_fns pl_fns_d3d11 = { .destroy = d3d11_gpu_destroy, }; -pl_gpu pl_gpu_create_d3d11(struct d3d11_ctx *ctx) +pl_gpu pl_gpu_create_d3d11(struct d3d11_ctx *ctx, + const struct pl_d3d11_params *params) { pl_assert(ctx->dev); IDXGIDevice1 *dxgi_dev = NULL; @@ -506,7 +507,7 @@ pl_gpu pl_gpu_create_d3d11(struct d3d11_ctx *ctx) } if (p->fl >= D3D_FEATURE_LEVEL_11_0) { - gpu->glsl.compute = true; + gpu->glsl.compute = !params->no_compute; gpu->limits.compute_queues = 1; // Set `gpu->limits.blittable_1d_3d`, since `pl_tex_blit_compute`, which // is used to emulate blits on 11_0 and up, supports 1D and 3D textures diff --git a/src/d3d11/gpu.h b/src/d3d11/gpu.h index cbc706ac..c6d842e6 100644 --- a/src/d3d11/gpu.h +++ b/src/d3d11/gpu.h @@ -29,7 +29,8 @@ #include "common.h" #include "utils.h" -pl_gpu pl_gpu_create_d3d11(struct d3d11_ctx *ctx); +pl_gpu pl_gpu_create_d3d11(struct d3d11_ctx *ctx, + const struct pl_d3d11_params *params); // --- pl_gpu internal structs and helpers diff --git a/src/include/libplacebo/d3d11.h b/src/include/libplacebo/d3d11.h index 8ecba30b..28e6eece 100644 --- a/src/include/libplacebo/d3d11.h +++ b/src/include/libplacebo/d3d11.h @@ -70,6 +70,11 @@ struct pl_d3d11_params { // Also logs IDXGIInfoQueue messages bool debug; + // Disables the use of compute shaders. Some devices/drivers perform better + // without them. This may also help prevent image corruption in cases where + // the driver is misbehaving. Some features may be disabled if this is set. + bool no_compute; + // Extra flags to pass to D3D11CreateDevice (D3D11_CREATE_DEVICE_FLAG). // libplacebo should be compatible with any flags passed here. UINT flags; diff --git a/src/include/libplacebo/opengl.h b/src/include/libplacebo/opengl.h index 46597b20..168281e1 100644 --- a/src/include/libplacebo/opengl.h +++ b/src/include/libplacebo/opengl.h @@ -72,6 +72,11 @@ struct pl_opengl_params { // undesirable when GPU-accelerated processing is expected. bool allow_software; + // Disables the use of compute shaders. Some devices/drivers perform better + // without them. This may also help prevent image corruption in cases where + // the driver is misbehaving. Some features may be disabled if this is set. + bool no_compute; + // Restrict the maximum allowed GLSL version. (Mainly for testing) int max_glsl_version; diff --git a/src/include/libplacebo/vulkan.h b/src/include/libplacebo/vulkan.h index 505ea293..b8d43e2c 100644 --- a/src/include/libplacebo/vulkan.h +++ b/src/include/libplacebo/vulkan.h @@ -230,6 +230,11 @@ struct pl_vulkan_params { // queues for a given QF enabled, regardless of this setting. int queue_count; + // Disables the use of compute shaders. Some devices/drivers perform better + // without them. This may also help prevent image corruption in cases where + // the driver is misbehaving. Some features may be disabled if this is set. + bool no_compute; + // Bitmask of extra queue families to enable. If set, then *all* queue // families matching *any* of these flags will be enabled at device // creation time. Setting this to VK_QUEUE_FLAG_BITS_MAX_ENUM effectively @@ -424,6 +429,7 @@ struct pl_vulkan_import_params { // Restrict specific features to e.g. work around driver bugs, or simply // for testing purposes. See `pl_vulkan_params` for a description of these. + bool no_compute; int max_glsl_version; uint32_t max_api_version; }; diff --git a/src/opengl/gpu.c b/src/opengl/gpu.c index d31171a1..38d87d1a 100644 --- a/src/opengl/gpu.c +++ b/src/opengl/gpu.c @@ -155,7 +155,7 @@ pl_gpu pl_gpu_create_gl(pl_log log, pl_opengl pl_gl, const struct pl_opengl_para } if (gl_test_ext(gpu, "GL_ARB_compute_shader", 43, 0) && glsl->version >= 420) { - glsl->compute = true; + glsl->compute = !params->no_compute; get(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, &glsl->max_shmem_size); get(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &glsl->max_group_threads); for (int i = 0; i < 3; i++) diff --git a/src/vulkan/context.c b/src/vulkan/context.c index 1c70fe59..92f0ab0b 100644 --- a/src/vulkan/context.c +++ b/src/vulkan/context.c @@ -1366,7 +1366,8 @@ static void unlock_queue(pl_vulkan pl_vk, uint32_t qf, uint32_t qidx) vk->unlock_queue(vk->queue_ctx, qf, qidx); } -static bool finalize_context(struct pl_vulkan_t *pl_vk, int max_glsl_version) +static bool finalize_context(struct pl_vulkan_t *pl_vk, int max_glsl_version, + bool no_compute) { struct vk_ctx *vk = PL_PRIV(pl_vk); @@ -1383,14 +1384,16 @@ static bool finalize_context(struct pl_vulkan_t *pl_vk, int max_glsl_version) return false; // Blacklist / restrict features + struct pl_glsl_version *glsl = (struct pl_glsl_version *) &pl_vk->gpu->glsl; if (max_glsl_version) { - struct pl_glsl_version *glsl = (struct pl_glsl_version *) &pl_vk->gpu->glsl; glsl->version = PL_MIN(glsl->version, max_glsl_version); glsl->version = PL_MAX(glsl->version, 140); // required for GL_KHR_vulkan_glsl PL_INFO(vk, "Restricting GLSL version to %d... new version is %d", max_glsl_version, glsl->version); } + glsl->compute &= !no_compute; + // Expose the resulting vulkan objects pl_vk->instance = vk->inst; pl_vk->phys_device = vk->physd; @@ -1522,7 +1525,7 @@ pl_vulkan pl_vulkan_create(pl_log log, const struct pl_vulkan_params *params) if (!device_init(vk, params)) goto error; - if (!finalize_context(pl_vk, params->max_glsl_version)) + if (!finalize_context(pl_vk, params->max_glsl_version, params->no_compute)) goto error; return pl_vk; @@ -1691,7 +1694,7 @@ next_qf: ; goto error; } - if (!finalize_context(pl_vk, params->max_glsl_version)) + if (!finalize_context(pl_vk, params->max_glsl_version, params->no_compute)) goto error; pl_free(tmp);