diff --git a/src/d3d11/context.c b/src/d3d11/context.c index e0ba90f1..e877a9c8 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->no_compute); if (!d3d11->gpu) goto error; diff --git a/src/d3d11/gpu.c b/src/d3d11/gpu.c index 05a08a32..ec7c8860 100644 --- a/src/d3d11/gpu.c +++ b/src/d3d11/gpu.c @@ -387,7 +387,7 @@ 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, bool no_compute) { pl_assert(ctx->dev); IDXGIDevice1 *dxgi_dev = NULL; @@ -505,21 +505,25 @@ pl_gpu pl_gpu_create_d3d11(struct d3d11_ctx *ctx) 1 << D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP; } - if (p->fl >= D3D_FEATURE_LEVEL_11_0) { - gpu->glsl.compute = true; - 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 - gpu->limits.blittable_1d_3d = true; - - gpu->glsl.max_shmem_size = D3D11_CS_TGSM_REGISTER_COUNT * sizeof(float); - gpu->glsl.max_group_threads = D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP; - gpu->glsl.max_group_size[0] = D3D11_CS_THREAD_GROUP_MAX_X; - gpu->glsl.max_group_size[1] = D3D11_CS_THREAD_GROUP_MAX_Y; - gpu->glsl.max_group_size[2] = D3D11_CS_THREAD_GROUP_MAX_Z; - gpu->limits.max_dispatch[0] = gpu->limits.max_dispatch[1] = - gpu->limits.max_dispatch[2] = - D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION; + if (!no_compute) { + if (p->fl >= D3D_FEATURE_LEVEL_11_0) { + gpu->glsl.compute = true; + 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 + gpu->limits.blittable_1d_3d = true; + + gpu->glsl.max_shmem_size = D3D11_CS_TGSM_REGISTER_COUNT * sizeof(float); + gpu->glsl.max_group_threads = D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP; + gpu->glsl.max_group_size[0] = D3D11_CS_THREAD_GROUP_MAX_X; + gpu->glsl.max_group_size[1] = D3D11_CS_THREAD_GROUP_MAX_Y; + gpu->glsl.max_group_size[2] = D3D11_CS_THREAD_GROUP_MAX_Z; + gpu->limits.max_dispatch[0] = gpu->limits.max_dispatch[1] = + gpu->limits.max_dispatch[2] = + D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION; + } + } else { + PL_INFO(gpu, "Disabling compute shaders"); } if (p->fl >= D3D_FEATURE_LEVEL_11_0) { diff --git a/src/include/libplacebo/d3d11.h b/src/include/libplacebo/d3d11.h index 8ecba30b..e6103b81 100644 --- a/src/include/libplacebo/d3d11.h +++ b/src/include/libplacebo/d3d11.h @@ -114,6 +114,9 @@ struct pl_d3d11_params { int min_feature_level; // Defaults to D3D_FEATURE_LEVEL_9_1 if unset int max_feature_level; // Defaults to D3D_FEATURE_LEVEL_12_1 if unset + // Disable compute shaders. + bool no_compute; + // Allow up to N in-flight frames. Similar to swapchain_depth for Vulkan and // OpenGL, though with DXGI this is a device-wide setting that affects all // swapchains (except for waitable swapchains.) See the documentation for diff --git a/src/include/libplacebo/opengl.h b/src/include/libplacebo/opengl.h index 46597b20..5eecd4c8 100644 --- a/src/include/libplacebo/opengl.h +++ b/src/include/libplacebo/opengl.h @@ -75,6 +75,9 @@ struct pl_opengl_params { // Restrict the maximum allowed GLSL version. (Mainly for testing) int max_glsl_version; + // Disable compute shaders. + bool no_compute; + // Optional. Required when importing/exporting dmabufs as textures. void *egl_display; void *egl_context; diff --git a/src/include/libplacebo/vulkan.h b/src/include/libplacebo/vulkan.h index 505ea293..a9704809 100644 --- a/src/include/libplacebo/vulkan.h +++ b/src/include/libplacebo/vulkan.h @@ -258,6 +258,7 @@ struct pl_vulkan_params { // for testing purposes int max_glsl_version; // limit the maximum GLSL version uint32_t max_api_version; // limit the maximum vulkan API version + bool no_compute; // disable compute shaders }; // Default/recommended parameters. Should generally be safe and efficient. @@ -426,6 +427,7 @@ struct pl_vulkan_import_params { // for testing purposes. See `pl_vulkan_params` for a description of these. int max_glsl_version; uint32_t max_api_version; + bool no_compute; }; #define pl_vulkan_import_params(...) (&(struct pl_vulkan_import_params) { __VA_ARGS__ }) diff --git a/src/opengl/gpu.c b/src/opengl/gpu.c index 8312242b..cb9d5142 100644 --- a/src/opengl/gpu.c +++ b/src/opengl/gpu.c @@ -154,12 +154,16 @@ pl_gpu pl_gpu_create_gl(pl_log log, pl_opengl pl_gl, const struct pl_opengl_para params->max_glsl_version, glsl->version); } - if (gl_test_ext(gpu, "GL_ARB_compute_shader", 43, 0) && glsl->version >= 420) { - glsl->compute = true; - 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++) - geti(GL_MAX_COMPUTE_WORK_GROUP_SIZE, i, &glsl->max_group_size[i]); + if (!params->no_compute) { + if (gl_test_ext(gpu, "GL_ARB_compute_shader", 43, 0) && glsl->version >= 420) { + glsl->compute = true; + 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++) + geti(GL_MAX_COMPUTE_WORK_GROUP_SIZE, i, &glsl->max_group_size[i]); + } + } else { + PL_INFO(gpu, "Disabling compute shaders"); } if (gl_test_ext(gpu, "GL_ARB_texture_gather", 40, 31) && diff --git a/src/vulkan/context.c b/src/vulkan/context.c index 37048672..23ee2b32 100644 --- a/src/vulkan/context.c +++ b/src/vulkan/context.c @@ -1367,7 +1367,7 @@ 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); @@ -1391,6 +1391,16 @@ static bool finalize_context(struct pl_vulkan_t *pl_vk, int max_glsl_version) PL_INFO(vk, "Restricting GLSL version to %d... new version is %d", max_glsl_version, glsl->version); } + if (no_compute || (max_glsl_version && max_glsl_version < 420)) { + struct pl_glsl_version *glsl = (struct pl_glsl_version *) &pl_vk->gpu->glsl; + glsl->compute = false; + glsl->max_shmem_size = 0; + glsl->max_group_threads = 0; + glsl->max_group_size[0] = 0; + glsl->max_group_size[1] = 0; + glsl->max_group_size[2] = 0; + PL_INFO(vk, "Disabling compute shaders"); + } // Expose the resulting vulkan objects pl_vk->instance = vk->inst; @@ -1523,7 +1533,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; @@ -1692,7 +1702,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);