summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.xyz>2017-08-05 22:29:48 +0200
committerNiklas Haas <git@haasn.xyz>2017-08-07 12:46:30 +0200
commit9581fbe56926c75e52bc015fa6146b7f11f3d6a3 (patch)
tree252ff1098cd07bc5ae56770eecf0a3c0549435a5
parent207458c7a9b682185a82ee23910c1327a70d276b (diff)
downloadmpv-9581fbe56926c75e52bc015fa6146b7f11f3d6a3.tar.bz2
mpv-9581fbe56926c75e52bc015fa6146b7f11f3d6a3.tar.xz
vo_opengl: generalize ra_buf to support other buffer objects
This allows us to integrate PBOs and SSBOs into the same abstraction, with the potential to easily add UBOs if the need arises.
-rw-r--r--video/out/opengl/ra.c12
-rw-r--r--video/out/opengl/ra.h55
-rw-r--r--video/out/opengl/ra_gl.c107
-rw-r--r--video/out/opengl/ra_gl.h6
-rw-r--r--video/out/opengl/shader_cache.c17
-rw-r--r--video/out/opengl/shader_cache.h2
-rw-r--r--video/out/opengl/video.c94
7 files changed, 182 insertions, 111 deletions
diff --git a/video/out/opengl/ra.c b/video/out/opengl/ra.c
index e67dd6ebdf..31f585fdf9 100644
--- a/video/out/opengl/ra.c
+++ b/video/out/opengl/ra.c
@@ -16,6 +16,18 @@ void ra_tex_free(struct ra *ra, struct ra_tex **tex)
*tex = NULL;
}
+struct ra_buf *ra_buf_create(struct ra *ra, const struct ra_buf_params *params)
+{
+ return ra->fns->buf_create(ra, params);
+}
+
+void ra_buf_free(struct ra *ra, struct ra_buf **buf)
+{
+ if (*buf)
+ ra->fns->buf_destroy(ra, *buf);
+ *buf = NULL;
+}
+
static size_t vartype_size(enum ra_vartype type)
{
switch (type) {
diff --git a/video/out/opengl/ra.h b/video/out/opengl/ra.h
index c60d75d47c..e93061eb61 100644
--- a/video/out/opengl/ra.h
+++ b/video/out/opengl/ra.h
@@ -37,6 +37,7 @@ enum {
RA_CAP_BLIT = 1 << 2, // supports ra_fns.blit
RA_CAP_COMPUTE = 1 << 3, // supports compute shaders
RA_CAP_PBO = 1 << 4, // supports ra.use_pbo
+ RA_CAP_BUF_RW = 1 << 5, // supports RA_VARTYPE_BUF_RW
RA_CAP_NESTED_ARRAY = 1 << 5,
};
@@ -107,13 +108,31 @@ struct ra_tex {
void *priv;
};
-// A persistent mapping, which can be used for texture upload.
-struct ra_mapped_buffer {
- // All fields are read-only after creation. The data is read/write, but
- // requires explicit fence usage.
+// Buffer type hint. Setting this may result in more or less efficient
+// operation, although it shouldn't technically prohibit anything
+enum ra_buf_type {
+ RA_BUF_TYPE_INVALID,
+ RA_BUF_TYPE_TEX_UPLOAD, // texture upload buffer (pixel buffer object)
+ RA_BUF_TYPE_SHADER_STORAGE // shader buffer, used for RA_VARTYPE_BUF_RW
+};
+
+struct ra_buf_params {
+ enum ra_buf_type type;
+ size_t size;
+ // Creates a read-writable persistent mapping (ra_buf.data)
+ bool host_mapped;
+ // If non-NULL, the buffer will be created with these contents. Otherwise,
+ // the initial data is undefined.
+ void *initial_data;
+};
+
+// A generic buffer, which can be used for many purposes (texture upload,
+// storage buffer, uniform buffer, etc.)
+struct ra_buf {
+ // All fields are read-only after creation.
+ struct ra_buf_params params;
+ void *data; // for persistently mapped buffers, points to the first byte
void *priv;
- void *data; // pointer to first usable byte
- size_t size; // total size of the mapping, starting at data
};
// Type of a shader uniform variable, or a vertex attribute. In all cases,
@@ -127,7 +146,7 @@ enum ra_vartype {
RA_VARTYPE_IMG_W, // C: ra_tex*, GLSL: various image types
// write-only (W) image for compute shaders
RA_VARTYPE_BYTE_UNORM, // C: uint8_t, GLSL: int, vec* (vertex data only)
- RA_VARTYPE_SSBO, // a hack for GL
+ RA_VARTYPE_BUF_RW, // C: ra_buf*, GLSL: buffer block
};
// Represents a uniform, texture input parameter, and similar things.
@@ -140,7 +159,7 @@ struct ra_renderpass_input {
// Vertex data: byte offset of the attribute into the vertex struct
// RA_VARTYPE_TEX: texture unit
// RA_VARTYPE_IMG_W: image unit
- // RA_VARTYPE_SSBO: whatever?
+ // RA_VARTYPE_BUF_* buffer binding point
// Other uniforms: unused
int binding;
};
@@ -304,20 +323,23 @@ struct ra_fns {
void (*tex_upload)(struct ra *ra, struct ra_tex *tex,
const void *src, ptrdiff_t stride,
struct mp_rect *region, uint64_t flags,
- struct ra_mapped_buffer *buf);
+ struct ra_buf *buf);
- // Create a persistently mapped buffer for tex_upload.
- // Optional, can be NULL or return NULL if unavailable.
- struct ra_mapped_buffer *(*create_mapped_buffer)(struct ra *ra, size_t size);
+ // Create a buffer. This can be used as a persistently mapped buffer,
+ // a uniform buffer, a shader storage buffer or possibly others.
+ // Not all usage types must be supported; may return NULL if unavailable.
+ struct ra_buf *(*buf_create)(struct ra *ra,
+ const struct ra_buf_params *params);
- void (*destroy_mapped_buffer)(struct ra *ra, struct ra_mapped_buffer *buf);
+ void (*buf_destroy)(struct ra *ra, struct ra_buf *buf);
// Essentially a fence: once the GPU uses the mapping for read-access (e.g.
// by starting a texture upload), the host must not write to the mapped
// data until an internal object has been signalled. This call returns
// whether it was signalled yet. If true, write accesses are allowed again.
- // Optional, only available if flush_mapping is.
- bool (*poll_mapped_buffer)(struct ra *ra, struct ra_mapped_buffer *buf);
+ // Optional, may be NULL if unavailable. This is only usable for buffers
+ // which have been persistently mapped.
+ bool (*poll_mapped_buffer)(struct ra *ra, struct ra_buf *buf);
// Clear the dst with the given color (rgba) and within the given scissor.
// dst must have dst->params.render_dst==true. Content outside of the
@@ -374,6 +396,9 @@ struct ra_fns {
struct ra_tex *ra_tex_create(struct ra *ra, const struct ra_tex_params *params);
void ra_tex_free(struct ra *ra, struct ra_tex **tex);
+struct ra_buf *ra_buf_create(struct ra *ra, const struct ra_buf_params *params);
+void ra_buf_free(struct ra *ra, struct ra_buf **buf);
+
const struct ra_format *ra_find_unorm_format(struct ra *ra,
int bytes_per_component,
int n_components);
diff --git a/video/out/opengl/ra_gl.c b/video/out/opengl/ra_gl.c
index 4c99fe0f59..3966afcebb 100644
--- a/video/out/opengl/ra_gl.c
+++ b/video/out/opengl/ra_gl.c
@@ -30,6 +30,8 @@ int ra_init_gl(struct ra *ra, GL *gl)
ra->caps |= RA_CAP_PBO;
if (gl->mpgl_caps & MPGL_CAP_NESTED_ARRAY)
ra->caps |= RA_CAP_NESTED_ARRAY;
+ if (gl->mpgl_caps & MPGL_CAP_SSBO)
+ ra->caps |= RA_CAP_BUF_RW;
ra->glsl_version = gl->glsl_version;
ra->glsl_es = gl->es > 0;
@@ -329,16 +331,16 @@ GL *ra_gl_get(struct ra *ra)
static void gl_tex_upload(struct ra *ra, struct ra_tex *tex,
const void *src, ptrdiff_t stride,
struct mp_rect *rc, uint64_t flags,
- struct ra_mapped_buffer *buf)
+ struct ra_buf *buf)
{
GL *gl = ra_gl_get(ra);
struct ra_tex_gl *tex_gl = tex->priv;
- struct ra_mapped_buffer_gl *buf_gl = NULL;
+ struct ra_buf_gl *buf_gl = NULL;
struct mp_rect full = {0, 0, tex->params.w, tex->params.h};
if (buf) {
buf_gl = buf->priv;
- gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, buf_gl->pbo);
+ gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, buf_gl->buffer);
src = (void *)((uintptr_t)src - (uintptr_t)buf->data);
}
@@ -380,57 +382,87 @@ static void gl_tex_upload(struct ra *ra, struct ra_tex *tex,
}
}
-static void gl_destroy_mapped_buffer(struct ra *ra, struct ra_mapped_buffer *buf)
+static void gl_buf_destroy(struct ra *ra, struct ra_buf *buf)
{
+ if (!buf)
+ return;
+
GL *gl = ra_gl_get(ra);
- struct ra_mapped_buffer_gl *buf_gl = buf->priv;
+ struct ra_buf_gl *buf_gl = buf->priv;
gl->DeleteSync(buf_gl->fence);
- gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, buf_gl->pbo);
- if (buf->data)
- gl->UnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
- gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- gl->DeleteBuffers(1, &buf_gl->pbo);
+ if (buf->data) {
+ // The target type used here doesn't matter at all to OpenGL
+ gl->BindBuffer(GL_ARRAY_BUFFER, buf_gl->buffer);
+ gl->UnmapBuffer(GL_ARRAY_BUFFER);
+ gl->BindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ gl->DeleteBuffers(1, &buf_gl->buffer);
talloc_free(buf_gl);
talloc_free(buf);
}
-static struct ra_mapped_buffer *gl_create_mapped_buffer(struct ra *ra,
- size_t size)
+static struct ra_buf *gl_buf_create(struct ra *ra,
+ const struct ra_buf_params *params)
{
GL *gl = ra_gl_get(ra);
- if (gl->version < 440)
+ if (params->host_mapped && gl->version < 440)
return NULL;
- struct ra_mapped_buffer *buf = talloc_zero(NULL, struct ra_mapped_buffer);
- buf->size = size;
+ struct ra_buf *buf = talloc_zero(NULL, struct ra_buf);
+ buf->params = *params;
+ buf->params.initial_data = NULL;
- struct ra_mapped_buffer_gl *buf_gl = buf->priv =
- talloc_zero(NULL, struct ra_mapped_buffer_gl);
+ struct ra_buf_gl *buf_gl = buf->priv = talloc_zero(NULL, struct ra_buf_gl);
+ gl->GenBuffers(1, &buf_gl->buffer);
- unsigned flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT |
- GL_MAP_COHERENT_BIT;
+ GLenum target;
+ switch (params->type) {
+ case RA_BUF_TYPE_TEX_UPLOAD: target = GL_PIXEL_UNPACK_BUFFER; break;
+ case RA_BUF_TYPE_SHADER_STORAGE: target = GL_SHADER_STORAGE_BUFFER; break;
+ default: abort();
+ };
- gl->GenBuffers(1, &buf_gl->pbo);
- gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, buf_gl->pbo);
- gl->BufferStorage(GL_PIXEL_UNPACK_BUFFER, size, NULL, flags | GL_CLIENT_STORAGE_BIT);
- buf->data = gl->MapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, buf->size, flags);
- gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- if (!buf->data) {
- gl_check_error(gl, ra->log, "mapping buffer");
- gl_destroy_mapped_buffer(ra, buf);
- return NULL;
+ gl->BindBuffer(target, buf_gl->buffer);
+
+ if (params->host_mapped) {
+ unsigned flags = GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT |
+ GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
+
+ unsigned storflags = flags;
+ if (params->type == RA_BUF_TYPE_TEX_UPLOAD)
+ storflags |= GL_CLIENT_STORAGE_BIT;
+
+ gl->BufferStorage(target, params->size, params->initial_data, storflags);
+ buf->data = gl->MapBufferRange(target, 0, params->size, flags);
+ if (!buf->data) {
+ gl_check_error(gl, ra->log, "mapping buffer");
+ gl_buf_destroy(ra, buf);
+ buf = NULL;
+ }
+ } else {
+ GLenum hint;
+ switch (params->type) {
+ case RA_BUF_TYPE_TEX_UPLOAD: hint = GL_STREAM_DRAW; break;
+ case RA_BUF_TYPE_SHADER_STORAGE: hint = GL_STREAM_COPY; break;
+ default: abort();
+ }
+
+ gl->BufferData(target, params->size, params->initial_data, hint);
}
+ gl->BindBuffer(target, 0);
return buf;
}
-static bool gl_poll_mapped_buffer(struct ra *ra, struct ra_mapped_buffer *buf)
+static bool gl_poll_mapped_buffer(struct ra *ra, struct ra_buf *buf)
{
+ assert(buf->data);
+
GL *gl = ra_gl_get(ra);
- struct ra_mapped_buffer_gl *buf_gl = buf->priv;
+ struct ra_buf_gl *buf_gl = buf->priv;
if (buf_gl->fence) {
GLenum res = gl->ClientWaitSync(buf_gl->fence, 0, 0); // non-blocking
@@ -743,9 +775,11 @@ static void update_uniform(struct ra *ra, struct ra_renderpass *pass,
}
break;
}
- case RA_VARTYPE_SSBO: {
- gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, input->binding,
- *(int *)val->data);
+ case RA_VARTYPE_BUF_RW: {
+ struct ra_buf *buf = *(struct ra_buf **)val->data;
+ struct ra_buf_gl *buf_gl = buf->priv;
+ gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, input->binding, buf_gl->buffer);
+ gl->MemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
break;
}
default:
@@ -775,11 +809,10 @@ static void disable_binding(struct ra *ra, struct ra_renderpass *pass,
}
break;
}
- case RA_VARTYPE_SSBO: {
+ case RA_VARTYPE_BUF_RW:
gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, input->binding, 0);
break;
}
- }
}
static void gl_renderpass_run(struct ra *ra,
@@ -915,8 +948,8 @@ static struct ra_fns ra_fns_gl = {
.tex_create = gl_tex_create,
.tex_destroy = gl_tex_destroy,
.tex_upload = gl_tex_upload,
- .create_mapped_buffer = gl_create_mapped_buffer,
- .destroy_mapped_buffer = gl_destroy_mapped_buffer,
+ .buf_create = gl_buf_create,
+ .buf_destroy = gl_buf_destroy,
.poll_mapped_buffer = gl_poll_mapped_buffer,
.clear = gl_clear,
.blit = gl_blit,
diff --git a/video/out/opengl/ra_gl.h b/video/out/opengl/ra_gl.h
index 0d3828c978..6270daba92 100644
--- a/video/out/opengl/ra_gl.h
+++ b/video/out/opengl/ra_gl.h
@@ -22,9 +22,9 @@ struct ra_tex_gl {
struct gl_pbo_upload pbo;
};
-// For ra_mapped_buffer.priv
-struct ra_mapped_buffer_gl {
- GLuint pbo;
+// For ra_buf.priv
+struct ra_buf_gl {
+ GLuint buffer;
GLsync fence;
};
diff --git a/video/out/opengl/shader_cache.c b/video/out/opengl/shader_cache.c
index 68d9d4cab2..050d01d36d 100644
--- a/video/out/opengl/shader_cache.c
+++ b/video/out/opengl/shader_cache.c
@@ -22,15 +22,16 @@
union uniform_val {
float f[9]; // RA_VARTYPE_FLOAT
- int i[4]; // RA_VARTYPE_INT, RA_VARTYPE_SSBO
+ int i[4]; // RA_VARTYPE_INT
struct ra_tex *tex; // RA_VARTYPE_TEX, RA_VARTYPE_IMG_*
+ struct ra_buf *buf; // RA_VARTYPE_BUF_*
};
struct sc_uniform {
struct ra_renderpass_input input;
const char *glsl_type;
union uniform_val v;
- char *ssbo_format;
+ char *buffer_format;
};
struct sc_cached_uniform {
@@ -264,20 +265,20 @@ void gl_sc_uniform_image2D_wo(struct gl_shader_cache *sc, const char *name,
u->v.tex = tex;
}
-void gl_sc_ssbo(struct gl_shader_cache *sc, char *name, int gl_ssbo,
+void gl_sc_ssbo(struct gl_shader_cache *sc, char *name, struct ra_buf *buf,
char *format, ...)
{
gl_sc_enable_extension(sc, "GL_ARB_shader_storage_buffer_object");
struct sc_uniform *u = find_uniform(sc, name);
- u->input.type = RA_VARTYPE_SSBO;
+ u->input.type = RA_VARTYPE_BUF_RW;
u->glsl_type = "";
u->input.binding = sc->next_buffer_binding++;
- u->v.i[0] = gl_ssbo;
+ u->v.buf = buf;
va_list ap;
va_start(ap, format);
- u->ssbo_format = ta_vasprintf(sc, format, ap);
+ u->buffer_format = ta_vasprintf(sc, format, ap);
va_end(ap);
}
@@ -516,9 +517,9 @@ static void add_uniforms(struct gl_shader_cache *sc, bstr *dst)
case RA_VARTYPE_IMG_W:
ADD(dst, "uniform %s %s;\n", u->glsl_type, u->input.name);
break;
- case RA_VARTYPE_SSBO:
+ case RA_VARTYPE_BUF_RW:
ADD(dst, "layout(std430, binding=%d) buffer %s { %s };\n",
- u->input.binding, u->input.name, u->ssbo_format);
+ u->input.binding, u->input.name, u->buffer_format);
break;
default: abort();
}
diff --git a/video/out/opengl/shader_cache.h b/video/out/opengl/shader_cache.h
index c4fcefc391..d5d512d779 100644
--- a/video/out/opengl/shader_cache.h
+++ b/video/out/opengl/shader_cache.h
@@ -26,7 +26,7 @@ void gl_sc_uniform_texture(struct gl_shader_cache *sc, char *name,
struct ra_tex *tex);
void gl_sc_uniform_image2D_wo(struct gl_shader_cache *sc, const char *name,
struct ra_tex *tex);
-void gl_sc_ssbo(struct gl_shader_cache *sc, char *name, int gl_ssbo,
+void gl_sc_ssbo(struct gl_shader_cache *sc, char *name, struct ra_buf *buf,
char *format, ...) PRINTF_ATTRIBUTE(4, 5);
void gl_sc_uniform_f(struct gl_shader_cache *sc, char *name, float f);
void gl_sc_uniform_i(struct gl_shader_cache *sc, char *name, int f);
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index 8c90a11376..c044e62664 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -169,7 +169,7 @@ struct pass_info {
#define PASS_INFO_MAX (SHADER_MAX_PASSES + 32)
struct dr_buffer {
- struct ra_mapped_buffer *buffer;
+ struct ra_buf *buf;
// The mpi reference will keep the data from being recycled (or from other
// references gaining write access) while the GPU is accessing the buffer.
struct mp_image *mpi;
@@ -230,7 +230,7 @@ struct gl_video {
struct fbotex output_fbo;
struct fbosurface surfaces[FBOSURFACES_MAX];
struct fbotex vdpau_deinterleave_fbo[2];
- GLuint hdr_peak_ssbo;
+ struct ra_buf *hdr_peak_ssbo;
// user pass descriptions and textures
struct tex_hook tex_hooks[SHADER_MAX_PASSES];
@@ -933,9 +933,9 @@ static struct dr_buffer *gl_find_dr_buffer(struct gl_video *p, uint8_t *ptr)
{
for (int i = 0; i < p->num_dr_buffers; i++) {
struct dr_buffer *buffer = &p->dr_buffers[i];
- uint8_t *buf = buffer->buffer->data;
- size_t size = buffer->buffer->size;
- if (ptr >= buf && ptr < buf + size)
+ uint8_t *bufptr = buffer->buf->data;
+ size_t size = buffer->buf->params.size;
+ if (ptr >= bufptr && ptr < bufptr + size)
return buffer;
}
@@ -950,7 +950,7 @@ again:;
if (!buffer->mpi)
continue;
- bool res = p->ra->fns->poll_mapped_buffer(p->ra, buffer->buffer);
+ bool res = p->ra->fns->poll_mapped_buffer(p->ra, buffer->buf);
if (res || force) {
// Unreferencing the image could cause gl_video_dr_free_buffer()
// to be called by the talloc destructor (if it was the last
@@ -2388,7 +2388,7 @@ static void pass_scale_main(struct gl_video *p)
// by previous passes (i.e. linear scaling)
static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool osd)
{
- GL *gl = p->gl;
+ struct ra *ra = p->ra;
// Figure out the target color space from the options, or auto-guess if
// none were set
@@ -2450,31 +2450,35 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool
}
bool detect_peak = p->opts.compute_hdr_peak && mp_trc_is_hdr(src.gamma);
- if (detect_peak) {
- pass_describe(p, "detect HDR peak");
- pass_is_compute(p, 8, 8); // 8x8 is good for performance
+ if (detect_peak && !p->hdr_peak_ssbo) {
+ struct {
+ unsigned int sig_peak_raw;
+ unsigned int index;
+ unsigned int frame_max[PEAK_DETECT_FRAMES+1];
+ } peak_ssbo = {0};
+
+ // Prefill with safe values
+ int safe = MP_REF_WHITE * mp_trc_nom_peak(p->image_params.color.gamma);
+ peak_ssbo.sig_peak_raw = PEAK_DETECT_FRAMES * safe;
+ for (int i = 0; i < PEAK_DETECT_FRAMES+1; i++)
+ peak_ssbo.frame_max[i] = safe;
+
+ struct ra_buf_params params = {
+ .type = RA_BUF_TYPE_SHADER_STORAGE,
+ .size = sizeof(peak_ssbo),
+ .initial_data = &peak_ssbo,
+ };
+ p->hdr_peak_ssbo = ra_buf_create(ra, &params);
if (!p->hdr_peak_ssbo) {
- struct {
- GLuint sig_peak_raw;
- GLuint index;
- GLuint frame_max[PEAK_DETECT_FRAMES+1];
- } peak_ssbo = {0};
-
- // Prefill with safe values
- int safe = MP_REF_WHITE * mp_trc_nom_peak(p->image_params.color.gamma);
- peak_ssbo.sig_peak_raw = PEAK_DETECT_FRAMES * safe;
- for (int i = 0; i < PEAK_DETECT_FRAMES+1; i++)
- peak_ssbo.frame_max[i] = safe;
-
- gl->GenBuffers(1, &p->hdr_peak_ssbo);
- gl->BindBuffer(GL_SHADER_STORAGE_BUFFER, p->hdr_peak_ssbo);
- gl->BufferData(GL_SHADER_STORAGE_BUFFER, sizeof(peak_ssbo),
- &peak_ssbo, GL_STREAM_COPY);
- gl->BindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
+ MP_WARN(p, "Failed to create HDR peak detection SSBO, disabling.\n");
+ detect_peak = (p->opts.compute_hdr_peak = false);
}
+ }
- gl->MemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
+ if (detect_peak) {
+ pass_describe(p, "detect HDR peak");
+ pass_is_compute(p, 8, 8); // 8x8 is good for performance
gl_sc_ssbo(p->sc, "PeakDetect", p->hdr_peak_ssbo,
"uint sig_peak_raw;"
"uint index;"
@@ -3304,7 +3308,7 @@ static bool pass_upload_image(struct gl_video *p, struct mp_image *mpi, uint64_t
p->ra->fns->tex_upload(p->ra, plane->tex, mpi->planes[n],
mpi->stride[n], NULL, 0,
- mapped ? mapped->buffer : NULL);
+ mapped ? mapped->buf : NULL);
if (mapped && !mapped->mpi)
mapped->mpi = mp_image_new_ref(mpi);
@@ -3377,7 +3381,7 @@ static void check_gl_features(struct gl_video *p)
bool have_mglsl = ra->glsl_version >= 130; // modern GLSL
bool have_texrg = gl->mpgl_caps & MPGL_CAP_TEX_RG;
bool have_compute = ra->caps & RA_CAP_COMPUTE;
- bool have_ssbo = gl->mpgl_caps & MPGL_CAP_SSBO;
+ bool have_ssbo = ra->caps & RA_CAP_BUF_RW;
const char *auto_fbo_fmts[] = {"rgba16", "rgba16f", "rgb10_a2", "rgba8", 0};
const char *user_fbo_fmts[] = {p->opts.fbo_format, 0};
@@ -3516,7 +3520,7 @@ void gl_video_uninit(struct gl_video *p)
gl_sc_destroy(p->sc);
ra_tex_free(p->ra, &p->lut_3d_texture);
- gl->DeleteBuffers(1, &p->hdr_peak_ssbo);
+ ra_buf_free(p->ra, &p->hdr_peak_ssbo);
timer_pool_destroy(p->upload_timer);
timer_pool_destroy(p->blit_timer);
@@ -3802,33 +3806,29 @@ void gl_video_set_hwdec(struct gl_video *p, struct gl_hwdec *hwdec)
void *gl_video_dr_alloc_buffer(struct gl_video *p, size_t size)
{
- if (!p->ra->fns->create_mapped_buffer)
- return NULL;
-
- MP_TARRAY_GROW(p, p->dr_buffers, p->num_dr_buffers);
- int index = p->num_dr_buffers++;
- struct dr_buffer *buffer = &p->dr_buffers[index];
-
- *buffer = (struct dr_buffer){
- .buffer = p->ra->fns->create_mapped_buffer(p->ra, size),
+ struct ra_buf_params params = {
+ .type = RA_BUF_TYPE_TEX_UPLOAD,
+ .host_mapped = true,
+ .size = size,
};
- if (!buffer->buffer) {
- MP_TARRAY_REMOVE_AT(p->dr_buffers, p->num_dr_buffers, index);
+ struct ra_buf *buf = ra_buf_create(p->ra, &params);
+ if (!buf)
return NULL;
- }
- return buffer->buffer->data;
+ MP_TARRAY_GROW(p, p->dr_buffers, p->num_dr_buffers);
+ p->dr_buffers[p->num_dr_buffers++] = (struct dr_buffer){ .buf = buf };
+
+ return buf->data;
};
void gl_video_dr_free_buffer(struct gl_video *p, void *ptr)
{
for (int n = 0; n < p->num_dr_buffers; n++) {
struct dr_buffer *buffer = &p->dr_buffers[n];
- if (buffer->buffer->data == ptr) {
+ if (buffer->buf->data == ptr) {
assert(!buffer->mpi); // can't be freed while it has a ref
- p->ra->fns->destroy_mapped_buffer(p->ra, buffer->buffer);
-
+ ra_buf_free(p->ra, &buffer->buf);
MP_TARRAY_REMOVE_AT(p->dr_buffers, p->num_dr_buffers, n);
return;
}