summaryrefslogtreecommitdiffstats
path: root/video/out/placebo/ra_pl.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/placebo/ra_pl.c')
-rw-r--r--video/out/placebo/ra_pl.c234
1 files changed, 71 insertions, 163 deletions
diff --git a/video/out/placebo/ra_pl.c b/video/out/placebo/ra_pl.c
index f8df590511..14c9444fd3 100644
--- a/video/out/placebo/ra_pl.c
+++ b/video/out/placebo/ra_pl.c
@@ -5,11 +5,11 @@
#include "utils.h"
struct ra_pl {
- const struct pl_gpu *gpu;
+ pl_gpu gpu;
struct ra_timer_pl *active_timer;
};
-static inline const struct pl_gpu *get_gpu(const struct ra *ra)
+static inline pl_gpu get_gpu(const struct ra *ra)
{
struct ra_pl *p = ra->priv;
return p->gpu;
@@ -17,16 +17,14 @@ static inline const struct pl_gpu *get_gpu(const struct ra *ra)
static struct ra_fns ra_fns_pl;
-const struct pl_gpu *ra_pl_get(const struct ra *ra)
+pl_gpu ra_pl_get(const struct ra *ra)
{
return ra->fns == &ra_fns_pl ? get_gpu(ra) : NULL;
}
-#if PL_API_VER >= 60
-static struct pl_timer *get_active_timer(const struct ra *ra);
-#endif
+static pl_timer get_active_timer(const struct ra *ra);
-struct ra *ra_create_pl(const struct pl_gpu *gpu, struct mp_log *log)
+struct ra *ra_create_pl(pl_gpu gpu, struct mp_log *log)
{
assert(gpu);
@@ -43,12 +41,14 @@ struct ra *ra_create_pl(const struct pl_gpu *gpu, struct mp_log *log)
ra->caps = RA_CAP_DIRECT_UPLOAD | RA_CAP_NESTED_ARRAY | RA_CAP_FRAGCOORD;
- if (gpu->caps & PL_GPU_CAP_COMPUTE)
+ if (gpu->glsl.compute)
ra->caps |= RA_CAP_COMPUTE | RA_CAP_NUM_GROUPS;
- if (gpu->caps & PL_GPU_CAP_PARALLEL_COMPUTE)
+ if (gpu->limits.compute_queues > gpu->limits.fragment_queues)
ra->caps |= RA_CAP_PARALLEL_COMPUTE;
- if (gpu->caps & PL_GPU_CAP_INPUT_VARIABLES)
+ if (gpu->limits.max_variable_comps)
ra->caps |= RA_CAP_GLOBAL_UNIFORM;
+ if (!gpu->limits.host_cached)
+ ra->caps |= RA_CAP_SLOW_DR;
if (gpu->limits.max_tex_1d_dim)
ra->caps |= RA_CAP_TEX_1D;
@@ -58,21 +58,22 @@ struct ra *ra_create_pl(const struct pl_gpu *gpu, struct mp_log *log)
ra->caps |= RA_CAP_BUF_RO;
if (gpu->limits.max_ssbo_size)
ra->caps |= RA_CAP_BUF_RW;
- if (gpu->limits.min_gather_offset && gpu->limits.max_gather_offset)
+ if (gpu->glsl.min_gather_offset && gpu->glsl.max_gather_offset)
ra->caps |= RA_CAP_GATHER;
// Semi-hack: assume all textures are blittable if r8 is
- const struct pl_fmt *r8 = pl_find_named_fmt(gpu, "r8");
+ pl_fmt r8 = pl_find_named_fmt(gpu, "r8");
if (r8->caps & PL_FMT_CAP_BLITTABLE)
ra->caps |= RA_CAP_BLIT;
ra->max_texture_wh = gpu->limits.max_tex_2d_dim;
- ra->max_shmem = gpu->limits.max_shmem_size;
ra->max_pushc_size = gpu->limits.max_pushc_size;
+ ra->max_compute_group_threads = gpu->glsl.max_group_threads;
+ ra->max_shmem = gpu->glsl.max_shmem_size;
// Set up format wrappers
for (int i = 0; i < gpu->num_formats; i++) {
- const struct pl_fmt *plfmt = gpu->formats[i];
+ pl_fmt plfmt = gpu->formats[i];
static const enum ra_ctype fmt_type_map[PL_FMT_TYPE_COUNT] = {
[PL_FMT_UNORM] = RA_CTYPE_UNORM,
[PL_FMT_UINT] = RA_CTYPE_UINT,
@@ -113,7 +114,7 @@ static void destroy_ra_pl(struct ra *ra)
talloc_free(ra);
}
-static struct ra_format *map_fmt(struct ra *ra, const struct pl_fmt *plfmt)
+static struct ra_format *map_fmt(struct ra *ra, pl_fmt plfmt)
{
for (int i = 0; i < ra->num_formats; i++) {
if (ra->formats[i]->priv == plfmt)
@@ -124,8 +125,7 @@ static struct ra_format *map_fmt(struct ra *ra, const struct pl_fmt *plfmt)
return NULL;
}
-bool mppl_wrap_tex(struct ra *ra, const struct pl_tex *pltex,
- struct ra_tex *out_tex)
+bool mppl_wrap_tex(struct ra *ra, pl_tex pltex, struct ra_tex *out_tex)
{
if (!pltex)
return false;
@@ -144,8 +144,9 @@ bool mppl_wrap_tex(struct ra *ra, const struct pl_tex *pltex,
.blit_dst = pltex->params.blit_dst,
.host_mutable = pltex->params.host_writable,
.downloadable = pltex->params.host_readable,
- .src_linear = pltex->params.sample_mode == PL_TEX_SAMPLE_LINEAR,
- .src_repeat = pltex->params.address_mode == PL_TEX_ADDRESS_REPEAT,
+ // These don't exist upstream, so just pick something reasonable
+ .src_linear = pltex->params.format->caps & PL_FMT_CAP_LINEAR,
+ .src_repeat = false,
},
.priv = (void *) pltex,
};
@@ -156,34 +157,8 @@ bool mppl_wrap_tex(struct ra *ra, const struct pl_tex *pltex,
static struct ra_tex *tex_create_pl(struct ra *ra,
const struct ra_tex_params *params)
{
- const struct pl_gpu *gpu = get_gpu(ra);
-
- // Check size limits
- bool ok = false;
- switch (params->dimensions) {
- case 1:
- ok = params->w <= gpu->limits.max_tex_1d_dim;
- break;
-
- case 2:
- ok = params->w <= gpu->limits.max_tex_2d_dim &&
- params->h <= gpu->limits.max_tex_2d_dim;
- break;
-
- case 3:
- ok = params->w <= gpu->limits.max_tex_2d_dim &&
- params->h <= gpu->limits.max_tex_2d_dim &&
- params->d <= gpu->limits.max_tex_2d_dim;
- break;
- };
-
- if (!ok) {
- MP_ERR(ra, "Texture size %dx%dx%d exceeds dimension limits!\n",
- params->w, params->h, params->d);
- return NULL;
- }
-
- const struct pl_tex *pltex = pl_tex_create(gpu, &(struct pl_tex_params) {
+ pl_gpu gpu = get_gpu(ra);
+ pl_tex pltex = pl_tex_create(gpu, &(struct pl_tex_params) {
.w = params->w,
.h = params->dimensions >= 2 ? params->h : 0,
.d = params->dimensions >= 3 ? params->d : 0,
@@ -195,10 +170,6 @@ static struct ra_tex *tex_create_pl(struct ra *ra,
.blit_dst = params->blit_dst || params->render_dst,
.host_writable = params->host_mutable,
.host_readable = params->downloadable,
- .sample_mode = params->src_linear ? PL_TEX_SAMPLE_LINEAR
- : PL_TEX_SAMPLE_NEAREST,
- .address_mode = params->src_repeat ? PL_TEX_ADDRESS_REPEAT
- : PL_TEX_ADDRESS_CLAMP,
.initial_data = params->initial_data,
});
@@ -209,6 +180,10 @@ static struct ra_tex *tex_create_pl(struct ra *ra,
return NULL;
}
+ // Keep track of these, so we can correctly bind them later
+ ratex->params.src_repeat = params->src_repeat;
+ ratex->params.src_linear = params->src_linear;
+
return ratex;
}
@@ -217,59 +192,32 @@ static void tex_destroy_pl(struct ra *ra, struct ra_tex *tex)
if (!tex)
return;
- pl_tex_destroy(get_gpu(ra), (const struct pl_tex **) &tex->priv);
+ pl_tex_destroy(get_gpu(ra), (pl_tex *) &tex->priv);
talloc_free(tex);
}
static bool tex_upload_pl(struct ra *ra, const struct ra_tex_upload_params *params)
{
- const struct pl_gpu *gpu = get_gpu(ra);
- const struct pl_tex *tex = params->tex->priv;
+ pl_gpu gpu = get_gpu(ra);
+ pl_tex tex = params->tex->priv;
struct pl_tex_transfer_params pl_params = {
.tex = tex,
.buf = params->buf ? params->buf->priv : NULL,
.buf_offset = params->buf_offset,
.ptr = (void *) params->src,
-#if PL_API_VER >= 60
.timer = get_active_timer(ra),
-#endif
};
- const struct pl_buf *staging = NULL;
-
+ pl_buf staging = NULL;
if (params->tex->params.dimensions == 2) {
- size_t texel_size = tex->params.format->texel_size;
- pl_params.stride_w = params->stride / texel_size;
- size_t stride = pl_params.stride_w * texel_size;
- int lines = tex->params.h;
if (params->rc) {
pl_params.rc = (struct pl_rect3d) {
.x0 = params->rc->x0, .x1 = params->rc->x1,
.y0 = params->rc->y0, .y1 = params->rc->y1,
};
- lines = pl_rect_h(pl_params.rc);
}
- if (stride != params->stride) {
- // Fall back to uploading via a staging buffer prepared in CPU
- staging = pl_buf_create(gpu, &(struct pl_buf_params) {
- .type = PL_BUF_TEX_TRANSFER,
- .size = lines * stride,
- .memory_type = PL_BUF_MEM_HOST,
- .host_mapped = true,
- });
- if (!staging)
- return false;
-
- const uint8_t *src = params->buf ? params->buf->data : params->src;
- assert(src);
- for (int y = 0; y < lines; y++)
- memcpy(staging->data + y * stride, src + y * params->stride, stride);
-
- pl_params.ptr = NULL;
- pl_params.buf = staging;
- pl_params.buf_offset = 0;
- }
+ pl_params.row_pitch = params->stride;
}
bool ok = pl_tex_upload(gpu, &pl_params);
@@ -279,62 +227,24 @@ static bool tex_upload_pl(struct ra *ra, const struct ra_tex_upload_params *para
static bool tex_download_pl(struct ra *ra, struct ra_tex_download_params *params)
{
- const struct pl_tex *tex = params->tex->priv;
- size_t texel_size = tex->params.format->texel_size;
+ pl_tex tex = params->tex->priv;
struct pl_tex_transfer_params pl_params = {
.tex = tex,
.ptr = params->dst,
- .stride_w = params->stride / texel_size,
-#if PL_API_VER >= 60
.timer = get_active_timer(ra),
-#endif
+ .row_pitch = params->stride,
};
- uint8_t *staging = NULL;
- size_t stride = pl_params.stride_w * texel_size;
- if (stride != params->stride) {
- staging = talloc_size(NULL, tex->params.h * stride);
- pl_params.ptr = staging;
- }
-
- bool ok = pl_tex_download(get_gpu(ra), &pl_params);
- if (ok && staging) {
- for (int y = 0; y < tex->params.h; y++) {
- memcpy((uint8_t *) params->dst + y * params->stride,
- staging + y * stride,
- stride);
- }
- }
-
- talloc_free(staging);
- return ok;
+ return pl_tex_download(get_gpu(ra), &pl_params);
}
static struct ra_buf *buf_create_pl(struct ra *ra,
const struct ra_buf_params *params)
{
- static const enum pl_buf_type buf_type[] = {
- [RA_BUF_TYPE_TEX_UPLOAD] = PL_BUF_TEX_TRANSFER,
- [RA_BUF_TYPE_SHADER_STORAGE] = PL_BUF_STORAGE,
- [RA_BUF_TYPE_UNIFORM] = PL_BUF_UNIFORM,
- [RA_BUF_TYPE_SHARED_MEMORY] = 0,
- };
-
- const struct pl_gpu *gpu = get_gpu(ra);
- size_t max_size[] = {
- [PL_BUF_TEX_TRANSFER] = gpu->limits.max_xfer_size,
- [PL_BUF_UNIFORM] = gpu->limits.max_ubo_size,
- [PL_BUF_STORAGE] = gpu->limits.max_ssbo_size,
- };
-
- if (params->size > max_size[buf_type[params->type]]) {
- MP_ERR(ra, "Buffer size %zu exceeds size limits!\n", params->size);
- return NULL;
- }
-
- const struct pl_buf *plbuf = pl_buf_create(gpu, &(struct pl_buf_params) {
- .type = buf_type[params->type],
+ pl_buf plbuf = pl_buf_create(get_gpu(ra), &(struct pl_buf_params) {
.size = params->size,
+ .uniform = params->type == RA_BUF_TYPE_UNIFORM,
+ .storable = params->type == RA_BUF_TYPE_SHADER_STORAGE,
.host_mapped = params->host_mapped,
.host_writable = params->host_mutable,
.initial_data = params->initial_data,
@@ -359,7 +269,7 @@ static void buf_destroy_pl(struct ra *ra, struct ra_buf *buf)
if (!buf)
return;
- pl_buf_destroy(get_gpu(ra), (const struct pl_buf **) &buf->priv);
+ pl_buf_destroy(get_gpu(ra), (pl_buf *) &buf->priv);
talloc_free(buf);
}
@@ -399,7 +309,14 @@ static void blit_pl(struct ra *ra, struct ra_tex *dst, struct ra_tex *src,
pldst.y1 = MPMIN(MPMAX(dst_rc->y1, 0), dst->params.h);
}
- pl_tex_blit(get_gpu(ra), dst->priv, src->priv, pldst, plsrc);
+ pl_tex_blit(get_gpu(ra), &(struct pl_tex_blit_params) {
+ .src = src->priv,
+ .dst = dst->priv,
+ .src_rc = plsrc,
+ .dst_rc = pldst,
+ .sample_mode = src->params.src_linear ? PL_TEX_SAMPLE_LINEAR
+ : PL_TEX_SAMPLE_NEAREST,
+ });
}
static const enum pl_var_type var_type[RA_VARTYPE_COUNT] = {
@@ -469,7 +386,7 @@ static int desc_namespace_pl(struct ra *ra, enum ra_vartype type)
}
struct pass_priv {
- const struct pl_pass *pl_pass;
+ pl_pass pass;
uint16_t *inp_index; // index translation map
// Space to hold the descriptor bindings and variable updates
struct pl_desc_binding *binds;
@@ -481,7 +398,7 @@ static struct ra_renderpass *renderpass_create_pl(struct ra *ra,
const struct ra_renderpass_params *params)
{
void *tmp = talloc_new(NULL);
- const struct pl_gpu *gpu = get_gpu(ra);
+ pl_gpu gpu = get_gpu(ra);
struct ra_renderpass *pass = NULL;
static const enum pl_pass_type pass_type[] = {
@@ -533,8 +450,6 @@ static struct ra_renderpass *renderpass_create_pl(struct ra *ra,
.glsl_shader = params->type == RA_RENDERPASS_TYPE_COMPUTE
? params->compute_shader
: params->frag_shader,
- .cached_program = params->cached_program.start,
- .cached_program_len = params->cached_program.len,
};
struct pl_blend_params blend_params;
@@ -543,17 +458,17 @@ static struct ra_renderpass *renderpass_create_pl(struct ra *ra,
pl_params.vertex_shader = params->vertex_shader;
pl_params.vertex_type = PL_PRIM_TRIANGLE_LIST;
pl_params.vertex_stride = params->vertex_stride;
- pl_params.target_dummy.params.format = params->target_format->priv;
pl_params.load_target = !params->invalidate_target;
+ pl_params.target_format = params->target_format->priv;
if (params->enable_blend) {
pl_params.blend_params = &blend_params;
blend_params = (struct pl_blend_params) {
// Same enum order as ra_blend
- .src_rgb = (enum ra_blend) params->blend_src_rgb,
- .dst_rgb = (enum ra_blend) params->blend_dst_rgb,
- .src_alpha = (enum ra_blend) params->blend_src_alpha,
- .dst_alpha = (enum ra_blend) params->blend_dst_alpha,
+ .src_rgb = (enum pl_blend_mode) params->blend_src_rgb,
+ .dst_rgb = (enum pl_blend_mode) params->blend_dst_rgb,
+ .src_alpha = (enum pl_blend_mode) params->blend_src_alpha,
+ .dst_alpha = (enum pl_blend_mode) params->blend_dst_alpha,
};
}
@@ -578,8 +493,8 @@ static struct ra_renderpass *renderpass_create_pl(struct ra *ra,
}
}
- priv->pl_pass = pl_pass_create(gpu, &pl_params);
- if (!priv->pl_pass)
+ priv->pass = pl_pass_create(gpu, &pl_params);
+ if (!priv->pass)
goto error;
pass = talloc_ptrtype(NULL, pass);
@@ -588,11 +503,6 @@ static struct ra_renderpass *renderpass_create_pl(struct ra *ra,
.priv = talloc_steal(pass, priv),
};
- pass->params.cached_program = (struct bstr) {
- .start = (void *) priv->pl_pass->params.cached_program,
- .len = priv->pl_pass->params.cached_program_len,
- };
-
// fall through
error:
talloc_free(tmp);
@@ -605,7 +515,7 @@ static void renderpass_destroy_pl(struct ra *ra, struct ra_renderpass *pass)
return;
struct pass_priv *priv = pass->priv;
- pl_pass_destroy(get_gpu(ra), (const struct pl_pass **) &priv->pl_pass);
+ pl_pass_destroy(get_gpu(ra), (pl_pass *) &priv->pass);
talloc_free(pass);
}
@@ -624,17 +534,23 @@ static void renderpass_run_pl(struct ra *ra,
.data = val->data,
});
} else {
- struct pl_desc_binding bind;
+ struct pl_desc_binding bind = {0};
switch (inp->type) {
case RA_VARTYPE_TEX:
- case RA_VARTYPE_IMG_W:
- bind.object = (* (struct ra_tex **) val->data)->priv;
+ case RA_VARTYPE_IMG_W: {
+ struct ra_tex *tex = *((struct ra_tex **) val->data);
+ bind.object = tex->priv;
+ bind.sample_mode = tex->params.src_linear ? PL_TEX_SAMPLE_LINEAR
+ : PL_TEX_SAMPLE_NEAREST;
+ bind.address_mode = tex->params.src_repeat ? PL_TEX_ADDRESS_REPEAT
+ : PL_TEX_ADDRESS_CLAMP;
break;
+ }
case RA_VARTYPE_BUF_RO:
case RA_VARTYPE_BUF_RW:
bind.object = (* (struct ra_buf **) val->data)->priv;
break;
- default: abort();
+ default: MP_ASSERT_UNREACHABLE();
};
p->binds[p->inp_index[val->index]] = bind;
@@ -642,17 +558,15 @@ static void renderpass_run_pl(struct ra *ra,
}
struct pl_pass_run_params pl_params = {
- .pass = p->pl_pass,
+ .pass = p->pass,
.var_updates = p->varups,
.num_var_updates = p->num_varups,
.desc_bindings = p->binds,
.push_constants = params->push_constants,
-#if PL_API_VER >= 60
.timer = get_active_timer(ra),
-#endif
};
- if (p->pl_pass->params.type == PL_PASS_RASTER) {
+ if (p->pass->params.type == PL_PASS_RASTER) {
pl_params.target = params->target->priv;
pl_params.viewport = mp_rect2d_to_pl(params->viewport);
pl_params.scissors = mp_rect2d_to_pl(params->scissors);
@@ -666,12 +580,10 @@ static void renderpass_run_pl(struct ra *ra,
pl_pass_run(get_gpu(ra), &pl_params);
}
-#if PL_API_VER >= 60
-
struct ra_timer_pl {
// Because libpplacebo only supports one operation per timer, we need
// to use multiple pl_timers to sum up multiple passes/transfers
- struct pl_timer **timers;
+ pl_timer *timers;
int num_timers;
int idx_timers;
};
@@ -684,7 +596,7 @@ static ra_timer *timer_create_pl(struct ra *ra)
static void timer_destroy_pl(struct ra *ra, ra_timer *timer)
{
- const struct pl_gpu *gpu = get_gpu(ra);
+ pl_gpu gpu = get_gpu(ra);
struct ra_timer_pl *t = timer;
for (int i = 0; i < t->num_timers; i++)
@@ -726,7 +638,7 @@ static uint64_t timer_stop_pl(struct ra *ra, ra_timer *timer)
return res;
}
-static struct pl_timer *get_active_timer(const struct ra *ra)
+static pl_timer get_active_timer(const struct ra *ra)
{
struct ra_pl *p = ra->priv;
if (!p->active_timer)
@@ -739,8 +651,6 @@ static struct pl_timer *get_active_timer(const struct ra *ra)
return t->timers[t->idx_timers++];
}
-#endif // PL_API_VER >= 60
-
static struct ra_fns ra_fns_pl = {
.destroy = destroy_ra_pl,
.tex_create = tex_create_pl,
@@ -759,11 +669,9 @@ static struct ra_fns ra_fns_pl = {
.renderpass_create = renderpass_create_pl,
.renderpass_destroy = renderpass_destroy_pl,
.renderpass_run = renderpass_run_pl,
-#if PL_API_VER >= 60
.timer_create = timer_create_pl,
.timer_destroy = timer_destroy_pl,
.timer_start = timer_start_pl,
.timer_stop = timer_stop_pl,
-#endif
};