diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-03-21 10:49:05 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-03-21 12:25:20 +0000 |
| commit | a406de7cf8564ee6db177275f41f9264482d5671 (patch) | |
| tree | 64fc23eac3f68a99d58fcda0340664296c406c9b | |
| parent | with unpatched love2d (diff) | |
| download | lua-texture-share-vk-a406de7cf8564ee6db177275f41f9264482d5671.tar.gz lua-texture-share-vk-a406de7cf8564ee6db177275f41f9264482d5671.zip | |
as lib
| -rw-r--r-- | main.lua | 130 | ||||
| -rw-r--r-- | texture_share_vk.lua | 172 |
2 files changed, 180 insertions, 122 deletions
@@ -1,110 +1,9 @@ -local ffi = require 'ffi' - --- from -local VK_SERVER_EXECUTABLE = "/usr/bin/texture-share-vk-server" -local VK_SERVER_DEFAULT_LOCKFILE_PATH = "/tmp/vk_server/vk_server.lock" -local VK_SERVER_DEFAULT_SOCKET_PATH = "/tmp/vk_server/vk_server.sock" -local VK_SERVER_DEFAULT_SHMEM_PREFIX = "shmem_img_" - --- from gl.h -local GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1 -local GL_COLOR_ATTACHMENT0 = 0x8CE0 -local GL_FRAMEBUFFER = 0x8D40 -local GL_TEXTURE_2D = 0x0DE1 - -ffi.cdef [[ -// gl.h -typedef int GLint; -typedef unsigned int GLuint; -typedef unsigned int GLenum; - -void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, - GLenum pname, GLint *params); - -// texture_share_ipc.h -typedef enum ImgFormat { - R8G8B8A8, - R8G8B8, - B8G8R8A8, - B8G8R8, - Undefined, -} ImgFormat; - -// texture_share_gl_client.h -typedef enum ImageLookupResult { - Error = -1, - NotFound = 0, - Found = 1, - RequiresUpdate = 2, -} ImageLookupResult; - -typedef struct ClientImageDataGuard ClientImageDataGuard; - -typedef struct GlClient GlClient; - -typedef struct GlImageExtent { - GLint top_left[2]; - GLint bottom_right[2]; -} GlImageExtent; - -bool gl_client_initialize_external_gl(void); - -struct GlClient *gl_client_new(const char *socket_path, uint64_t timeout_in_millis); -struct GlClient *gl_client_new_with_server_launch(const char *socket_path, - uint64_t client_timeout_in_millis, - const char *server_program, - const char *server_lock_path, - const char *server_socket_path, - const char *shmem_prefix, - uint64_t server_socket_timeout_in_millis, - uint64_t server_connection_wait_timeout_in_millis, - uint64_t server_ipc_timeout_in_millis, - uint64_t server_lockfile_timeout_in_millis, - uint64_t server_spawn_timeout_in_millis); - -void gl_client_destroy(struct GlClient *gl_client); - -enum ImageLookupResult gl_client_init_image(struct GlClient *gl_client, - const char *image_name, - uint32_t width, - uint32_t height, - ImgFormat format, - bool overwrite_existing); - -int gl_client_send_image(struct GlClient *gl_client, - const char *image_name, - GLuint src_texture_id, - GLenum src_texture_target, - bool invert, - GLuint prev_fbo, - const struct GlImageExtent *extents); -]] -local tvs = ffi.load("texture_share_gl_client") -local gl = ffi.load("GL") - -local width, height -local canvas -local client, image +local tvs = require 'texture_share_vk' +local client, shared function love.load() - width, height = love.graphics.getDimensions() - canvas = love.graphics.newCanvas(width, height) - - assert(tvs.gl_client_initialize_external_gl(), "no init") - client = assert(tvs.gl_client_new_with_server_launch( - VK_SERVER_DEFAULT_SOCKET_PATH, - 1000, - VK_SERVER_EXECUTABLE, - VK_SERVER_DEFAULT_LOCKFILE_PATH, - VK_SERVER_DEFAULT_SOCKET_PATH, - VK_SERVER_DEFAULT_SHMEM_PREFIX, - 2000, - 2000, - 2000, - 2000, - 2000 - ), "failed to connect or launch tsv server") - image = assert(tvs.gl_client_init_image(client, "love2d", width, height, ffi.C.R8G8B8A8, true) > 0) + client = tvs.new() + shared = client:newSharedCanvas("love2d", love.graphics.getDimensions()) end local angle = 0 @@ -114,31 +13,18 @@ function love.update(dt) end function love.draw() - love.graphics.setCanvas(canvas) + local width, height = love.graphics.getDimensions() + love.graphics.setCanvas(shared.canvas) -- NOTE: different from normal canvas love.graphics.clear(0, 0, 0, 0) love.graphics.translate(width/2, height/2) love.graphics.rotate(angle) love.graphics.setColor(1, 0, 0, 1) love.graphics.rectangle("fill", -150,-150, 300,300) - - local name_ptr = ffi.typeof('GLint[1]')() - gl.glGetFramebufferAttachmentParameteriv( - GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, - name_ptr - ) love.graphics.setCanvas() - - tvs.gl_client_send_image( - client, "love2d", - name_ptr[0], - GL_TEXTURE_2D, - false, 0, nil - ) + shared:send() love.graphics.reset() love.graphics.setBlendMode("alpha", "premultiplied") - love.graphics.draw(canvas) + love.graphics.draw(shared.canvas) -- NOTE: different from normal canvas end diff --git a/texture_share_vk.lua b/texture_share_vk.lua new file mode 100644 index 0000000..b8e2523 --- /dev/null +++ b/texture_share_vk.lua @@ -0,0 +1,172 @@ +local ffi = require 'ffi' + +ffi.cdef [[ +// GL/gl.h +typedef int GLint; +typedef unsigned int GLuint; +typedef unsigned int GLenum; + +void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, + GLenum pname, GLint *params); + +// texture_share_ipc/texture_share_ipc.h +typedef enum ImgFormat { + R8G8B8A8, + R8G8B8, + B8G8R8A8, + B8G8R8, + Undefined, +} ImgFormat; + +// texture_share_gl_client/texture_share_gl_client.h +typedef enum ImageLookupResult { + Error = -1, + NotFound = 0, + Found = 1, + RequiresUpdate = 2, +} ImageLookupResult; + +typedef struct ClientImageDataGuard ClientImageDataGuard; + +typedef struct GlClient GlClient; + +typedef struct GlImageExtent { + GLint top_left[2]; + GLint bottom_right[2]; +} GlImageExtent; + +bool gl_client_initialize_external_gl(void); + +struct GlClient *gl_client_new(const char *socket_path, uint64_t timeout_in_millis); +struct GlClient *gl_client_new_with_server_launch(const char *socket_path, + uint64_t client_timeout_in_millis, + const char *server_program, + const char *server_lock_path, + const char *server_socket_path, + const char *shmem_prefix, + uint64_t server_socket_timeout_in_millis, + uint64_t server_connection_wait_timeout_in_millis, + uint64_t server_ipc_timeout_in_millis, + uint64_t server_lockfile_timeout_in_millis, + uint64_t server_spawn_timeout_in_millis); + +void gl_client_destroy(struct GlClient *gl_client); + +enum ImageLookupResult gl_client_init_image(struct GlClient *gl_client, + const char *image_name, + uint32_t width, + uint32_t height, + ImgFormat format, + bool overwrite_existing); + +int gl_client_send_image(struct GlClient *gl_client, + const char *image_name, + GLuint src_texture_id, + GLenum src_texture_target, + bool invert, + GLuint prev_fbo, + const struct GlImageExtent *extents); +]] + +-- from texture_share_vk/config.h +local VK_SERVER_EXECUTABLE = "/usr/bin/texture-share-vk-server" +local VK_SERVER_DEFAULT_LOCKFILE_PATH = "/tmp/vk_server/vk_server.lock" +local VK_SERVER_DEFAULT_SOCKET_PATH = "/tmp/vk_server/vk_server.sock" +local VK_SERVER_DEFAULT_SHMEM_PREFIX = "shmem_img_" + +-- from GL/gl.h +local GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1 +local GL_COLOR_ATTACHMENT0 = 0x8CE0 +local GL_FRAMEBUFFER = 0x8D40 +local GL_TEXTURE_2D = 0x0DE1 + +local IMAGE_FORMATS = { + rgba8 = ffi.C.R8G8B8A8, + rgb8 = ffi.C.R8G8B8, +} + +local tvs = ffi.load("texture_share_gl_client") +local gl = ffi.load("GL") + +local Client, Canvas = {}, {} +Client.__index = Client + +function Client.new() + assert(tvs.gl_client_initialize_external_gl(), "failed to init tsv OpenGL") + local client = assert(tvs.gl_client_new_with_server_launch( + VK_SERVER_DEFAULT_SOCKET_PATH, + 1000, + VK_SERVER_EXECUTABLE, + VK_SERVER_DEFAULT_LOCKFILE_PATH, + VK_SERVER_DEFAULT_SOCKET_PATH, + VK_SERVER_DEFAULT_SHMEM_PREFIX, + 2000, + 2000, + 2000, + 2000, + 2000 + ), "failed to connect or launch tsv server") + + return setmetatable({ client = client }, Client) +end + +function Client:newSharedCanvas(name, ...) + local canvas = love.graphics.newCanvas(...) + local width, height = canvas:getDimensions() + local format = assert(IMAGE_FORMATS[canvas:getFormat()], "unsupported Texture format") + assert( + tvs.gl_client_init_image(self.client, name, width, height, format, true) > 0, + "failed to init image" + ) + + local last_canvas = love.graphics.getCanvas() + love.graphics.setCanvas(canvas) + + local name_ptr = ffi.typeof('GLint[1]')() + gl.glGetFramebufferAttachmentParameteriv( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + name_ptr + ) + love.graphics.setCanvas(last_canvas) + + return setmetatable({ + name = name, + canvas = canvas, + client = self, + texture_id = name_ptr[0] + }, Canvas) +end + +function Client:__gc() + tvs.gl_client_destroy(self) +end + +function Canvas:send() + tvs.gl_client_send_image( + self.client.client, + self.name, + self.texture_id, + GL_TEXTURE_2D, + false, + 0, + nil + ) +end + +function Canvas:__index(key) + local val = Canvas[key] + if val then return val end + + val = self.canvas[key] + if val then + Canvas[key] = function (shared, ...) + return val(shared.canvas, ...) + end + + return Canvas[key] + end +end + +return Client |
