git.s-ol.nu openxPriments / 95c9656
draw two triangles s-ol 1 year, 4 months ago
4 changed file(s) with 215 addition(s) and 145 deletion(s). Raw diff Collapse all Expand all
(No changes)
136136 };
137137
138138 // CREATE DEVICE
139
139140 const device_extensions = [_][*:0]const u8{
140 "VK_KHR_spirv_1_4",
141
142 "VK_KHR_swapchain",
143 "VK_KHR_maintenance1",
144
141 // "VK_KHR_maintenance1",
145142 "VK_KHR_8bit_storage",
146143 "VK_KHR_16bit_storage",
147144 "VK_KHR_storage_buffer_storage_class",
148145 };
146
147 const device_features = mem.zeroInit(vk.PhysicalDeviceFeatures, .{
148 .geometry_shader = vk.TRUE,
149 .multi_viewport = vk.TRUE,
150 });
149151
150152 const device_create_info = vk.DeviceCreateInfo{
151153 .flags = .{},
155157 .pp_enabled_layer_names = undefined,
156158 .enabled_extension_count = device_extensions.len,
157159 .pp_enabled_extension_names = device_extensions[0..],
158 .p_enabled_features = null,
160 .p_enabled_features = &device_features,
159161 };
160162
161163 try xri.createVulkanDeviceKHR(instance, .{
180182
181183 self.queue = self.vkd.getDeviceQueue(self.device, self.family_index, 0);
182184
183 // CREATE COMMAND POOL
184 self.command_pool = try self.vkd.createCommandPool(self.device, .{
185 .flags = .{ .reset_command_buffer_bit = true },
186 .queue_family_index = self.family_index,
187 }, null);
188 errdefer self.vkd.destroyCommandPool(self.device, self.command_pool, null);
189
190 return self;
191 }
192
193 pub fn createSwapchain(self: *Graphics, session: xr.Session, configs: []const xr.ViewConfigurationView) !void {
194 const factory = dg.IEngineFactoryVk_Wrapper.wrap(dg.Diligent_GetEngineFactoryVk());
185 // DILIGENT
195186
196187 const create_info = dg.EngineVkCreateInfo{
197188 ._EngineCreateInfo = .{
198189 .APIVersion = dg.DILIGENT_API_VERSION,
199190 .NumDeferredContexts = 0,
200 .Features = mem.zeroes(dg.DeviceFeatures),
191 .Features = mem.zeroInit(dg.DeviceFeatures, .{
192 .GeometryShaders = dg.DEVICE_FEATURE_STATE_ENABLED,
193 .MultiViewport = dg.DEVICE_FEATURE_STATE_ENABLED,
194 }),
201195 .pRawMemAllocator = null,
202196 .DebugMessageCallback = null,
203197 },
239233 .pDxCompilerPath = null,
240234 .AdapterId = 0,
241235 .EnableValidation = false,
236 // .GlobalExtensionCount = @intCast(u32, instance_extensions.len),
237 // .ppGlobalExtensionNames = instance_extensions,
242238 .GlobalExtensionCount = 0,
243239 .ppGlobalExtensionNames = null,
244240 .pVkAllocator = null,
245241 };
242
243 const factory = dg.IEngineFactoryVk_Wrapper.wrap(dg.Diligent_GetEngineFactoryVk());
244
246245 var device: ?*dg.IRenderDevice = null;
247246 var context: ?*dg.IDeviceContext = null;
248247 factory.AttachToVulkanDevice(
249248 &@intToPtr(*dg.VkInstance_T, @enumToInt(self.instance)),
250249 &@intToPtr(*dg.VkPhysicalDevice_T, @enumToInt(self.physical_device)),
250 @ptrCast(*const dg.VkPhysicalDeviceFeatures, &device_features),
251251 &@intToPtr(*dg.VkDevice_T, @enumToInt(self.device)),
252252 &@intToPtr(*dg.VkQueue_T, @enumToInt(self.queue)),
253253 self.family_index,
258258
259259 self.dg_device = dg.IRenderDeviceVk_Wrapper.wrap(@ptrCast(?*dg.IRenderDeviceVk, device));
260260 self.dg_ctx = dg.IDeviceContext_Wrapper.wrap(context);
261
262 return self;
263 }
264
265 pub fn createSwapchain(self: *Graphics, session: xr.Session, configs: []const xr.ViewConfigurationView) !void {
266 const factory = dg.IEngineFactoryVk_Wrapper.wrap(dg.Diligent_GetEngineFactoryVk());
261267
262268 try Swapchain.init(&self.swapchain, self, factory, session, configs);
263269 }
351357 configs: []const xr.ViewConfigurationView,
352358 ) !void {
353359 const config = configs[0];
354 const view_count = @intCast(u32, configs.len);
355 for (configs[1..]) |c| {
360 const image_rects = try gfx.allocator.alloc(xr.Rect2Di, configs.len);
361 errdefer gfx.allocator.free(image_rects);
362
363 for (configs) |c, i| {
356364 if (c.recommended_swapchain_sample_count != config.recommended_swapchain_sample_count) {
357365 return error.ViewCfgDiffer;
358366 }
362370 if (c.recommended_image_rect_height != config.recommended_image_rect_height) {
363371 return error.ViewCfgDiffer;
364372 }
365 }
366
367 // xri.enumerateSwapchainFormats(...);
368 const swapchain = try gfx.xri.createSwapchain(session, .{
369 .create_flags = .{},
370 .usage_flags = .{
371 .color_attachment_bit = true,
372 .transfer_dst_bit = true,
373 .sampled_bit = true,
374 },
375 .format = @enumToInt(vk.Format.r8g8b8a8_srgb),
376 .sample_count = config.recommended_swapchain_sample_count,
377 .width = config.recommended_image_rect_width,
378 .height = config.recommended_image_rect_height * view_count,
379 .face_count = 1,
380 .array_size = 1,
381 .mip_count = 1,
382 });
383
384 // get images
385 const image_count = try gfx.xri.enumerateSwapchainImages(swapchain, 0, null);
386 const xr_images = try gfx.allocator.alloc(xr.SwapchainImageVulkan2KHR, image_count);
387 std.mem.set(xr.SwapchainImageVulkan2KHR, xr_images, xr.SwapchainImageVulkan2KHR.empty());
388 defer gfx.allocator.free(xr_images);
389
390 _ = try gfx.xri.enumerateSwapchainImages(swapchain, image_count, @ptrCast(
391 [*]xr.SwapchainImageBaseHeader,
392 xr_images.ptr,
393 ));
394
395 const images = try gfx.allocator.alloc(vk.Image, xr_images.len);
396 defer gfx.allocator.free(images);
397
398 const image_rects = try gfx.allocator.alloc(xr.Rect2Di, xr_images.len);
399 errdefer gfx.allocator.free(images);
400
401 for (xr_images) |xr_image, i| {
402 images[i] = xr_image.image;
373
403374 image_rects[i] = .{
404375 .offset = .{
405376 .y = @intCast(i32, config.recommended_image_rect_height) * @intCast(i32, i),
409380 .height = @intCast(i32, config.recommended_image_rect_height),
410381 },
411382 };
383 }
384
385 // xri.enumerateSwapchainFormats(...);
386 const view_count = @intCast(u32, configs.len);
387 const swapchain = try gfx.xri.createSwapchain(session, .{
388 .create_flags = .{},
389 .usage_flags = .{
390 .color_attachment_bit = true,
391 .transfer_dst_bit = true,
392 .sampled_bit = true,
393 },
394 .format = @enumToInt(vk.Format.r8g8b8a8_srgb),
395 .sample_count = config.recommended_swapchain_sample_count,
396 .width = config.recommended_image_rect_width,
397 .height = config.recommended_image_rect_height * view_count,
398 .face_count = 1,
399 .array_size = 1,
400 .mip_count = 1,
401 });
402
403 // get images
404 const image_count = try gfx.xri.enumerateSwapchainImages(swapchain, 0, null);
405 const xr_images = try gfx.allocator.alloc(xr.SwapchainImageVulkan2KHR, image_count);
406 std.mem.set(xr.SwapchainImageVulkan2KHR, xr_images, xr.SwapchainImageVulkan2KHR.empty());
407 defer gfx.allocator.free(xr_images);
408
409 _ = try gfx.xri.enumerateSwapchainImages(swapchain, image_count, @ptrCast(
410 [*]xr.SwapchainImageBaseHeader,
411 xr_images.ptr,
412 ));
413
414 const images = try gfx.allocator.alloc(vk.Image, xr_images.len);
415 defer gfx.allocator.free(images);
416
417 for (xr_images) |xr_image, i| {
418 images[i] = xr_image.image;
412419 }
413420
414421 const swap_desc = dg.SwapChainDesc{
285285 .image_array_index = 0,
286286 },
287287 };
288
289 try gfx_scene.render();
290 // try self.graphics.renderView(views.projections[i], swapchain.frames[image_index]);
291288 }
289
290 try gfx_scene.render();
292291
293292 swapchain.presentImage();
294293
301300
302301 if (self.first_render) {
303302 if (renderdoc.api) |api| _ = api.EndFrameCapture(null, null);
304 self.first_render = false;
303 // self.first_render = false;
305304 }
306305
307306 return true;
11 const graphics = @import("graphics.zig");
22
33 const vertex_source =
4 \\struct PSInput
5 \\{
6 \\ float4 Pos : SV_POSITION;
7 \\ float3 Color : COLOR;
8 \\};
9 \\void main(in uint VertId : SV_VertexID,
10 \\ out PSInput PSIn)
11 \\{
12 \\ float4 Pos[3];
13 \\ Pos[0] = float4(-0.5, -0.5, 0.0, 1.0);
14 \\ Pos[1] = float4( 0.0, +0.5, 0.0, 1.0);
15 \\ Pos[2] = float4(+0.5, -0.5, 0.0, 1.0);
16 \\ float3 Col[3];
17 \\ Col[0] = float3(1.0, 0.0, 0.0); // red
18 \\ Col[1] = float3(0.0, 1.0, 0.0); // green
19 \\ Col[2] = float3(0.0, 0.0, 1.0); // blue
20 \\ PSIn.Pos = Pos[VertId];
21 \\ PSIn.Color = Col[VertId];
4 \\layout(location = 0) out vec3 out_Color;
5 \\
6 \\void main() {
7 \\ vec4 positions[3] = vec4[3](
8 \\ vec4(-0.5, -0.5, 0.0, 1.0),
9 \\ vec4(0.0, 0.5, 0.0, 1.0),
10 \\ vec4(0.5, -0.5, 0.0, 1.0)
11 \\ );
12 \\ vec3 colors[3] = vec3[3](
13 \\ vec3(1.0, 0.0, 0.0),
14 \\ vec3(0.0, 1.0, 0.0),
15 \\ vec3(0.0, 0.0, 1.0)
16 \\ );
17 \\
18 \\ gl_Position = positions[uint(gl_VertexIndex)];
19 \\ out_Color = colors[uint(gl_VertexIndex)];
2220 \\}
2321 ;
2422
25 const fragment_source =
26 \\struct PSInput
27 \\{
28 \\ float4 Pos : SV_POSITION;
29 \\ float3 Color : COLOR;
23 const geometry_source =
24 \\layout(triangles, invocations=2) in;
25 \\layout(max_vertices = 3, triangle_strip) out;
26 \\
27 \\struct VSOutput {
28 \\ vec4 position;
29 \\ vec3 color;
3030 \\};
31 \\float4 main(PSInput In) : SV_Target
32 \\{
33 \\ return float4(In.Color.rgb, 1.0);
31 \\
32 \\layout(location = 0) out vec3 out_Color;
33 \\layout(location = 0) in vec3 in_Color[3];
34 \\
35 \\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;
45 \\ gl_ViewportIndex = int(gl_InvocationID);
46 \\ EmitVertex();
47 \\ }
48 \\ EndPrimitive();
3449 \\}
3550 ;
3651
52 const fragment_source =
53 \\layout(location = 0) in vec3 in_Color;
54 \\layout(location = 0) out vec4 out_Color;
55 \\
56 \\void main() {
57 \\ out_Color = vec4(in_Color, 1.0);
58 \\}
59 ;
60
3761 pub const Scene = struct {
38 pipeline_state: ?*dg.IPipelineState,
39
40 graphics: *const graphics.Graphics,
41
42 pub fn init(gfx: *const graphics.Graphics) !Scene {
43 var pipeline_state: ?*dg.IPipelineState = null;
44
45 const dev = gfx.dg_device;
46 const swc = gfx.swapchain.dg_handle;
47
48 var shader_create_info = dg.ShaderCreateInfo{
49 .SourceLanguage = dg.SHADER_SOURCE_LANGUAGE_HLSL,
50 .UseCombinedTextureSamplers = true,
51
52 .Desc = undefined,
62 pipeline_state: *dg.IPipelineState,
63 viewports: []dg.Viewport,
64 scissors: []dg.Rect,
65
66 ctx: dg.IDeviceContext_Wrapper,
67 dev: dg.IRenderDeviceVk_Wrapper,
68 swc: dg.ISwapChainVk_Wrapper,
69
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,
5386
5487 // default
5588 .FilePath = null,
5689 .pShaderSourceStreamFactory = null,
5790 .ppConversionStream = null,
58 .Source = null,
5991 .ByteCode = null,
6092 .ByteCodeSize = 0,
6193 .EntryPoint = "main",
6294 .Macros = null,
95 .UseCombinedTextureSamplers = false,
6396 .CombinedSamplerSuffix = "_sampler",
6497 .ShaderCompiler = dg.SHADER_COMPILER_DEFAULT,
6598 .HLSLVersion = .{ .Major = 0, .Minor = 0 },
6699 .GLSLVersion = .{ .Major = 0, .Minor = 0 },
67100 .GLESSLVersion = .{ .Major = 0, .Minor = 0 },
68101 .ppCompilerOutput = null,
69 };
70
71 var vertex_shader: ?*dg.IShader = null;
72 var fragment_shader: ?*dg.IShader = null;
73 {
74 shader_create_info.Desc = .{
75 ._DeviceObjectAttribs = .{ .Name = "Vertex Shader" },
76 .ShaderType = dg.SHADER_TYPE_VERTEX,
102 }, &shader);
103
104 return shader orelse error.ShaderCreationError;
105 }
106
107 pub fn init(gfx: *const graphics.Graphics) !Scene {
108 const dev = gfx.dg_device;
109 const swc = gfx.swapchain.dg_handle;
110
111 var self: Scene = undefined;
112 self.ctx = gfx.dg_ctx;
113 self.dev = dev;
114 self.swc = swc;
115
116 self.viewports = try gfx.allocator.alloc(dg.Viewport, gfx.swapchain.image_rects.len);
117 errdefer gfx.allocator.free(self.viewports);
118 self.scissors = try gfx.allocator.alloc(dg.Rect, gfx.swapchain.image_rects.len);
119 errdefer gfx.allocator.free(self.scissors);
120
121 for (gfx.swapchain.image_rects) |rect, i| {
122 self.viewports[i] = .{
123 .TopLeftX = @intToFloat(f32, rect.offset.x),
124 .TopLeftY = @intToFloat(f32, rect.offset.y),
125 .Width = @intToFloat(f32, rect.extent.width),
126 .Height = @intToFloat(f32, rect.extent.height),
127 .MinDepth = 0,
128 .MaxDepth = 1,
77129 };
78 shader_create_info.Source = vertex_source;
79 dev.CreateShader(&shader_create_info, &vertex_shader);
130
131 self.scissors[i] = .{
132 .left = rect.offset.x,
133 .right = rect.offset.x + rect.extent.width,
134 .top = rect.offset.y,
135 .bottom = rect.offset.y + rect.extent.height,
136 };
80137 }
81138
82 {
83 shader_create_info.Desc = .{
84 ._DeviceObjectAttribs = .{ .Name = "Fragment Shader" },
85 .ShaderType = dg.SHADER_TYPE_PIXEL,
86 };
87 shader_create_info.Source = fragment_source;
88 dev.CreateShader(&shader_create_info, &fragment_shader);
89 }
90
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);
142
143 var pipeline_state: ?*dg.IPipelineState = null;
91144 dev.CreateGraphicsPipelineState(&dg.GraphicsPipelineStateCreateInfo{
92145 ._PipelineStateCreateInfo = .{
93146 .PSODesc = .{
109162 },
110163 .GraphicsPipeline = .{
111164 .PrimitiveTopology = dg.PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
112 .NumViewports = 1,
165 .NumViewports = 2,
113166 .NumRenderTargets = 1, // non default
114167 .SubpassIndex = 0,
115168 .pRenderPass = null,
153206 .CullMode = dg.CULL_MODE_NONE, // not default
154207 .FrontCounterClockwise = true,
155208 .DepthClipEnable = true,
156 .ScissorEnable = false,
209 .ScissorEnable = true,
157210 .AntialiasedLineEnable = false,
158211 .DepthBias = 0,
159212 .DepthBiasClamp = 0,
178231 .pPS = fragment_shader,
179232 .pDS = null,
180233 .pHS = null,
181 .pGS = null,
234 .pGS = geometry_shader,
182235 .pAS = null,
183236 .pMS = null,
184237 }, &pipeline_state);
185
186 return Scene{
187 .pipeline_state = pipeline_state orelse return error.PipelineError,
188
189 .graphics = gfx,
190 };
238 self.pipeline_state = pipeline_state orelse return error.PipelineCreateError;
239
240 return self;
241 }
242
243 pub fn deinit(self: *const Scene) void {
244 gfx.allocator.free(self.viewports);
191245 }
192246
193247 pub fn render(self: *const Scene) !void {
194 const ctx = self.graphics.dg_ctx;
195 const swc = self.graphics.swapchain.dg_handle;
196
197 var rtv = swc.GetCurrentBackBufferRTV();
198 const dsv = swc.GetDepthBufferDSV();
199 ctx.SetRenderTargets(1, &rtv, dsv, dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
248 var rtv = self.swc.GetCurrentBackBufferRTV();
249 const dsv = self.swc.GetDepthBufferDSV();
250
251 self.ctx.SetRenderTargets(1, &rtv, dsv, dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
252 self.ctx.SetViewports(
253 @intCast(u32, self.viewports.len),
254 self.viewports.ptr,
255 0,
256 0,
257 );
258 self.ctx.SetScissorRects(
259 @intCast(u32, self.scissors.len),
260 self.scissors.ptr,
261 0,
262 0,
263 );
200264
201265 const clear_color = [_]f32{ 0.35, 0.35, 0.35, 1 };
202 ctx.ClearRenderTarget(rtv, clear_color[0..], dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
203 ctx.ClearDepthStencil(dsv, dg.CLEAR_DEPTH_FLAG, 1, 0, dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
204
205 ctx.SetPipelineState(self.pipeline_state);
206
207 ctx.Draw(&dg.DrawAttribs{
266 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);
270
271 self.ctx.Draw(&dg.DrawAttribs{
208272 .NumVertices = 3,
209273
210274 .Flags = dg.DRAW_FLAG_NONE,