QPU is default substrate: recipe table + ctx env-var override #7
+34
-6
@@ -53,6 +53,25 @@ daedalus_ctx *daedalus_ctx_create(void)
|
|||||||
|
|
||||||
daedalus_ctx *daedalus_ctx_create_no_qpu(void)
|
daedalus_ctx *daedalus_ctx_create_no_qpu(void)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Per the "QPU is default substrate" decree 2026-05-23:
|
||||||
|
* setting DAEDALUS_FORCE_QPU=1 in the process env escalates this
|
||||||
|
* function to a full daedalus_ctx_create(), letting the libavcodec
|
||||||
|
* substitution shims (which call create_no_qpu via pthread_once)
|
||||||
|
* fire the V3D shaders that exist for cycles 1/2/4/5/8. Without
|
||||||
|
* this hook each consumer process (firefox, mpv, daemon) would
|
||||||
|
* need its own shim build to opt into QPU.
|
||||||
|
*
|
||||||
|
* Default behaviour (env var unset / not "1") is unchanged: pure
|
||||||
|
* NEON ctx, no implicit Vulkan init. Firefox / mpv consumers
|
||||||
|
* that dlopen libavcodec without opting in stay on the
|
||||||
|
* Vulkan-free path; the daemon explicitly sets
|
||||||
|
* DAEDALUS_FORCE_QPU=1 before loading libavcodec.
|
||||||
|
*/
|
||||||
|
const char *force = getenv("DAEDALUS_FORCE_QPU");
|
||||||
|
if (force && force[0] == '1' && force[1] == 0)
|
||||||
|
return daedalus_ctx_create();
|
||||||
|
|
||||||
daedalus_ctx *ctx = calloc(1, sizeof(*ctx));
|
daedalus_ctx *ctx = calloc(1, sizeof(*ctx));
|
||||||
if (!ctx) return NULL;
|
if (!ctx) return NULL;
|
||||||
ctx->has_qpu = 0;
|
ctx->has_qpu = 0;
|
||||||
@@ -84,16 +103,25 @@ void daedalus_ctx_destroy(daedalus_ctx *ctx)
|
|||||||
|
|
||||||
daedalus_substrate daedalus_recipe_substrate_for(daedalus_kernel k)
|
daedalus_substrate daedalus_recipe_substrate_for(daedalus_kernel k)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Recipe table per the "QPU is default substrate" decree
|
||||||
|
* 2026-05-23. Any kernel that has a V3D compute shader returns
|
||||||
|
* SUBSTRATE_QPU; CPU is the fallback for kernels without a
|
||||||
|
* shader (still the case for H.264 IDCT 4x4 / IDCT 8x8 / qpel
|
||||||
|
* mc20 — covered by follow-on task 165). The dispatch
|
||||||
|
* wrappers already fall back to CPU automatically when the
|
||||||
|
* ctx doesn't have QPU available (daedalus_ctx_has_qpu == 0).
|
||||||
|
*/
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case DAEDALUS_KERNEL_VP9_IDCT8: return DAEDALUS_SUBSTRATE_QPU;
|
case DAEDALUS_KERNEL_VP9_IDCT8: return DAEDALUS_SUBSTRATE_QPU;
|
||||||
case DAEDALUS_KERNEL_VP9_LPF4_INNER: return DAEDALUS_SUBSTRATE_QPU;
|
case DAEDALUS_KERNEL_VP9_LPF4_INNER: return DAEDALUS_SUBSTRATE_QPU;
|
||||||
case DAEDALUS_KERNEL_VP9_MC_8H: return DAEDALUS_SUBSTRATE_CPU;
|
case DAEDALUS_KERNEL_VP9_MC_8H: return DAEDALUS_SUBSTRATE_QPU; /* v3d_mc_8h.spv */
|
||||||
case DAEDALUS_KERNEL_VP9_LPF8_INNER: return DAEDALUS_SUBSTRATE_QPU;
|
case DAEDALUS_KERNEL_VP9_LPF8_INNER: return DAEDALUS_SUBSTRATE_QPU;
|
||||||
case DAEDALUS_KERNEL_AV1_CDEF_8X8: return DAEDALUS_SUBSTRATE_CPU;
|
case DAEDALUS_KERNEL_AV1_CDEF_8X8: return DAEDALUS_SUBSTRATE_QPU; /* v3d_cdef.spv */
|
||||||
case DAEDALUS_KERNEL_H264_IDCT4: return DAEDALUS_SUBSTRATE_CPU;
|
case DAEDALUS_KERNEL_H264_IDCT4: return DAEDALUS_SUBSTRATE_CPU; /* TODO task #165 */
|
||||||
case DAEDALUS_KERNEL_H264_IDCT8: return DAEDALUS_SUBSTRATE_CPU;
|
case DAEDALUS_KERNEL_H264_IDCT8: return DAEDALUS_SUBSTRATE_CPU; /* TODO task #165 */
|
||||||
case DAEDALUS_KERNEL_H264_DEBLOCK_LV: return DAEDALUS_SUBSTRATE_CPU;
|
case DAEDALUS_KERNEL_H264_DEBLOCK_LV: return DAEDALUS_SUBSTRATE_QPU; /* v3d_h264deblock.spv */
|
||||||
case DAEDALUS_KERNEL_H264_QPEL_MC20: return DAEDALUS_SUBSTRATE_CPU;
|
case DAEDALUS_KERNEL_H264_QPEL_MC20: return DAEDALUS_SUBSTRATE_CPU; /* TODO task #165 */
|
||||||
}
|
}
|
||||||
return DAEDALUS_SUBSTRATE_CPU;
|
return DAEDALUS_SUBSTRATE_CPU;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user