git.s-ol.nu openxPriments / 1c3a46d
start using uniform buffer s-ol 2 years ago
3 changed file(s) with 215 addition(s) and 58 deletion(s). Raw diff Collapse all Expand all
115115 pub fn main() !void {
116116 comptime const interfaces = [_][]const u8{
117117 "Graphics/GraphicsEngine/interface/DeviceContext.h",
118 "Graphics/GraphicsEngine/interface/PipelineState.h",
119 "Graphics/GraphicsEngine/interface/ShaderResourceVariable.h",
120 "Graphics/GraphicsEngine/interface/ShaderResourceBinding.h",
121 "Graphics/GraphicsEngine/interface/Buffer.h",
118122 "Graphics/GraphicsEngineVulkan/interface/RenderDeviceVk.h",
119123 "Graphics/GraphicsEngineVulkan/interface/EngineFactoryVk.h",
120124 "Graphics/GraphicsEngineVulkan/interface/SwapChainVk.h",
287287 };
288288 }
289289
290 try gfx_scene.render();
290 try gfx_scene.render(located_views[0..]);
291291
292292 swapchain.presentImage();
293293
0 const std = @import("std");
01 const dg = @import("diligent");
12 const graphics = @import("graphics.zig");
3 usingnamespace @import("xrvk.zig");
24
35 const vertex_source =
46 \\layout(location = 0) out vec3 out_Color;
2123 ;
2224
2325 const geometry_source =
24 \\layout(triangles, invocations=2) in;
26 \\layout(triangles, invocations = 2) in;
2527 \\layout(max_vertices = 3, triangle_strip) out;
2628 \\
2729 \\struct VSOutput {
2931 \\ vec3 color;
3032 \\};
3133 \\
34 \\struct ViewUBO {
35 \\ mat4 projection;
36 \\ mat4 modelview;
37 \\};
38 \\
39 \\layout(binding = 0) uniform Views {
40 \\ ViewUBO views[2];
41 \\};
42 \\
3243 \\layout(location = 0) out vec3 out_Color;
3344 \\layout(location = 0) in vec3 in_Color[3];
3445 \\
3546 \\void main() {
36 \\ VSOutput triangle[3] = VSOutput[](
37 \\ VSOutput(gl_in[0].gl_Position, in_Color[0]),
38 \\ VSOutput(gl_in[1].gl_Position, in_Color[1]),
39 \\ VSOutput(gl_in[2].gl_Position, in_Color[2])
40 \\ );
41 \\ for (int i = 0; i < 3; i++)
42 \\ {
43 \\ gl_Position = triangle[i].position;
44 \\ out_Color = triangle[i].color;
47 \\ for (int i = 0; i < 3; i++) {
48 \\ vec4 worldPos = views[gl_InvocationID].modelview * gl_in[i].gl_Position;
49 \\ gl_Position = views[gl_InvocationID].projection * worldPos;
4550 \\ gl_ViewportIndex = int(gl_InvocationID);
51 \\ out_Color = in_Color[i];
4652 \\ EmitVertex();
4753 \\ }
4854 \\ EndPrimitive();
5965 ;
6066
6167 pub const Scene = struct {
62 pipeline_state: *dg.IPipelineState,
6368 viewports: []dg.Viewport,
6469 scissors: []dg.Rect,
70
71 pipeline_state: dg.IPipelineState_Wrapper,
72 resource_binding: dg.IShaderResourceBinding_Wrapper,
73 views_ubo: dg.IBuffer_Wrapper,
74 views: []ViewUBO,
6575
6676 ctx: dg.IDeviceContext_Wrapper,
6777 dev: dg.IRenderDeviceVk_Wrapper,
6878 swc: dg.ISwapChainVk_Wrapper,
6979
70 fn createShader(
71 self: *const Scene,
72 name: [:0]const u8,
73 shader_type: dg.SHADER_TYPE,
74 language: dg.SHADER_SOURCE_LANGUAGE,
75 source: [:0]const u8,
76 ) !*dg.IShader {
77 var shader: ?*dg.IShader = null;
78 self.dev.CreateShader(&dg.ShaderCreateInfo{
79 .Desc = .{
80 ._DeviceObjectAttribs = .{ .Name = name },
81 .ShaderType = shader_type,
82 },
83
84 .Source = source,
85 .SourceLanguage = language,
86
87 // default
88 .FilePath = null,
89 .pShaderSourceStreamFactory = null,
90 .ppConversionStream = null,
91 .ByteCode = null,
92 .ByteCodeSize = 0,
93 .EntryPoint = "main",
94 .Macros = null,
95 .UseCombinedTextureSamplers = false,
96 .CombinedSamplerSuffix = "_sampler",
97 .ShaderCompiler = dg.SHADER_COMPILER_DEFAULT,
98 .HLSLVersion = .{ .Major = 0, .Minor = 0 },
99 .GLSLVersion = .{ .Major = 0, .Minor = 0 },
100 .GLESSLVersion = .{ .Major = 0, .Minor = 0 },
101 .ppCompilerOutput = null,
102 }, &shader);
103
104 return shader orelse error.ShaderCreationError;
105 }
80 const ViewUBO = packed struct {
81 projection: [16]f32,
82 modelview: [16]f32,
83 };
10684
10785 pub fn init(gfx: *const graphics.Graphics) !Scene {
10886 const dev = gfx.dg_device;
11795 errdefer gfx.allocator.free(self.viewports);
11896 self.scissors = try gfx.allocator.alloc(dg.Rect, gfx.swapchain.image_rects.len);
11997 errdefer gfx.allocator.free(self.scissors);
98 self.views = try gfx.allocator.alloc(ViewUBO, gfx.swapchain.image_rects.len);
99 errdefer gfx.allocator.free(self.views);
120100
121101 for (gfx.swapchain.image_rects) |rect, i| {
122102 self.viewports[i] = .{
134114 .top = rect.offset.y,
135115 .bottom = rect.offset.y + rect.extent.height,
136116 };
117
118 self.views[i] = .{
119 .projection = [_]f32{
120 1, 0, 0, 0,
121 0, 1, 0, 0,
122 0, 0, 1, 0,
123 0, 0, 0, 1,
124 },
125 .modelview = [_]f32{
126 1, 0, 0, 0,
127 0, 1, 0, 0,
128 0, 0, 1, 0,
129 0, 0, 0, 1,
130 },
131 };
137132 }
138133
139 const vertex_shader = try self.createShader("Vertex Shader", dg.SHADER_TYPE_VERTEX, dg.SHADER_SOURCE_LANGUAGE_GLSL, vertex_source);
140 const geometry_shader = try self.createShader("Geometry Shader", dg.SHADER_TYPE_GEOMETRY, dg.SHADER_SOURCE_LANGUAGE_GLSL, geometry_source);
141 const fragment_shader = try self.createShader("Fragment Shader", dg.SHADER_TYPE_PIXEL, dg.SHADER_SOURCE_LANGUAGE_GLSL, fragment_source);
134 const vertex_shader = try self.createShader(
135 "Vertex Shader",
136 dg.SHADER_TYPE_VERTEX,
137 dg.SHADER_SOURCE_LANGUAGE_GLSL,
138 vertex_source,
139 );
140 const geometry_shader = try self.createShader(
141 "Geometry Shader",
142 dg.SHADER_TYPE_GEOMETRY,
143 dg.SHADER_SOURCE_LANGUAGE_GLSL,
144 geometry_source,
145 );
146 const fragment_shader = try self.createShader(
147 "Fragment Shader",
148 dg.SHADER_TYPE_PIXEL,
149 dg.SHADER_SOURCE_LANGUAGE_GLSL,
150 fragment_source,
151 );
142152
143153 var pipeline_state: ?*dg.IPipelineState = null;
144154 dev.CreateGraphicsPipelineState(&dg.GraphicsPipelineStateCreateInfo{
235245 .pAS = null,
236246 .pMS = null,
237247 }, &pipeline_state);
238 self.pipeline_state = pipeline_state orelse return error.PipelineCreateError;
248 self.pipeline_state = dg.IPipelineState_Wrapper.wrap(pipeline_state);
249 errdefer self.pipeline_state.Release();
250
251 self.views_ubo = try self.createBuffer(
252 [2]ViewUBO,
253 "View Uniform Buffer",
254 null,
255 dg.BIND_UNIFORM_BUFFER,
256 dg.USAGE_DYNAMIC,
257 dg.CPU_ACCESS_WRITE,
258 );
259 errdefer self.views_ubo.Release();
260
261 const shader_variable = self.pipeline_state.GetStaticVariableByIndex(dg.SHADER_TYPE_GEOMETRY, 0);
262 dg.IShaderResourceVariable_Wrapper.wrap(shader_variable).Set(@ptrCast(*dg.IDeviceObject, self.views_ubo.ptr));
263
264 var resource_binding: ?*dg.IShaderResourceBinding = null;
265 self.pipeline_state.CreateShaderResourceBinding(&resource_binding, true);
266 self.resource_binding = dg.IShaderResourceBinding_Wrapper.wrap(resource_binding);
267 errdefer self.resource_binding.Release();
239268
240269 return self;
241270 }
242271
243272 pub fn deinit(self: *const Scene) void {
273 self.resource_binding.Release();
274 self.views_ubo.Release();
275 self.pipeline_state.Release();
276
244277 gfx.allocator.free(self.viewports);
245 }
246
247 pub fn render(self: *const Scene) !void {
278 gfx.allocator.free(self.scissors);
279 gfx.allocator.free(self.views);
280 }
281
282 pub fn render(self: *const Scene, views: []const xr.View) !void {
283 // update uniform buffer
284 for (views) |view, i| {
285 self.views[i].modelview[3] = view.pose.position.x / 3.0;
286 }
287 try self.updateBufferSlice(ViewUBO, self.views_ubo, self.views);
288
289 // setup and clear render targets
248290 var rtv = self.swc.GetCurrentBackBufferRTV();
249291 const dsv = self.swc.GetDepthBufferDSV();
250292
264306
265307 const clear_color = [_]f32{ 0.35, 0.35, 0.35, 1 };
266308 self.ctx.ClearRenderTarget(rtv, clear_color[0..], dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
267 self.ctx.ClearDepthStencil(dsv, dg.CLEAR_DEPTH_FLAG, 1, 0, dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
268
269 self.ctx.SetPipelineState(self.pipeline_state);
309 self.ctx.ClearDepthStencil(
310 dsv,
311 dg.CLEAR_DEPTH_FLAG,
312 1,
313 0,
314 dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION,
315 );
316
317 // record drenderpass
318 self.ctx.SetPipelineState(self.pipeline_state.ptr);
319 self.ctx.CommitShaderResources(self.resource_binding.ptr, dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
270320
271321 self.ctx.Draw(&dg.DrawAttribs{
272322 .NumVertices = 3,
277327 .FirstInstanceLocation = 0,
278328 });
279329 }
330
331 fn createShader(
332 self: *const Scene,
333 name: [:0]const u8,
334 shader_type: dg.SHADER_TYPE,
335 language: dg.SHADER_SOURCE_LANGUAGE,
336 source: [:0]const u8,
337 ) !*dg.IShader {
338 var shader: ?*dg.IShader = null;
339 self.dev.CreateShader(&dg.ShaderCreateInfo{
340 .Desc = .{
341 ._DeviceObjectAttribs = .{ .Name = name },
342 .ShaderType = shader_type,
343 },
344
345 .Source = source,
346 .SourceLanguage = language,
347
348 // default
349 .FilePath = null,
350 .pShaderSourceStreamFactory = null,
351 .ppConversionStream = null,
352 .ByteCode = null,
353 .ByteCodeSize = 0,
354 .EntryPoint = "main",
355 .Macros = null,
356 .UseCombinedTextureSamplers = false,
357 .CombinedSamplerSuffix = "_sampler",
358 .ShaderCompiler = dg.SHADER_COMPILER_DEFAULT,
359 .HLSLVersion = .{ .Major = 0, .Minor = 0 },
360 .GLSLVersion = .{ .Major = 0, .Minor = 0 },
361 .GLESSLVersion = .{ .Major = 0, .Minor = 0 },
362 .ppCompilerOutput = null,
363 }, &shader);
364
365 return shader orelse error.ShaderCreationError;
366 }
367
368 fn createBuffer(
369 self: *const Scene,
370 comptime T: type,
371 name: [:0]const u8,
372 initial: ?*T,
373 bind: dg.BIND_FLAGS,
374 usage: dg.USAGE,
375 cpu_access: dg.CPU_ACCESS_FLAGS,
376 ) !dg.IBuffer_Wrapper {
377 var buffer: ?*dg.IBuffer = null;
378 var data_ptr: ?*const dg.BufferData = null;
379
380 if (initial) |ptr| {
381 const data = dg.BufferData{
382 .pData = ptr,
383 .DataSize = @sizeOf(T),
384 };
385 data_ptr = &data;
386 }
387
388 self.dev.CreateBuffer(&dg.BufferDesc{
389 ._DeviceObjectAttribs = .{ .Name = name },
390 .uiSizeInBytes = @sizeOf(T),
391 .BindFlags = bind, // default: dg.BIND_NONE
392 .Usage = usage, // default: dg.USAGE_DEFAULT
393 .CPUAccessFlags = cpu_access, // default: dg.CPU_ACCESS_NONE
394 .Mode = dg.BUFFER_MODE_UNDEFINED,
395 .ElementByteStride = 0,
396 .CommandQueueMask = 1,
397 }, data_ptr, &buffer);
398
399 return dg.IBuffer_Wrapper.wrap(buffer);
400 }
401
402 fn updateBuffer(
403 self: *const Scene,
404 comptime T: type,
405 buffer: dg.IBuffer_Wrapper,
406 value: *T,
407 ) !void {
408 var data: ?*T = null;
409 self.ctx.MapBuffer(buffer.ptr, dg.MAP_WRITE, dg.MAP_FLAG_DISCARD, @ptrCast(?*c_void, &data));
410 if (data) |ptr| {
411 ptr.* = value;
412 self.ctx.UnmapBuffer(buffer.ptr, dg.MAP_WRITE);
413 } else {
414 return error.MapFailed;
415 }
416 }
417
418 fn updateBufferSlice(
419 self: *const Scene,
420 comptime T: type,
421 buffer: dg.IBuffer_Wrapper,
422 values: []const T,
423 ) !void {
424 var data: [*c]T = null;
425 self.ctx.MapBuffer(buffer.ptr, dg.MAP_WRITE, dg.MAP_FLAG_DISCARD, @ptrCast([*c]?*c_void, &data));
426 if (data) |ptr| {
427 std.mem.copy(T, data[0..values.len], values);
428 self.ctx.UnmapBuffer(buffer.ptr, dg.MAP_WRITE);
429 } else {
430 return error.MapFailed;
431 }
432 }
280433 };