From c111fa68b85c34ff3469e9dabc685d967162a6c5 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Mon, 27 Nov 2017 02:19:48 -0800 Subject: [PATCH] libobs: Add vertex/index buffer "direct" flush functions (Note: This commit also modifies libobs-d3d11 and libobs-opengl) Allows the ability to flush data directly without having to use the buffer's internal data. Allows the caller to manage his/her own vertex/index buffer data if desired, working around the design flaw of having to rely on a vertex/index buffer's internal data. --- libobs-d3d11/d3d11-subsystem.cpp | 56 +++++++++++++++++++++-------- libobs-opengl/gl-indexbuffer.c | 16 +++++++-- libobs-opengl/gl-vertexbuffer.c | 51 +++++++++++++++++--------- libobs/graphics/graphics-imports.c | 2 ++ libobs/graphics/graphics-internal.h | 4 +++ libobs/graphics/graphics.c | 19 ++++++++++ libobs/graphics/graphics.h | 4 +++ 7 files changed, 118 insertions(+), 34 deletions(-) diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index 930b2ea50..452684bf5 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -1938,36 +1938,53 @@ void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer) delete vertbuffer; } -void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer) +static inline void gs_vertexbuffer_flush_internal(gs_vertbuffer_t *vertbuffer, + const gs_vb_data *data) { + size_t num_tex = data->num_tex < vertbuffer->uvBuffers.size() + ? data->num_tex + : vertbuffer->uvBuffers.size(); + if (!vertbuffer->dynamic) { blog(LOG_ERROR, "gs_vertexbuffer_flush: vertex buffer is " "not dynamic"); return; } - vertbuffer->FlushBuffer(vertbuffer->vertexBuffer, - vertbuffer->vbd.data->points, sizeof(vec3)); + if (data->points) + vertbuffer->FlushBuffer(vertbuffer->vertexBuffer, + data->points, sizeof(vec3)); - if (vertbuffer->normalBuffer) + if (vertbuffer->normalBuffer && data->normals) vertbuffer->FlushBuffer(vertbuffer->normalBuffer, - vertbuffer->vbd.data->normals, sizeof(vec3)); + data->normals, sizeof(vec3)); - if (vertbuffer->tangentBuffer) + if (vertbuffer->tangentBuffer && data->tangents) vertbuffer->FlushBuffer(vertbuffer->tangentBuffer, - vertbuffer->vbd.data->tangents, sizeof(vec3)); + data->tangents, sizeof(vec3)); - if (vertbuffer->colorBuffer) + if (vertbuffer->colorBuffer && data->colors) vertbuffer->FlushBuffer(vertbuffer->colorBuffer, - vertbuffer->vbd.data->colors, sizeof(uint32_t)); + data->colors, sizeof(uint32_t)); - for (size_t i = 0; i < vertbuffer->uvBuffers.size(); i++) { - gs_tvertarray &tv = vertbuffer->vbd.data->tvarray[i]; + for (size_t i = 0; i < num_tex; i++) { + gs_tvertarray &tv = data->tvarray[i]; vertbuffer->FlushBuffer(vertbuffer->uvBuffers[i], tv.array, tv.width*sizeof(float)); } } +void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer) +{ + gs_vertexbuffer_flush_internal(vertbuffer, vertbuffer->vbd.data); +} + +void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer, + const gs_vb_data *data) +{ + gs_vertexbuffer_flush_internal(vertbuffer, data); +} + struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vertbuffer) { return vertbuffer->vbd.data; @@ -1979,7 +1996,8 @@ void gs_indexbuffer_destroy(gs_indexbuffer_t *indexbuffer) delete indexbuffer; } -void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer) +static inline void gs_indexbuffer_flush_internal(gs_indexbuffer_t *indexbuffer, + const void *data) { HRESULT hr; @@ -1992,12 +2010,22 @@ void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer) if (FAILED(hr)) return; - memcpy(map.pData, indexbuffer->indices.data, - indexbuffer->num * indexbuffer->indexSize); + memcpy(map.pData, data, indexbuffer->num * indexbuffer->indexSize); indexbuffer->device->context->Unmap(indexbuffer->indexBuffer, 0); } +void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer) +{ + gs_indexbuffer_flush_internal(indexbuffer, indexbuffer->indices.data); +} + +void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer, + const void *data) +{ + gs_indexbuffer_flush_internal(indexbuffer, data); +} + void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer) { return indexbuffer->indices.data; diff --git a/libobs-opengl/gl-indexbuffer.c b/libobs-opengl/gl-indexbuffer.c index 2210fbc28..187835ea7 100644 --- a/libobs-opengl/gl-indexbuffer.c +++ b/libobs-opengl/gl-indexbuffer.c @@ -70,15 +70,15 @@ void gs_indexbuffer_destroy(gs_indexbuffer_t *ib) } } -void gs_indexbuffer_flush(gs_indexbuffer_t *ib) +static inline void gs_indexbuffer_flush_internal(gs_indexbuffer_t *ib, + const void *data) { if (!ib->dynamic) { blog(LOG_ERROR, "Index buffer is not dynamic"); goto fail; } - if (!update_buffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer, ib->data, - ib->size)) + if (!update_buffer(GL_ELEMENT_ARRAY_BUFFER, ib->buffer, data, ib->size)) goto fail; return; @@ -87,6 +87,16 @@ fail: blog(LOG_ERROR, "gs_indexbuffer_flush (GL) failed"); } +void gs_indexbuffer_flush(gs_indexbuffer_t *ib) +{ + gs_indexbuffer_flush_internal(ib, ib->data); +} + +void gs_indexbuffer_flush_direct(gs_indexbuffer_t *ib, const void *data) +{ + gs_indexbuffer_flush_internal(ib, data); +} + void *gs_indexbuffer_get_data(const gs_indexbuffer_t *ib) { return ib->data; diff --git a/libobs-opengl/gl-vertexbuffer.c b/libobs-opengl/gl-vertexbuffer.c index 62f2476a9..a56e6515a 100644 --- a/libobs-opengl/gl-vertexbuffer.c +++ b/libobs-opengl/gl-vertexbuffer.c @@ -120,45 +120,51 @@ void gs_vertexbuffer_destroy(gs_vertbuffer_t *vb) } } -void gs_vertexbuffer_flush(gs_vertbuffer_t *vb) +static inline void gs_vertexbuffer_flush_internal(gs_vertbuffer_t *vb, + const struct gs_vb_data *data) { size_t i; + size_t num_tex = data->num_tex < vb->data->num_tex + ? data->num_tex + : vb->data->num_tex; if (!vb->dynamic) { blog(LOG_ERROR, "vertex buffer is not dynamic"); goto failed; } - if (!update_buffer(GL_ARRAY_BUFFER, vb->vertex_buffer, - vb->data->points, - vb->data->num * sizeof(struct vec3))) - goto failed; + if (data->points) { + if (!update_buffer(GL_ARRAY_BUFFER, vb->vertex_buffer, + data->points, + data->num * sizeof(struct vec3))) + goto failed; + } - if (vb->normal_buffer) { + if (vb->normal_buffer && data->normals) { if (!update_buffer(GL_ARRAY_BUFFER, vb->normal_buffer, - vb->data->normals, - vb->data->num * sizeof(struct vec3))) + data->normals, + data->num * sizeof(struct vec3))) goto failed; } - if (vb->tangent_buffer) { + if (vb->tangent_buffer && data->tangents) { if (!update_buffer(GL_ARRAY_BUFFER, vb->tangent_buffer, - vb->data->tangents, - vb->data->num * sizeof(struct vec3))) + data->tangents, + data->num * sizeof(struct vec3))) goto failed; } - if (vb->color_buffer) { + if (vb->color_buffer && data->colors) { if (!update_buffer(GL_ARRAY_BUFFER, vb->color_buffer, - vb->data->colors, - vb->data->num * sizeof(uint32_t))) + data->colors, + data->num * sizeof(uint32_t))) goto failed; } - for (i = 0; i < vb->data->num_tex; i++) { + for (i = 0; i < num_tex; i++) { GLuint buffer = vb->uv_buffers.array[i]; - struct gs_tvertarray *tv = vb->data->tvarray+i; - size_t size = vb->data->num * tv->width * sizeof(float); + struct gs_tvertarray *tv = data->tvarray+i; + size_t size = data->num * tv->width * sizeof(float); if (!update_buffer(GL_ARRAY_BUFFER, buffer, tv->array, size)) goto failed; @@ -170,6 +176,17 @@ failed: blog(LOG_ERROR, "gs_vertexbuffer_flush (GL) failed"); } +void gs_vertexbuffer_flush(gs_vertbuffer_t *vb) +{ + gs_vertexbuffer_flush_internal(vb, vb->data); +} + +void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vb, + const struct gs_vb_data *data) +{ + gs_vertexbuffer_flush_internal(vb, data); +} + struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vb) { return vb->data; diff --git a/libobs/graphics/graphics-imports.c b/libobs/graphics/graphics-imports.c index 6d00b9af3..63c19ab11 100644 --- a/libobs/graphics/graphics-imports.c +++ b/libobs/graphics/graphics-imports.c @@ -141,10 +141,12 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT(gs_vertexbuffer_destroy); GRAPHICS_IMPORT(gs_vertexbuffer_flush); + GRAPHICS_IMPORT(gs_vertexbuffer_flush_direct); GRAPHICS_IMPORT(gs_vertexbuffer_get_data); GRAPHICS_IMPORT(gs_indexbuffer_destroy); GRAPHICS_IMPORT(gs_indexbuffer_flush); + GRAPHICS_IMPORT(gs_indexbuffer_flush_direct); GRAPHICS_IMPORT(gs_indexbuffer_get_data); GRAPHICS_IMPORT(gs_indexbuffer_get_num_indices); GRAPHICS_IMPORT(gs_indexbuffer_get_type); diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index f009cc791..6be06d515 100644 --- a/libobs/graphics/graphics-internal.h +++ b/libobs/graphics/graphics-internal.h @@ -189,11 +189,15 @@ struct gs_exports { void (*gs_vertexbuffer_destroy)(gs_vertbuffer_t *vertbuffer); void (*gs_vertexbuffer_flush)(gs_vertbuffer_t *vertbuffer); + void (*gs_vertexbuffer_flush_direct)(gs_vertbuffer_t *vertbuffer, + const struct gs_vb_data *data); struct gs_vb_data *(*gs_vertexbuffer_get_data)( const gs_vertbuffer_t *vertbuffer); void (*gs_indexbuffer_destroy)(gs_indexbuffer_t *indexbuffer); void (*gs_indexbuffer_flush)(gs_indexbuffer_t *indexbuffer); + void (*gs_indexbuffer_flush_direct)(gs_indexbuffer_t *indexbuffer, + const void *data); void *(*gs_indexbuffer_get_data)(const gs_indexbuffer_t *indexbuffer); size_t (*gs_indexbuffer_get_num_indices)( const gs_indexbuffer_t *indexbuffer); diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index 191a0fc81..00c1a8795 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -2477,6 +2477,16 @@ void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer) thread_graphics->exports.gs_vertexbuffer_flush(vertbuffer); } +void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer, + const struct gs_vb_data *data) +{ + if (!gs_valid_p2("gs_vertexbuffer_flush_direct", vertbuffer, data)) + return; + + thread_graphics->exports.gs_vertexbuffer_flush_direct(vertbuffer, + data); +} + struct gs_vb_data *gs_vertexbuffer_get_data(const gs_vertbuffer_t *vertbuffer) { if (!gs_valid_p("gs_vertexbuffer_get_data", vertbuffer)) @@ -2505,6 +2515,15 @@ void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer) thread_graphics->exports.gs_indexbuffer_flush(indexbuffer); } +void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer, + const void *data) +{ + if (!gs_valid_p2("gs_indexbuffer_flush_direct", indexbuffer, data)) + return; + + thread_graphics->exports.gs_indexbuffer_flush_direct(indexbuffer, data); +} + void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer) { if (!gs_valid_p("gs_indexbuffer_get_data", indexbuffer)) diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index 505b04bbc..d619c3a69 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -718,11 +718,15 @@ EXPORT void gs_samplerstate_destroy(gs_samplerstate_t *samplerstate); EXPORT void gs_vertexbuffer_destroy(gs_vertbuffer_t *vertbuffer); EXPORT void gs_vertexbuffer_flush(gs_vertbuffer_t *vertbuffer); +EXPORT void gs_vertexbuffer_flush_direct(gs_vertbuffer_t *vertbuffer, + const struct gs_vb_data *data); EXPORT struct gs_vb_data *gs_vertexbuffer_get_data( const gs_vertbuffer_t *vertbuffer); EXPORT void gs_indexbuffer_destroy(gs_indexbuffer_t *indexbuffer); EXPORT void gs_indexbuffer_flush(gs_indexbuffer_t *indexbuffer); +EXPORT void gs_indexbuffer_flush_direct(gs_indexbuffer_t *indexbuffer, + const void *data); EXPORT void *gs_indexbuffer_get_data(const gs_indexbuffer_t *indexbuffer); EXPORT size_t gs_indexbuffer_get_num_indices( const gs_indexbuffer_t *indexbuffer);