From 9581fbe56926c75e52bc015fa6146b7f11f3d6a3 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Sat, 5 Aug 2017 22:29:48 +0200 Subject: 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. --- video/out/opengl/ra.c | 12 +++++ video/out/opengl/ra.h | 55 +++++++++++++++------ video/out/opengl/ra_gl.c | 107 ++++++++++++++++++++++++++-------------- video/out/opengl/ra_gl.h | 6 +-- video/out/opengl/shader_cache.c | 17 ++++--- video/out/opengl/shader_cache.h | 2 +- video/out/opengl/video.c | 94 +++++++++++++++++------------------ 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, ¶ms); 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, ¶ms); + 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; } -- cgit v1.2.3