git.s-ol.nu openxPriments / bf279de
draw a triangle s-ol 1 year, 4 months ago
4 changed file(s) with 459 addition(s) and 174 deletion(s). Raw diff Collapse all Expand all
(No changes)
2929 queue: vk.Queue,
3030 family_index: u32,
3131 command_pool: vk.CommandPool,
32 swapchain: ?Swapchain,
32 swapchain: Swapchain,
33
34 dg_device: dg.IRenderDeviceVk_Wrapper,
35 dg_ctx: dg.IDeviceContext_Wrapper,
3336
3437 allocator: *Allocator,
3538
3841 xri: xr.InstanceDispatch,
3942 instance: xr.Instance,
4043 system: xr.SystemId,
41 ) !*Graphics {
42 var self = try allocator.create(Graphics);
43 errdefer allocator.destroy(self);
44 ) !Graphics {
45 var self: Graphics = undefined;
4446
4547 self.xri = xri;
4648 self.allocator = allocator;
6365 const zero = [_:0]u8{};
6466 const instance_extensions = [_][*:0]const u8{
6567 "VK_EXT_debug_utils",
68 "VK_KHR_get_physical_device_properties2",
69 "VK_KHR_surface",
6670 };
6771
6872 const instance_create_info = vk.InstanceCreateInfo{
132136 };
133137
134138 // CREATE DEVICE
139 const device_extensions = [_][*:0]const u8{
140 "VK_KHR_spirv_1_4",
141
142 "VK_KHR_swapchain",
143 "VK_KHR_maintenance1",
144
145 "VK_KHR_8bit_storage",
146 "VK_KHR_16bit_storage",
147 "VK_KHR_storage_buffer_storage_class",
148 };
135149
136150 const device_create_info = vk.DeviceCreateInfo{
137151 .flags = .{},
139153 .p_queue_create_infos = &queue_create_info,
140154 .enabled_layer_count = 0,
141155 .pp_enabled_layer_names = undefined,
142 .enabled_extension_count = 0,
143 .pp_enabled_extension_names = undefined,
156 .enabled_extension_count = device_extensions.len,
157 .pp_enabled_extension_names = device_extensions[0..],
144158 .p_enabled_features = null,
145159 };
146160
173187 }, null);
174188 errdefer self.vkd.destroyCommandPool(self.device, self.command_pool, null);
175189
176 self.swapchain = null;
177
178190 return self;
179191 }
180192
181 pub fn init_swapchain(
182 self: *Graphics,
183 session: xr.Session,
184 config: []xr.ViewConfigurationView,
185 ) !void {
193 pub fn createSwapchain(self: *Graphics, session: xr.Session, configs: []const xr.ViewConfigurationView) !void {
186194 const factory = dg.IEngineFactoryVk_Wrapper.wrap(dg.Diligent_GetEngineFactoryVk());
187 std.debug.print("factory: {}\n", .{factory});
188195
189196 const create_info = dg.EngineVkCreateInfo{
190197 ._EngineCreateInfo = .{
195202 .DebugMessageCallback = null,
196203 },
197204 .NumCommandsToFlushCmdBuffer = 2048,
198 // 8192, 1024, 8192, 8192, 1024, 4096, 4096, 1024, 1024, 256, 256
199 .MainDescriptorPoolSize = mem.zeroes(dg.VulkanDescriptorPoolSize),
200 // 2048, 256, 2048, 2048, 256, 1024, 1024, 256, 256, 64, 64
201 .DynamicDescriptorPoolSize = mem.zeroes(dg.VulkanDescriptorPoolSize),
205 .MainDescriptorPoolSize = .{
206 .MaxDescriptorSets = 8192,
207 .NumSeparateSamplerDescriptors = 1024,
208 .NumCombinedSamplerDescriptors = 8192,
209 .NumSampledImageDescriptors = 8192,
210 .NumStorageImageDescriptors = 1024,
211 .NumUniformBufferDescriptors = 4096,
212 .NumStorageBufferDescriptors = 4096,
213 .NumUniformTexelBufferDescriptors = 1024,
214 .NumStorageTexelBufferDescriptors = 1024,
215 .NumInputAttachmentDescriptors = 256,
216 .NumAccelStructDescriptors = 256,
217 },
218 .DynamicDescriptorPoolSize = .{
219 .MaxDescriptorSets = 2048,
220 .NumSeparateSamplerDescriptors = 256,
221 .NumCombinedSamplerDescriptors = 2048,
222 .NumSampledImageDescriptors = 2048,
223 .NumStorageImageDescriptors = 256,
224 .NumUniformBufferDescriptors = 1024,
225 .NumStorageBufferDescriptors = 1024,
226 .NumUniformTexelBufferDescriptors = 256,
227 .NumStorageTexelBufferDescriptors = 256,
228 .NumInputAttachmentDescriptors = 64,
229 .NumAccelStructDescriptors = 64,
230 },
202231 .DeviceLocalMemoryPageSize = 16 << 20,
203232 .HostVisibleMemoryPageSize = 16 << 20,
204233 .DeviceLocalMemoryReserveSize = 256 << 20,
216245 };
217246 var device: ?*dg.IRenderDevice = null;
218247 var context: ?*dg.IDeviceContext = null;
219 try factory.AttachToVulkanDevice(
248 factory.AttachToVulkanDevice(
220249 &@intToPtr(*dg.VkInstance_T, @enumToInt(self.instance)),
221250 &@intToPtr(*dg.VkPhysicalDevice_T, @enumToInt(self.physical_device)),
222251 &@intToPtr(*dg.VkDevice_T, @enumToInt(self.device)),
227256 &context,
228257 );
229258
230 const swapchain = try Swapchain.init(self, session, config[0]);
231 errdefer swapchain.deinit();
232 self.swapchain = swapchain;
233
234 var dg_swapchain: ?*dg.ISwapChain = undefined;
235 const swap_desc = dg.SwapChainDesc{
236 .Width = @intCast(u32, swapchain.image_rect.extent.width),
237 .Height = @intCast(u32, swapchain.image_rect.extent.height),
238 .ColorBufferFormat = dg.TEX_FORMAT_RGBA8_UNORM,
239 .DepthBufferFormat = dg.TEX_FORMAT_D32_FLOAT,
240 .Usage = dg.SWAP_CHAIN_USAGE_RENDER_TARGET,
241 .PreTransform = dg.SURFACE_TRANSFORM_OPTIMAL,
242 .BufferCount = @intCast(u32, swapchain.images.len),
243 .DefaultDepthValue = 1,
244 .DefaultStencilValue = 0,
245 .IsPrimary = true,
246 };
247 const callbacks = dg.SwapChainImageCallbacks{
248 .Cookie = self,
249 .ImageCallbackAcquire = @This().acquire,
250 .ImageCallbackRelease = @This().release,
251 };
252 try factory.CreateSwapChainVk(
253 device,
254 context,
255 &swap_desc,
256 @intCast(u32, swapchain.images.len),
257 @ptrCast(**dg.VkImage_T, swapchain.images.ptr),
258 &callbacks,
259 &dg_swapchain,
260 );
259 self.dg_device = dg.IRenderDeviceVk_Wrapper.wrap(@ptrCast(?*dg.IRenderDeviceVk, device));
260 self.dg_ctx = dg.IDeviceContext_Wrapper.wrap(context);
261
262 try Swapchain.init(&self.swapchain, self, factory, session, configs);
261263 }
262264
263265 pub fn deinit(self: *const Graphics) void {
264 if (self.swapchain) |swapchain| {
265 swapchain.deinit();
266 }
266 self.swapchain.deinit();
267267
268268 self.vkd.destroyCommandPool(self.device, self.command_pool, null);
269269 self.vkd.destroyDevice(self.device, null);
272272 self.allocator.destroy(self);
273273 }
274274
275 fn acquire(c_self: ?*c_void, index: [*c]u32) callconv(.C) dg.VkResult {
276 const self = @ptrCast(*Graphics, @alignCast(@alignOf(Graphics), c_self));
277
278 if (self.swapchain) |swapchain| {
279 index.* = self.xri.acquireSwapchainImage(
280 swapchain.handle,
281 &xr.SwapchainImageAcquireInfo.empty(),
282 ) catch @panic("error acquiring image");
283 _ = self.xri.waitSwapchainImage(swapchain.handle, .{ .timeout = -1 }) catch {};
284 return .VK_SUCCESS;
285 }
286
287 return .VK_ERROR_UNKNOWN;
288 }
289
290 fn release(c_self: ?*c_void) callconv(.C) void {
291 const self = @ptrCast(*Graphics, @alignCast(@alignOf(Graphics), c_self));
292
293 if (self.swapchain) |swapchain| {
294 _ = self.xri.releaseSwapchainImage(
295 swapchain.handle,
296 &xr.SwapchainImageReleaseInfo.empty(),
297 ) catch {};
298 }
299 }
300
301 fn debug_callback(
275 pub fn lockQueue(self: *const Graphics) void {
276 _ = self.dg_device.LockCommandQueue(0);
277 }
278
279 pub fn unlockQueue(self: *const Graphics) void {
280 self.dg_device.UnlockCommandQueue(0);
281 }
282
283 pub fn setupDebugging(self: *Graphics) !void {
284 if (self.vki.vkCreateDebugUtilsMessengerEXT) |pfn| {
285 var messenger: vk.c.VkDebugUtilsMessengerEXT = undefined;
286 const messenger_create_info = vk.c.VkDebugUtilsMessengerCreateInfoEXT{
287 .sType = .VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
288 .pNext = null,
289 .flags = 0,
290 .messageSeverity = 0x1110,
291 .messageType = 0x3,
292 .pfnUserCallback = @This().debug_cb,
293 .pUserData = @as(*c_void, self),
294 };
295
296 _ = pfn(
297 @intToPtr(vk.c.VkInstance, @enumToInt(self.instance)),
298 &messenger_create_info,
299 null,
300 &messenger,
301 );
302 } else {
303 return error.FunctionUnsupported;
304 }
305 }
306
307 pub fn getBinding(self: *const Graphics) xr.GraphicsBindingVulkan2KHR {
308 return .{
309 .instance = self.instance,
310 .device = self.device,
311 .physical_device = self.physical_device,
312 .queue_family_index = self.family_index,
313 .queue_index = 0,
314 };
315 }
316
317 fn debug_cb(
302318 msg_severity: vk.c.VkDebugUtilsMessageSeverityFlagBitsEXT,
303319 msg_type: vk.c.VkDebugUtilsMessageTypeFlagsEXT,
304320 c_data: ?*const vk.c.VkDebugUtilsMessengerCallbackDataEXT,
318334 }
319335 return 0;
320336 }
321
322 pub fn setup_debugging(self: *Graphics) !void {
323 if (self.vki.vkCreateDebugUtilsMessengerEXT) |pfn| {
324 var messenger: vk.c.VkDebugUtilsMessengerEXT = undefined;
325 const messenger_create_info = vk.c.VkDebugUtilsMessengerCreateInfoEXT{
326 .sType = .VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
327 .pNext = null,
328 .flags = 0,
329 .messageSeverity = 0x1110,
330 .messageType = 0x3,
331 .pfnUserCallback = @This().debug_callback,
332 .pUserData = @as(*c_void, self),
333 };
334
335 _ = pfn(
336 @intToPtr(vk.c.VkInstance, @enumToInt(self.instance)),
337 &messenger_create_info,
338 null,
339 &messenger,
340 );
341 } else {
342 return error.FunctionUnsupported;
343 }
344 }
345
346 pub fn get_binding(self: *const Graphics) xr.GraphicsBindingVulkan2KHR {
347 return .{
348 .instance = self.instance,
349 .device = self.device,
350 .physical_device = self.physical_device,
351 .queue_family_index = self.family_index,
352 .queue_index = 0,
353 };
354 }
355337 };
356338
357339 pub const Swapchain = struct {
358340 handle: xr.Swapchain,
359 images: []vk.Image,
360 image_rect: xr.Rect2Di,
341 dg_handle: dg.ISwapChainVk_Wrapper,
342 image_rects: []xr.Rect2Di,
361343
362344 graphics: *const Graphics,
363345
364346 pub fn init(
347 self: *Swapchain,
365348 gfx: *const Graphics,
349 factory: dg.IEngineFactoryVk_Wrapper,
366350 session: xr.Session,
367 config: xr.ViewConfigurationView,
368 ) !Swapchain {
351 configs: []const xr.ViewConfigurationView,
352 ) !void {
353 const config = configs[0];
354 const view_count = @intCast(u32, configs.len);
355 for (configs[1..]) |c| {
356 if (c.recommended_swapchain_sample_count != config.recommended_swapchain_sample_count) {
357 return error.ViewCfgDiffer;
358 }
359 if (c.recommended_image_rect_width != config.recommended_image_rect_width) {
360 return error.ViewCfgDiffer;
361 }
362 if (c.recommended_image_rect_height != config.recommended_image_rect_height) {
363 return error.ViewCfgDiffer;
364 }
365 }
366
369367 // xri.enumerateSwapchainFormats(...);
370368 const swapchain = try gfx.xri.createSwapchain(session, .{
371369 .create_flags = .{},
372370 .usage_flags = .{
373371 .color_attachment_bit = true,
374 // .depth_stencil_attachment_bit = true,
375372 .transfer_dst_bit = true,
376373 .sampled_bit = true,
377374 },
378 .format = @enumToInt(vk.Format.r8g8b8a8_unorm),
375 .format = @enumToInt(vk.Format.r8g8b8a8_srgb),
379376 .sample_count = config.recommended_swapchain_sample_count,
380 .width = config.recommended_image_rect_width * 2,
381 .height = config.recommended_image_rect_height,
377 .width = config.recommended_image_rect_width,
378 .height = config.recommended_image_rect_height * view_count,
382379 .face_count = 1,
383380 .array_size = 1,
384381 .mip_count = 1,
395392 xr_images.ptr,
396393 ));
397394
398 const command_buffers = try gfx.allocator.alloc(vk.CommandBuffer, xr_images.len);
399 errdefer gfx.allocator.free(command_buffers);
400
401 try gfx.vkd.allocateCommandBuffers(gfx.device, .{
402 .command_pool = gfx.command_pool,
403 .command_buffer_count = image_count,
404 .level = .primary,
405 }, command_buffers.ptr);
406
407395 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);
408399 errdefer gfx.allocator.free(images);
409400
410 for (images) |*image, i| {
411 image.* = xr_images[i].image;
412 }
413
414 std.debug.print("created swapchain {}x{}, SS{}, {} images\n", .{
415 config.recommended_image_rect_width,
416 config.recommended_image_rect_height,
417 config.recommended_swapchain_sample_count,
418 images.len,
419 });
420
421 return Swapchain{
422 .handle = swapchain,
423 .image_rect = .{
424 .offset = .{},
401 for (xr_images) |xr_image, i| {
402 images[i] = xr_image.image;
403 image_rects[i] = .{
404 .offset = .{
405 .y = @intCast(i32, config.recommended_image_rect_height) * @intCast(i32, i),
406 },
425407 .extent = .{
426408 .width = @intCast(i32, config.recommended_image_rect_width),
427409 .height = @intCast(i32, config.recommended_image_rect_height),
428410 },
429 },
430 .images = images,
411 };
412 }
413
414 const swap_desc = dg.SwapChainDesc{
415 .Width = config.recommended_image_rect_width,
416 .Height = config.recommended_image_rect_height * view_count,
417 .ColorBufferFormat = dg.TEX_FORMAT_RGBA8_UNORM_SRGB,
418 .DepthBufferFormat = dg.TEX_FORMAT_D32_FLOAT,
419 .Usage = dg.SWAP_CHAIN_USAGE_RENDER_TARGET,
420 .PreTransform = dg.SURFACE_TRANSFORM_OPTIMAL,
421 .BufferCount = @intCast(u32, images.len),
422 .DefaultDepthValue = 1,
423 .DefaultStencilValue = 0,
424 .IsPrimary = true,
425 };
426 const callbacks = dg.SwapChainImageCallbacks{
427 .Cookie = self,
428 .ImageCallbackAcquire = @This().acquire_cb,
429 .ImageCallbackRelease = @This().release_cb,
430 };
431
432 var dg_swapchain: ?*dg.ISwapChain = undefined;
433 factory.CreateSwapChainVk(
434 @ptrCast(*dg.IRenderDevice, gfx.dg_device.ptr),
435 gfx.dg_ctx.ptr,
436 &swap_desc,
437 @intCast(u32, images.len),
438 @ptrCast(**dg.VkImage_T, images.ptr),
439 &callbacks,
440 &dg_swapchain,
441 );
442
443 std.debug.print("created swapchain {}x{}*{}, SS{}, {} images\n", .{
444 config.recommended_image_rect_width,
445 config.recommended_image_rect_height,
446 view_count,
447 config.recommended_swapchain_sample_count,
448 images.len,
449 });
450
451 self.* = .{
452 .handle = swapchain,
453 .dg_handle = dg.ISwapChainVk_Wrapper.wrap(@ptrCast([*c]dg.ISwapChainVk, dg_swapchain)),
454 .image_rects = image_rects,
431455
432456 .graphics = gfx,
433457 };
434458 }
435459
436 pub fn deinit(self: Swapchain) void {
460 pub fn deinit(self: *const Swapchain) void {
437461 const gfx = self.graphics;
438462
439 gfx.allocator.free(self.images);
463 gfx.allocator.free(self.image_rects);
440464 gfx.xri.destroySwapchain(self.handle) catch {};
441465 }
466
467 pub fn acquireImage(self: *const Swapchain) !void {
468 const result = self.dg_handle.AcquireNextImage();
469 if (result != .VK_SUCCESS) {
470 return error.Unknown;
471 }
472 }
473
474 pub fn presentImage(self: *const Swapchain) void {
475 self.dg_handle.PresentImage();
476 }
477
478 fn acquire_cb(c_self: ?*c_void, index: [*c]u32) callconv(.C) dg.VkResult {
479 const self = @ptrCast(*Swapchain, @alignCast(@alignOf(Swapchain), c_self));
480 const xri = &self.graphics.xri;
481
482 index.* = xri.acquireSwapchainImage(
483 self.handle,
484 &xr.SwapchainImageAcquireInfo.empty(),
485 ) catch return .VK_ERROR_UNKNOWN;
486
487 _ = xri.waitSwapchainImage(self.handle, .{ .timeout = -1 }) catch {};
488
489 return .VK_SUCCESS;
490 }
491
492 fn release_cb(c_self: ?*c_void) callconv(.C) void {
493 const self = @ptrCast(*Swapchain, @alignCast(@alignOf(Swapchain), c_self));
494
495 _ = self.graphics.xri.releaseSwapchainImage(
496 self.handle,
497 &xr.SwapchainImageReleaseInfo.empty(),
498 ) catch {};
499 }
442500 };
00 usingnamespace @import("xrvk.zig");
11 const std = @import("std");
22 const gfx = @import("graphics.zig");
3 const scene = @import("scene.zig");
34 const renderdoc = @import("renderdoc.zig");
45 const Allocator = std.mem.Allocator;
56
2223
2324 state: xr.SessionState,
2425 views: ?ViewInfo,
25 graphics: *gfx.Graphics,
26 graphics: gfx.Graphics,
2627 layers: []*const xr.CompositionLayerBaseHeader,
2728 scene_space: xr.Space,
2829
8990 });
9091
9192 var graphics = try gfx.Graphics.init(allocator, xri, instance, system);
92 try graphics.setup_debugging();
93
94 const binding = graphics.get_binding();
93 try graphics.setupDebugging();
94
95 const binding = graphics.getBinding();
9596 const session = try xri.createSession(instance, .{
9697 .next = &binding,
9798 .create_flags = .{},
219220 for (views.configurations) |config, i| {
220221 views.projections[i] = xr.CompositionLayerProjectionView.empty();
221222 }
222 try self.graphics.init_swapchain(self.session, views.configurations);
223 try self.graphics.createSwapchain(self.session, views.configurations);
224 const gfx_scene = try scene.Scene.init(&self.graphics);
223225
224226 const composition_layer = try self.allocator.create(xr.CompositionLayerProjection);
225227 composition_layer.* = .{
237239 try self.pollEvents();
238240 if (self.state == .stopping) break;
239241
240 if (!try self.renderFrame()) {
242 if (!try self.renderFrame(&gfx_scene)) {
241243 std.os.nanosleep(0, 250_000_000);
242244 }
243245 }
244246 }
245247
246 pub fn renderFrame(self: *Session) !bool {
248 pub fn renderFrame(self: *Session, gfx_scene: *const scene.Scene) !bool {
247249 if (self.views) |views| {
250 self.graphics.lockQueue();
251 errdefer self.graphics.unlockQueue();
248252 var frame_state = xr.FrameState.empty();
249253 _ = try self.xri.waitFrame(self.session, null, &frame_state);
250254 _ = try self.xri.beginFrame(self.session, null);
255 self.graphics.unlockQueue();
251256
252257 var layer_count: u32 = 0;
253258
267272 return error.InvalidPositionOrOrientation;
268273 }
269274
270 // acquire image
271
272 // for (located_views) |located_view, i| {
273 // views.projections[i] = .{
274 // .pose = located_view.pose,
275 // .fov = located_view.fov,
276 // .sub_image = .{
277 // .swapchain = swapchain.handle,
278 // .image_rect = swapchain.image_rect,
279 // .image_array_index = 0,
280 // },
281 // };
282 //
283 // try self.graphics.render_view(views.projections[i], swapchain.frames[image_index]);
284 // }
285
286 // present
275 const swapchain = self.graphics.swapchain;
276 try swapchain.acquireImage();
277
278 for (located_views) |located_view, i| {
279 views.projections[i] = .{
280 .pose = located_view.pose,
281 .fov = located_view.fov,
282 .sub_image = .{
283 .swapchain = swapchain.handle,
284 .image_rect = swapchain.image_rects[i],
285 .image_array_index = 0,
286 },
287 };
288
289 try gfx_scene.render();
290 // try self.graphics.renderView(views.projections[i], swapchain.frames[image_index]);
291 }
292
293 swapchain.presentImage();
287294
288295 _ = try self.xri.endFrame(self.session, .{
289296 .display_time = frame_state.predicted_display_time,
300307 return true;
301308 }
302309
310 self.graphics.lockQueue();
311 errdefer self.graphics.unlockQueue();
303312 _ = try self.xri.endFrame(self.session, .{
304313 .display_time = frame_state.predicted_display_time,
305314 .environment_blend_mode = .@"opaque",
306315 .layer_count = 0,
307316 .layers = null,
308317 });
318 self.graphics.unlockQueue();
309319
310320 return false;
311321 }
0 const dg = @import("diligent");
1 const graphics = @import("graphics.zig");
2
3 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];
22 \\}
23 ;
24
25 const fragment_source =
26 \\struct PSInput
27 \\{
28 \\ float4 Pos : SV_POSITION;
29 \\ float3 Color : COLOR;
30 \\};
31 \\float4 main(PSInput In) : SV_Target
32 \\{
33 \\ return float4(In.Color.rgb, 1.0);
34 \\}
35 ;
36
37 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,
53
54 // default
55 .FilePath = null,
56 .pShaderSourceStreamFactory = null,
57 .ppConversionStream = null,
58 .Source = null,
59 .ByteCode = null,
60 .ByteCodeSize = 0,
61 .EntryPoint = "main",
62 .Macros = null,
63 .CombinedSamplerSuffix = "_sampler",
64 .ShaderCompiler = dg.SHADER_COMPILER_DEFAULT,
65 .HLSLVersion = .{ .Major = 0, .Minor = 0 },
66 .GLSLVersion = .{ .Major = 0, .Minor = 0 },
67 .GLESSLVersion = .{ .Major = 0, .Minor = 0 },
68 .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,
77 };
78 shader_create_info.Source = vertex_source;
79 dev.CreateShader(&shader_create_info, &vertex_shader);
80 }
81
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
91 dev.CreateGraphicsPipelineState(&dg.GraphicsPipelineStateCreateInfo{
92 ._PipelineStateCreateInfo = .{
93 .PSODesc = .{
94 ._DeviceObjectAttribs = .{ .Name = "Simple triangle PSO" },
95 .PipelineType = dg.PIPELINE_TYPE_GRAPHICS,
96
97 // default
98 .SRBAllocationGranularity = 1,
99 .CommandQueueMask = 1,
100 .ResourceLayout = .{
101 .DefaultVariableType = dg.SHADER_RESOURCE_VARIABLE_TYPE_STATIC,
102 .NumVariables = 0,
103 .Variables = null,
104 .NumImmutableSamplers = 0,
105 .ImmutableSamplers = null,
106 },
107 },
108 .Flags = 0,
109 },
110 .GraphicsPipeline = .{
111 .PrimitiveTopology = dg.PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
112 .NumViewports = 1,
113 .NumRenderTargets = 1, // non default
114 .SubpassIndex = 0,
115 .pRenderPass = null,
116
117 .RTVFormats = [8]dg.TEXTURE_FORMAT{
118 swc.GetDesc().*.ColorBufferFormat,
119 dg.TEX_FORMAT_UNKNOWN,
120 dg.TEX_FORMAT_UNKNOWN,
121 dg.TEX_FORMAT_UNKNOWN,
122 dg.TEX_FORMAT_UNKNOWN,
123 dg.TEX_FORMAT_UNKNOWN,
124 dg.TEX_FORMAT_UNKNOWN,
125 dg.TEX_FORMAT_UNKNOWN,
126 },
127 .DSVFormat = swc.GetDesc().*.DepthBufferFormat,
128
129 .SampleMask = 0xffffffff,
130 .SmplDesc = .{ .Count = 1, .Quality = 0 },
131 .NodeMask = 0,
132
133 .BlendDesc = .{ // default
134 .AlphaToCoverageEnable = false,
135 .IndependentBlendEnable = false,
136 .RenderTargets = [_]dg.RenderTargetBlendDesc{
137 .{
138 .BlendEnable = false,
139 .LogicOperationEnable = false,
140 .SrcBlend = dg.BLEND_FACTOR_ONE,
141 .DestBlend = dg.BLEND_FACTOR_ZERO,
142 .BlendOp = dg.BLEND_OPERATION_ADD,
143 .SrcBlendAlpha = dg.BLEND_FACTOR_ONE,
144 .DestBlendAlpha = dg.BLEND_FACTOR_ZERO,
145 .BlendOpAlpha = dg.BLEND_OPERATION_ADD,
146 .LogicOp = dg.LOGIC_OP_NOOP,
147 .RenderTargetWriteMask = dg.COLOR_MASK_ALL,
148 },
149 } ** dg.DILIGENT_MAX_RENDER_TARGETS,
150 },
151 .RasterizerDesc = .{ // default
152 .FillMode = dg.FILL_MODE_SOLID,
153 .CullMode = dg.CULL_MODE_NONE, // not default
154 .FrontCounterClockwise = true,
155 .DepthClipEnable = true,
156 .ScissorEnable = false,
157 .AntialiasedLineEnable = false,
158 .DepthBias = 0,
159 .DepthBiasClamp = 0,
160 .SlopeScaledDepthBias = 0,
161 },
162 .DepthStencilDesc = .{ // default
163 .DepthEnable = false, // not default
164 .DepthWriteEnable = false, // @TRUE
165 .DepthFunc = dg.COMPARISON_FUNC_LESS,
166 .StencilEnable = false,
167 .StencilReadMask = 0xff,
168 .StencilWriteMask = 0xff,
169 .FrontFace = undefined,
170 .BackFace = undefined,
171 },
172 .InputLayout = .{
173 .NumElements = 0,
174 .LayoutElements = null,
175 },
176 },
177 .pVS = vertex_shader,
178 .pPS = fragment_shader,
179 .pDS = null,
180 .pHS = null,
181 .pGS = null,
182 .pAS = null,
183 .pMS = null,
184 }, &pipeline_state);
185
186 return Scene{
187 .pipeline_state = pipeline_state orelse return error.PipelineError,
188
189 .graphics = gfx,
190 };
191 }
192
193 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);
200
201 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{
208 .NumVertices = 3,
209
210 .Flags = dg.DRAW_FLAG_NONE,
211 .NumInstances = 1,
212 .StartVertexLocation = 0,
213 .FirstInstanceLocation = 0,
214 });
215 }
216 };