diff --git a/engine/ui/shaders/rect.frag.hlsl b/engine/ui/shaders/rect.frag.hlsl index 07d7759..7b7431b 100644 --- a/engine/ui/shaders/rect.frag.hlsl +++ b/engine/ui/shaders/rect.frag.hlsl @@ -1,6 +1,7 @@ #include "rect_shared.hlsli" #include "fragmentHelpers.hlsli" + struct PSOut{ float4 Color: SV_Target0; }; @@ -8,6 +9,8 @@ struct PSOut{ Texture2D Texture0 : register(t0, space2); SamplerState Sampler0 : register(s0, space2); +StructuredBuffer scene: register(t1, space2); + PSOut main( float4 Color : TEXCOORD0, float2 UV : TEXCOORD1, diff --git a/engine/ui/shaders/rect.frag.json b/engine/ui/shaders/rect.frag.json index ecd3f0c..ad5956b 100644 --- a/engine/ui/shaders/rect.frag.json +++ b/engine/ui/shaders/rect.frag.json @@ -6,7 +6,7 @@ } ], "types" : { - "_9" : { + "_13" : { "name" : "Scene", "members" : [ { @@ -61,12 +61,12 @@ } ] }, - "_8" : { + "_12" : { "name" : "type.StructuredBuffer.Scene", "members" : [ { "name" : "_m0", - "type" : "_9", + "type" : "_13", "array" : [ 0 ], @@ -126,12 +126,12 @@ ], "ssbos" : [ { - "type" : "_8", + "type" : "_12", "name" : "scene", "readonly" : true, "block_size" : 0, - "set" : 0, - "binding" : 0 + "set" : 2, + "binding" : 1 } ] } \ No newline at end of file diff --git a/engine/ui/shaders/rect.vert.hlsl b/engine/ui/shaders/rect.vert.hlsl index 3b77234..050793a 100644 --- a/engine/ui/shaders/rect.vert.hlsl +++ b/engine/ui/shaders/rect.vert.hlsl @@ -1,6 +1,13 @@ #include "rect_shared.hlsli" +StructuredBuffer scene: register(t0, space0); + +cbuffer Uniforms : register(b0, space1) +{ + float2 Extents; +}; + struct Input { float3 Position : TEXCOORD0; diff --git a/engine/ui/shaders/rect_shared.hlsli b/engine/ui/shaders/rect_shared.hlsli index 3b810ac..ae75201 100644 --- a/engine/ui/shaders/rect_shared.hlsli +++ b/engine/ui/shaders/rect_shared.hlsli @@ -12,9 +12,3 @@ struct Scene float4 edgeColor; }; -StructuredBuffer scene: register(t0, space0); - -cbuffer Uniforms : register(b0, space1) -{ - float2 Extents; -}; diff --git a/engine/ui/src/sgpu/papyrusSgpu.zig b/engine/ui/src/sgpu/papyrusSgpu.zig index 904670d..2192dbc 100644 --- a/engine/ui/src/sgpu/papyrusSgpu.zig +++ b/engine/ui/src/sgpu/papyrusSgpu.zig @@ -34,9 +34,13 @@ const DrawCommand = union(enum(u8)) { const SsboBuffer = struct { buffer: *gpu.GPUBuffer, staging: *gpu.GPUTransferBuffer, + elementSize: u32, + count: u32, pub fn init(device: *gpu.GPUDevice, elementSize: u32, count: u32) @This() { var self: @This() = undefined; + self.elementSize = elementSize; + self.count = count; { const bci = gpu.GPUBufferCreateInfo{ @@ -44,6 +48,7 @@ const SsboBuffer = struct { .usage = .{ .bufferusageGraphicsStorageRead = true, }, + .props = 0, }; self.buffer = device.createGPUBuffer(&bci); } @@ -52,12 +57,35 @@ const SsboBuffer = struct { const bci = gpu.GPUTransferBufferCreateInfo{ .usage = .transferbufferusageUpload, .size = elementSize * count, + .props = 0, }; self.staging = device.createGPUTransferBuffer(&bci); } + + core.engine_log("buffer created elementSize: {d} count: {d}", .{ elementSize, count }); return self; } + + pub fn mapSlice(self: *@This(), comptime T: type, device: *gpu.GPUDevice) []T { + var rv: []T = undefined; + rv.ptr = @alignCast(@ptrCast(device.mapGPUTransferBuffer(self.staging, false))); + rv.len = self.count; + + return rv; + } + + pub fn unmap(self: *@This(), device: *gpu.GPUDevice) void { + device.unmapGPUTransferBuffer(self.staging); + } + + pub fn submit(self: *@This(), pass: *gpu.GPUCopyPass) void { + pass.uploadToGPUBuffer(&.{ .transfer_buffer = self.staging, .offset = 0 }, &.{ + .buffer = self.buffer, + .offset = 0, + .size = self.elementSize * self.count, + }, false); + } }; const ScreenBuffers = struct { @@ -96,6 +124,7 @@ pub fn create(allocator: std.mem.Allocator) !*@This() { pub fn setup(self: *@This()) !void { core.graphics_log("imgui startup", .{}); try rend.registerRendererObject(@This(), self); + try self.createRectPipeline(); } pub fn destroy(self: *@This()) void { @@ -113,6 +142,8 @@ pub fn createRectPipeline(self: *@This()) !void { const vertex = try ctx.loadShader("rect.vert", rect_vert.LoadArgs); const fragment = try ctx.loadShader("rect.frag", rect_frag.LoadArgs); + core.graphics_log("rect shaders created", .{}); + var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo); pci.vertex_shader = vertex; pci.fragment_shader = fragment; @@ -158,6 +189,73 @@ pub fn postRender(p: *anyopaque, cmd: *gpu.GPUCommandBuffer) void { pub fn drawToTarget(self: *@This(), ctx: *papyrus.Context, targetTexture: *gpu.GPUTexture) void { ctx.makeDrawList(&self.drawList, &self.stringArena) catch return; + var rectIndex: u32 = 0; + // var rectIndex: u32 = 0; + // + // imagePosition: vec2, + // imageSize: vec2, + // anchorPoint: vec2, + // scale: vec2, + // alpha: float, + // borderWidth: float, + // flags: uint, + // baseColor: vec4, + // rounding: vec4, + // edgeColor: vec4, + + // map ssbos + + const cmd = rend.context().state.cmd.?; + + const renderer = rend.context(); + const copyPass = cmd.beginGPUCopyPass(); + + { + const rectBuffer = self.screenBuffers.rect.mapSlice(rect_frag.Scene, renderer.device); + + for (self.drawList.items) |item| { + switch (item.primitive) { + .Rect => |rect| { + self.tempDrawCommand.append(self.allocator, .{ .rect = .{ .ssboIndex = rectIndex } }) catch unreachable; + rectBuffer[rectIndex] = .{ + .imagePosition = .{ .x = rect.tl.x, .y = rect.tl.y }, + .imageSize = .{ .x = rect.size.x, .y = rect.size.y }, + .anchorPoint = .{ .x = -1.0, .y = -1.0 }, + .scale = .{ .x = 1.0, .y = 1.0 }, + .alpha = 1.0, + .baseColor = .{ + .x = rect.backgroundColor.r, + .y = rect.backgroundColor.g, + .z = rect.backgroundColor.b, + .w = rect.backgroundColor.a, + }, + .rounding = .{ + .x = rect.rounding.tl, + .y = rect.rounding.tr, + .z = rect.rounding.bl, + .w = rect.rounding.br, + }, + .edgeColor = .{ + .x = rect.borderColor.r, + .y = rect.borderColor.g, + .z = rect.borderColor.b, + .w = rect.borderColor.a, + }, + .borderWidth = rect.borderWidth, + .flags = 0, + }; + + rectIndex += 1; + }, + .Text => {}, + } + } + self.screenBuffers.rect.submit(copyPass); + self.screenBuffers.rect.unmap(renderer.device); + } + + copyPass.endGPUCopyPass(); + if (self.first) { self.first = false; @@ -166,8 +264,6 @@ pub fn drawToTarget(self: *@This(), ctx: *papyrus.Context, targetTexture: *gpu.G } } - const cmd = rend.context().state.cmd.?; - const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{ .texture = targetTexture, .load_op = .loadopLoad, @@ -177,12 +273,7 @@ pub fn drawToTarget(self: *@This(), ctx: *papyrus.Context, targetTexture: *gpu.G const pass = cmd.beginGPURenderPass(&targetInfo, 1, null); pass.bindGPUVertexBuffers(1, &.{ .buffer = rend.context().meshPool.vertexBuffer, .offset = 0 }, 1); pass.bindGPUIndexBuffer(&.{ .buffer = rend.context().meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit); - for (self.drawList.items) |item| { - switch (item.primitive) { - .Rect => {}, - .Text => {}, - } - } + // upload the ssbo pass.endGPURenderPass(); }