| … | 3 unchanged lines hidden | ||
| 4 | 4 | ||
| 5 | 5 | // --- Opaque handle types --- | |
| 6 | 6 | ||
| 7 | - | Pipeline_Handle :: distinct u64 | |
| 8 | - | Buffer_Handle :: distinct u64 | |
| 9 | - | Texture_Handle :: distinct u64 | |
| 10 | - | Shader_Handle :: distinct u64 | |
| 11 | - | Descriptor_Handle :: distinct u64 | |
| 12 | - | Render_Pass_Handle :: distinct u64 | |
| 13 | - | Framebuffer_Handle :: distinct u64 | |
| 14 | - | Sampler_Handle :: distinct u64 | |
| 7 | + | Pipeline_Handle :: distinct u64 | |
| 8 | + | Buffer_Handle :: distinct u64 | |
| 9 | + | Texture_Handle :: distinct u64 | |
| 10 | + | Shader_Handle :: distinct u64 | |
| 11 | + | Descriptor_Handle :: distinct u64 | |
| 12 | + | Render_Pass_Handle :: distinct u64 | |
| 13 | + | Framebuffer_Handle :: distinct u64 | |
| 14 | + | Sampler_Handle :: distinct u64 | |
| 15 | 15 | ||
| 16 | - | NULL_PIPELINE :: Pipeline_Handle(0) | |
| 17 | - | NULL_BUFFER :: Buffer_Handle(0) | |
| 18 | - | NULL_TEXTURE :: Texture_Handle(0) | |
| 19 | - | NULL_SHADER :: Shader_Handle(0) | |
| 20 | - | NULL_DESCRIPTOR :: Descriptor_Handle(0) | |
| 21 | - | NULL_RENDER_PASS :: Render_Pass_Handle(0) | |
| 22 | - | NULL_FRAMEBUFFER :: Framebuffer_Handle(0) | |
| 23 | - | NULL_SAMPLER :: Sampler_Handle(0) | |
| 16 | + | NULL_PIPELINE :: Pipeline_Handle(0) | |
| 17 | + | NULL_BUFFER :: Buffer_Handle(0) | |
| 18 | + | NULL_TEXTURE :: Texture_Handle(0) | |
| 19 | + | NULL_SHADER :: Shader_Handle(0) | |
| 20 | + | NULL_DESCRIPTOR :: Descriptor_Handle(0) | |
| 21 | + | NULL_RENDER_PASS :: Render_Pass_Handle(0) | |
| 22 | + | NULL_FRAMEBUFFER :: Framebuffer_Handle(0) | |
| 23 | + | NULL_SAMPLER :: Sampler_Handle(0) | |
| 24 | 24 | ||
| 25 | 25 | MAX_FRAMES_IN_FLIGHT :: 2 | |
| 26 | 26 | ||
| … | 9 unchanged lines hidden | ||
| 36 | 36 | Capability_Flags :: bit_set[Capability] | |
| 37 | 37 | ||
| 38 | 38 | Capabilities :: struct { | |
| 39 | - | features: Capability_Flags, | |
| 40 | - | max_color_targets: u32, | |
| 39 | + | features: Capability_Flags, | |
| 40 | + | max_color_targets: u32, | |
| 41 | 41 | max_push_constant_size: u32, | |
| 42 | - | max_frames_in_flight: u32, | |
| 42 | + | max_frames_in_flight: u32, | |
| 43 | 43 | } | |
| 44 | 44 | ||
| 45 | 45 | no_capabilities :: proc() -> Capabilities { | |
| 46 | 46 | return {} | |
| 47 | 47 | } | |
| 48 | 48 | ||
| 49 | - | implemented_base_capabilities :: proc(max_color_targets, max_push_constant_size: u32) -> Capabilities { | |
| 49 | + | implemented_base_capabilities :: proc( | |
| 50 | + | max_color_targets, max_push_constant_size: u32, | |
| 51 | + | ) -> Capabilities { | |
| 50 | 52 | return { | |
| 51 | - | features = { | |
| 52 | - | .Compute_Dispatch, | |
| 53 | - | .Storage_Buffers, | |
| 54 | - | .Offscreen_Targets, | |
| 55 | - | .Sampled_Targets, | |
| 56 | - | }, | |
| 53 | + | features = {.Compute_Dispatch, .Storage_Buffers, .Offscreen_Targets, .Sampled_Targets}, | |
| 57 | 54 | max_color_targets = max_color_targets, | |
| 58 | 55 | max_push_constant_size = max_push_constant_size, | |
| 59 | 56 | max_frames_in_flight = MAX_FRAMES_IN_FLIGHT, | |
| … | 231 unchanged lines hidden | ||
| 291 | 288 | } | |
| 292 | 289 | ||
| 293 | 290 | Blend_Mode :: enum u8 { | |
| 294 | - | Alpha, // src*α + dst*(1-α) | |
| 295 | - | Additive, // src*α + dst | |
| 291 | + | Alpha, // src*α + dst*(1-α) | |
| 292 | + | Additive, // src*α + dst | |
| 296 | 293 | Premultiplied_Alpha, // src + dst*(1-α) | |
| 297 | 294 | } | |
| 298 | 295 | ||
| 296 | + | Blend_Factor :: enum { | |
| 297 | + | Zero, | |
| 298 | + | One, | |
| 299 | + | Src_Alpha, | |
| 300 | + | One_Minus_Src_Alpha, | |
| 301 | + | } | |
| 302 | + | ||
| 303 | + | Blend_Factors :: struct { | |
| 304 | + | src_color: Blend_Factor, | |
| 305 | + | dst_color: Blend_Factor, | |
| 306 | + | src_alpha: Blend_Factor, | |
| 307 | + | dst_alpha: Blend_Factor, | |
| 308 | + | } | |
| 309 | + | ||
| 310 | + | blend_factors :: proc(mode: Blend_Mode) -> Blend_Factors { | |
| 311 | + | switch mode { | |
| 312 | + | case .Alpha: | |
| 313 | + | return {.Src_Alpha, .One_Minus_Src_Alpha, .One, .One_Minus_Src_Alpha} | |
| 314 | + | case .Additive: | |
| 315 | + | return {.Src_Alpha, .One, .One, .One} | |
| 316 | + | case .Premultiplied_Alpha: | |
| 317 | + | return {.One, .One_Minus_Src_Alpha, .One, .One_Minus_Src_Alpha} | |
| 318 | + | } | |
| 319 | + | return {.Src_Alpha, .One_Minus_Src_Alpha, .One, .One_Minus_Src_Alpha} | |
| 320 | + | } | |
| 321 | + | ||
| 299 | 322 | Pipeline_Desc :: struct { | |
| 300 | - | vert_shader: Shader_Handle, | |
| 301 | - | frag_shader: Shader_Handle, | |
| 302 | - | render_pass: Render_Pass_Handle, | |
| 303 | - | topology: Topology, | |
| 304 | - | cull_mode: Cull_Mode, | |
| 305 | - | front_face: Front_Face, | |
| 306 | - | enable_blending: bool, | |
| 307 | - | blend_mode: Blend_Mode, | |
| 308 | - | enable_depth_test: bool, | |
| 309 | - | enable_depth_bias: bool, | |
| 310 | - | depth_only: bool, | |
| 311 | - | push_constant_size: u32, | |
| 323 | + | vert_shader: Shader_Handle, | |
| 324 | + | frag_shader: Shader_Handle, | |
| 325 | + | render_pass: Render_Pass_Handle, | |
| 326 | + | topology: Topology, | |
| 327 | + | cull_mode: Cull_Mode, | |
| 328 | + | front_face: Front_Face, | |
| 329 | + | enable_blending: bool, | |
| 330 | + | blend_mode: Blend_Mode, | |
| 331 | + | enable_depth_test: bool, | |
| 332 | + | enable_depth_bias: bool, | |
| 333 | + | depth_only: bool, | |
| 334 | + | push_constant_size: u32, | |
| 312 | 335 | push_constant_stages: Shader_Stage_Flags, | |
| 313 | - | descriptor_layouts: []Descriptor_Handle, | |
| 314 | - | vertex_bindings: []Vertex_Binding, | |
| 315 | - | vertex_attributes: []Vertex_Attribute, | |
| 336 | + | descriptor_layouts: []Descriptor_Handle, | |
| 337 | + | vertex_bindings: []Vertex_Binding, | |
| 338 | + | vertex_attributes: []Vertex_Attribute, | |
| 316 | 339 | } | |
| 317 | 340 | ||
| 318 | 341 | Buffer_Desc :: struct { | |
| 319 | - | size: u64, | |
| 320 | - | usage: Buffer_Usage_Flags, | |
| 321 | - | memory: Memory_Property_Flags, | |
| 342 | + | size: u64, | |
| 343 | + | usage: Buffer_Usage_Flags, | |
| 344 | + | memory: Memory_Property_Flags, | |
| 322 | 345 | } | |
| 323 | 346 | ||
| 324 | 347 | Texture_Desc :: struct { | |
| … | 4 unchanged lines hidden | ||
| 329 | 352 | } | |
| 330 | 353 | ||
| 331 | 354 | Sampler_Desc :: struct { | |
| 332 | - | mag_filter: Filter, | |
| 333 | - | min_filter: Filter, | |
| 334 | - | address_mode_u: Address_Mode, | |
| 335 | - | address_mode_v: Address_Mode, | |
| 336 | - | enable_aniso: bool, | |
| 337 | - | enable_compare: bool, | |
| 338 | - | compare_op: Compare_Op, | |
| 339 | - | mipmap_mode: Filter, | |
| 355 | + | mag_filter: Filter, | |
| 356 | + | min_filter: Filter, | |
| 357 | + | address_mode_u: Address_Mode, | |
| 358 | + | address_mode_v: Address_Mode, | |
| 359 | + | enable_aniso: bool, | |
| 360 | + | enable_compare: bool, | |
| 361 | + | compare_op: Compare_Op, | |
| 362 | + | mipmap_mode: Filter, | |
| 340 | 363 | } | |
| 341 | 364 | ||
| 342 | 365 | Descriptor_Set_Layout_Binding :: struct { | |
| 343 | - | binding: u32, | |
| 344 | - | type: Descriptor_Type, | |
| 345 | - | count: u32, | |
| 346 | - | stages: Shader_Stage_Flags, | |
| 366 | + | binding: u32, | |
| 367 | + | type: Descriptor_Type, | |
| 368 | + | count: u32, | |
| 369 | + | stages: Shader_Stage_Flags, | |
| 347 | 370 | } | |
| 348 | 371 | ||
| 349 | 372 | Render_Pass_Desc :: struct { | |
| 350 | - | has_color: bool, | |
| 351 | - | has_depth: bool, | |
| 352 | - | color_format: Format, | |
| 353 | - | depth_format: Format, | |
| 354 | - | depth_only: bool, // depth-only pass (shadows) | |
| 355 | - | ||
| 373 | + | has_color: bool, | |
| 374 | + | has_depth: bool, | |
| 375 | + | color_format: Format, | |
| 376 | + | depth_format: Format, | |
| 377 | + | depth_only: bool, // depth-only pass (shadows) | |
| 356 | 378 | color_load_op: Attachment_Load_Op, | |
| 357 | 379 | color_store_op: Attachment_Store_Op, | |
| 358 | 380 | color_final_layout: Image_Layout, | |
| … | 41 unchanged lines hidden | ||
| 400 | 422 | // Backend is a struct of proc pointers that abstract GPU operations. | |
| 401 | 423 | // Each backend implementation (Vulkan, D3D11, D3D12) populates these. | |
| 402 | 424 | Backend :: struct { | |
| 403 | - | capabilities: Capabilities, | |
| 425 | + | capabilities: Capabilities, | |
| 404 | 426 | ||
| 405 | 427 | // --- Lifecycle --- | |
| 406 | - | shutdown: proc(), | |
| 407 | - | wait_idle: proc(), | |
| 428 | + | shutdown: proc(), | |
| 429 | + | wait_idle: proc(), | |
| 408 | 430 | ||
| 409 | 431 | // --- Frame --- | |
| 410 | - | begin_frame: proc(clear_color: [4]f32) -> (Frame_Context, bool), | |
| 411 | - | end_frame: proc(ctx: Frame_Context) -> bool, // returns true if swapchain recreated | |
| 412 | - | on_resize: proc(width, height: u32), | |
| 413 | - | get_extent: proc() -> Extent, | |
| 414 | - | current_frame_index: proc() -> u32, | |
| 432 | + | begin_frame: proc(clear_color: [4]f32) -> (Frame_Context, bool), | |
| 433 | + | end_frame: proc(ctx: Frame_Context) -> bool, // returns true if swapchain recreated | |
| 434 | + | on_resize: proc(width, height: u32), | |
| 435 | + | get_extent: proc() -> Extent, | |
| 436 | + | current_frame_index: proc() -> u32, | |
| 415 | 437 | ||
| 416 | 438 | // --- Render pass --- | |
| 417 | - | begin_render_pass: proc(ctx: Frame_Context, desc: Render_Pass_Begin_Desc), | |
| 418 | - | begin_default_pass: proc(ctx: Frame_Context, clear_color: [4]f32), | |
| 419 | - | end_render_pass: proc(ctx: Frame_Context), | |
| 420 | - | set_viewport: proc(ctx: Frame_Context, x, y, w, h: f32), | |
| 421 | - | set_scissor: proc(ctx: Frame_Context, x, y: i32, w, h: u32), | |
| 422 | - | set_depth_bias: proc(ctx: Frame_Context, constant, slope: f32), | |
| 439 | + | begin_render_pass: proc(ctx: Frame_Context, desc: Render_Pass_Begin_Desc), | |
| 440 | + | begin_default_pass: proc(ctx: Frame_Context, clear_color: [4]f32), | |
| 441 | + | end_render_pass: proc(ctx: Frame_Context), | |
| 442 | + | set_viewport: proc(ctx: Frame_Context, x, y, w, h: f32), | |
| 443 | + | set_scissor: proc(ctx: Frame_Context, x, y: i32, w, h: u32), | |
| 444 | + | set_depth_bias: proc(ctx: Frame_Context, constant, slope: f32), | |
| 423 | 445 | ||
| 424 | 446 | // --- Pipeline --- | |
| 425 | - | create_graphics_pipeline: proc(desc: Pipeline_Desc) -> (Pipeline_Handle, bool), | |
| 426 | - | destroy_graphics_pipeline: proc(handle: Pipeline_Handle), | |
| 427 | - | bind_graphics_pipeline: proc(ctx: Frame_Context, handle: Pipeline_Handle), | |
| 428 | - | push_constants: proc(ctx: Frame_Context, pipeline: Pipeline_Handle, stages: Shader_Stage_Flags, offset, size: u32, data: rawptr), | |
| 447 | + | create_graphics_pipeline: proc(desc: Pipeline_Desc) -> (Pipeline_Handle, bool), | |
| 448 | + | destroy_graphics_pipeline: proc(handle: Pipeline_Handle), | |
| 449 | + | bind_graphics_pipeline: proc(ctx: Frame_Context, handle: Pipeline_Handle), | |
| 450 | + | push_constants: proc( | |
| 451 | + | ctx: Frame_Context, | |
| 452 | + | pipeline: Pipeline_Handle, | |
| 453 | + | stages: Shader_Stage_Flags, | |
| 454 | + | offset, size: u32, | |
| 455 | + | data: rawptr, | |
| 456 | + | ), | |
| 429 | 457 | ||
| 430 | 458 | // --- Buffers --- | |
| 431 | - | create_buffer: proc(desc: Buffer_Desc) -> (Buffer_Handle, bool), | |
| 432 | - | create_buffer_staged: proc(data: rawptr, size: int, usage: Buffer_Usage_Flags) -> (Buffer_Handle, bool), | |
| 433 | - | destroy_buffer: proc(handle: Buffer_Handle), | |
| 434 | - | map_buffer: proc(handle: Buffer_Handle) -> rawptr, | |
| 435 | - | unmap_buffer: proc(handle: Buffer_Handle), | |
| 436 | - | get_buffer_mapped: proc(handle: Buffer_Handle) -> rawptr, | |
| 437 | - | bind_vertex_buffer: proc(ctx: Frame_Context, handle: Buffer_Handle), | |
| 438 | - | bind_index_buffer: proc(ctx: Frame_Context, handle: Buffer_Handle), | |
| 459 | + | create_buffer: proc(desc: Buffer_Desc) -> (Buffer_Handle, bool), | |
| 460 | + | create_buffer_staged: proc( | |
| 461 | + | data: rawptr, | |
| 462 | + | size: int, | |
| 463 | + | usage: Buffer_Usage_Flags, | |
| 464 | + | ) -> ( | |
| 465 | + | Buffer_Handle, | |
| 466 | + | bool, | |
| 467 | + | ), | |
| 468 | + | destroy_buffer: proc(handle: Buffer_Handle), | |
| 469 | + | map_buffer: proc(handle: Buffer_Handle) -> rawptr, | |
| 470 | + | unmap_buffer: proc(handle: Buffer_Handle), | |
| 471 | + | get_buffer_mapped: proc(handle: Buffer_Handle) -> rawptr, | |
| 472 | + | bind_vertex_buffer: proc(ctx: Frame_Context, handle: Buffer_Handle), | |
| 473 | + | bind_index_buffer: proc(ctx: Frame_Context, handle: Buffer_Handle), | |
| 439 | 474 | ||
| 440 | 475 | // --- Textures --- | |
| 441 | - | create_texture: proc(desc: Texture_Desc, pixels: rawptr) -> (Texture_Handle, bool), | |
| 442 | - | destroy_texture: proc(handle: Texture_Handle), | |
| 476 | + | create_texture: proc( | |
| 477 | + | desc: Texture_Desc, | |
| 478 | + | pixels: rawptr, | |
| 479 | + | ) -> ( | |
| 480 | + | Texture_Handle, | |
| 481 | + | bool, | |
| 482 | + | ), | |
| 483 | + | destroy_texture: proc(handle: Texture_Handle), | |
| 443 | 484 | ||
| 444 | 485 | // --- Samplers --- | |
| 445 | - | create_sampler: proc(desc: Sampler_Desc) -> (Sampler_Handle, bool), | |
| 446 | - | destroy_sampler: proc(handle: Sampler_Handle), | |
| 486 | + | create_sampler: proc(desc: Sampler_Desc) -> (Sampler_Handle, bool), | |
| 487 | + | destroy_sampler: proc(handle: Sampler_Handle), | |
| 447 | 488 | ||
| 448 | 489 | // --- Images (for depth/shadow targets) --- | |
| 449 | - | create_image: proc(desc: Texture_Desc) -> (Texture_Handle, bool), | |
| 450 | - | create_image_view: proc(texture: Texture_Handle, format: Format, aspect: Image_Aspect_Flags) -> bool, | |
| 451 | - | destroy_image: proc(handle: Texture_Handle), | |
| 490 | + | create_image: proc(desc: Texture_Desc) -> (Texture_Handle, bool), | |
| 491 | + | create_image_view: proc( | |
| 492 | + | texture: Texture_Handle, | |
| 493 | + | format: Format, | |
| 494 | + | aspect: Image_Aspect_Flags, | |
| 495 | + | ) -> bool, | |
| 496 | + | destroy_image: proc(handle: Texture_Handle), | |
| 452 | 497 | ||
| 453 | 498 | // --- Descriptors --- | |
| 454 | - | create_descriptor_set_layout: proc(bindings: []Descriptor_Set_Layout_Binding) -> (Descriptor_Handle, bool), | |
| 499 | + | create_descriptor_set_layout: proc( | |
| 500 | + | bindings: []Descriptor_Set_Layout_Binding, | |
| 501 | + | ) -> ( | |
| 502 | + | Descriptor_Handle, | |
| 503 | + | bool, | |
| 504 | + | ), | |
| 455 | 505 | destroy_descriptor_set_layout: proc(handle: Descriptor_Handle), | |
| 456 | - | create_descriptor_pool: proc(max_sets: u32, types: []Descriptor_Type, counts: []u32) -> (Descriptor_Handle, bool), | |
| 506 | + | create_descriptor_pool: proc( | |
| 507 | + | max_sets: u32, | |
| 508 | + | types: []Descriptor_Type, | |
| 509 | + | counts: []u32, | |
| 510 | + | ) -> ( | |
| 511 | + | Descriptor_Handle, | |
| 512 | + | bool, | |
| 513 | + | ), | |
| 457 | 514 | destroy_descriptor_pool: proc(handle: Descriptor_Handle), | |
| 458 | - | allocate_descriptor_set: proc(pool: Descriptor_Handle, layout: Descriptor_Handle) -> (Descriptor_Handle, bool), | |
| 459 | - | bind_descriptor_set: proc(ctx: Frame_Context, pipeline: Pipeline_Handle, set: Descriptor_Handle, index: u32), | |
| 460 | - | update_descriptor_image: proc(set: Descriptor_Handle, binding: u32, texture: Texture_Handle, sampler: Sampler_Handle, layout: Image_Layout), | |
| 461 | - | update_descriptor_buffer: proc(set: Descriptor_Handle, binding: u32, buffer: Buffer_Handle, size: u64), | |
| 515 | + | allocate_descriptor_set: proc( | |
| 516 | + | pool: Descriptor_Handle, | |
| 517 | + | layout: Descriptor_Handle, | |
| 518 | + | ) -> ( | |
| 519 | + | Descriptor_Handle, | |
| 520 | + | bool, | |
| 521 | + | ), | |
| 522 | + | bind_descriptor_set: proc( | |
| 523 | + | ctx: Frame_Context, | |
| 524 | + | pipeline: Pipeline_Handle, | |
| 525 | + | set: Descriptor_Handle, | |
| 526 | + | index: u32, | |
| 527 | + | ), | |
| 528 | + | update_descriptor_image: proc( | |
| 529 | + | set: Descriptor_Handle, | |
| 530 | + | binding: u32, | |
| 531 | + | texture: Texture_Handle, | |
| 532 | + | sampler: Sampler_Handle, | |
| 533 | + | layout: Image_Layout, | |
| 534 | + | ), | |
| 535 | + | update_descriptor_buffer: proc( | |
| 536 | + | set: Descriptor_Handle, | |
| 537 | + | binding: u32, | |
| 538 | + | buffer: Buffer_Handle, | |
| 539 | + | size: u64, | |
| 540 | + | ), | |
| 462 | 541 | ||
| 463 | 542 | // --- Render pass objects --- | |
| 464 | - | create_render_pass: proc(desc: Render_Pass_Desc) -> (Render_Pass_Handle, bool), | |
| 465 | - | destroy_render_pass: proc(handle: Render_Pass_Handle), | |
| 466 | - | create_framebuffer: proc(desc: Framebuffer_Desc) -> (Framebuffer_Handle, bool), | |
| 467 | - | destroy_framebuffer: proc(handle: Framebuffer_Handle), | |
| 543 | + | create_render_pass: proc(desc: Render_Pass_Desc) -> (Render_Pass_Handle, bool), | |
| 544 | + | destroy_render_pass: proc(handle: Render_Pass_Handle), | |
| 545 | + | create_framebuffer: proc(desc: Framebuffer_Desc) -> (Framebuffer_Handle, bool), | |
| 546 | + | destroy_framebuffer: proc(handle: Framebuffer_Handle), | |
| 468 | 547 | ||
| 469 | 548 | // --- Shaders --- | |
| 470 | - | create_shader_module: proc(desc: Shader_Module_Desc) -> (Shader_Handle, bool), | |
| 471 | - | destroy_shader: proc(handle: Shader_Handle), | |
| 549 | + | create_shader_module: proc(desc: Shader_Module_Desc) -> (Shader_Handle, bool), | |
| 550 | + | destroy_shader: proc(handle: Shader_Handle), | |
| 472 | 551 | ||
| 473 | 552 | // --- Draw --- | |
| 474 | - | draw_indexed: proc(ctx: Frame_Context, index_count, instance_count: u32, first_index: u32, vertex_offset: i32, first_instance: u32), | |
| 553 | + | draw_indexed: proc( | |
| 554 | + | ctx: Frame_Context, | |
| 555 | + | index_count, instance_count: u32, | |
| 556 | + | first_index: u32, | |
| 557 | + | vertex_offset: i32, | |
| 558 | + | first_instance: u32, | |
| 559 | + | ), | |
| 475 | 560 | ||
| 476 | 561 | // --- Compute --- | |
| 477 | - | create_compute_pipeline: proc(shader: Shader_Handle, num_buffers: u32, push_constant_size: u32) -> (Pipeline_Handle, bool), | |
| 478 | - | destroy_compute_pipeline: proc(handle: Pipeline_Handle), | |
| 479 | - | bind_compute_pipeline: proc(ctx: Frame_Context, handle: Pipeline_Handle), | |
| 480 | - | dispatch_compute: proc(ctx: Frame_Context, groups_x, groups_y, groups_z: u32), | |
| 481 | - | compute_barrier: proc(ctx: Frame_Context), | |
| 562 | + | create_compute_pipeline: proc( | |
| 563 | + | shader: Shader_Handle, | |
| 564 | + | num_buffers: u32, | |
| 565 | + | push_constant_size: u32, | |
| 566 | + | ) -> ( | |
| 567 | + | Pipeline_Handle, | |
| 568 | + | bool, | |
| 569 | + | ), | |
| 570 | + | destroy_compute_pipeline: proc(handle: Pipeline_Handle), | |
| 571 | + | bind_compute_pipeline: proc(ctx: Frame_Context, handle: Pipeline_Handle), | |
| 572 | + | dispatch_compute: proc(ctx: Frame_Context, groups_x, groups_y, groups_z: u32), | |
| 573 | + | compute_barrier: proc(ctx: Frame_Context), | |
| 482 | 574 | ||
| 483 | 575 | // --- Sync --- | |
| 484 | - | get_default_render_pass: proc() -> Render_Pass_Handle, | |
| 485 | - | get_depth_format: proc() -> Format, | |
| 576 | + | get_default_render_pass: proc() -> Render_Pass_Handle, | |
| 577 | + | get_depth_format: proc() -> Format, | |
| 486 | 578 | } | |
| 487 | 579 | ||
| 488 | 580 | backend_vtable_is_complete :: proc(b: ^Backend) -> bool { | |
| 489 | 581 | if b == nil do return false | |
| 490 | - | return b.shutdown != nil && | |
| 491 | - | b.wait_idle != nil && | |
| 492 | - | b.begin_frame != nil && | |
| 493 | - | b.end_frame != nil && | |
| 494 | - | b.on_resize != nil && | |
| 495 | - | b.get_extent != nil && | |
| 496 | - | b.current_frame_index != nil && | |
| 497 | - | b.begin_render_pass != nil && | |
| 498 | - | b.begin_default_pass != nil && | |
| 499 | - | b.end_render_pass != nil && | |
| 500 | - | b.set_viewport != nil && | |
| 501 | - | b.set_scissor != nil && | |
| 502 | - | b.set_depth_bias != nil && | |
| 503 | - | b.create_graphics_pipeline != nil && | |
| 504 | - | b.destroy_graphics_pipeline != nil && | |
| 505 | - | b.bind_graphics_pipeline != nil && | |
| 506 | - | b.push_constants != nil && | |
| 507 | - | b.create_buffer != nil && | |
| 508 | - | b.create_buffer_staged != nil && | |
| 509 | - | b.destroy_buffer != nil && | |
| 510 | - | b.map_buffer != nil && | |
| 511 | - | b.unmap_buffer != nil && | |
| 512 | - | b.get_buffer_mapped != nil && | |
| 513 | - | b.bind_vertex_buffer != nil && | |
| 514 | - | b.bind_index_buffer != nil && | |
| 515 | - | b.create_texture != nil && | |
| 516 | - | b.destroy_texture != nil && | |
| 517 | - | b.create_sampler != nil && | |
| 518 | - | b.destroy_sampler != nil && | |
| 519 | - | b.create_image != nil && | |
| 520 | - | b.create_image_view != nil && | |
| 521 | - | b.destroy_image != nil && | |
| 522 | - | b.create_descriptor_set_layout != nil && | |
| 523 | - | b.destroy_descriptor_set_layout != nil && | |
| 524 | - | b.create_descriptor_pool != nil && | |
| 525 | - | b.destroy_descriptor_pool != nil && | |
| 526 | - | b.allocate_descriptor_set != nil && | |
| 527 | - | b.bind_descriptor_set != nil && | |
| 528 | - | b.update_descriptor_image != nil && | |
| 529 | - | b.update_descriptor_buffer != nil && | |
| 530 | - | b.create_render_pass != nil && | |
| 531 | - | b.destroy_render_pass != nil && | |
| 532 | - | b.create_framebuffer != nil && | |
| 533 | - | b.destroy_framebuffer != nil && | |
| 534 | - | b.create_shader_module != nil && | |
| 535 | - | b.destroy_shader != nil && | |
| 536 | - | b.draw_indexed != nil && | |
| 537 | - | b.create_compute_pipeline != nil && | |
| 538 | - | b.destroy_compute_pipeline != nil && | |
| 539 | - | b.bind_compute_pipeline != nil && | |
| 540 | - | b.dispatch_compute != nil && | |
| 541 | - | b.compute_barrier != nil && | |
| 542 | - | b.get_default_render_pass != nil && | |
| 543 | - | b.get_depth_format != nil | |
| 582 | + | return( | |
| 583 | + | b.shutdown != nil && | |
| 584 | + | b.wait_idle != nil && | |
| 585 | + | b.begin_frame != nil && | |
| 586 | + | b.end_frame != nil && | |
| 587 | + | b.on_resize != nil && | |
| 588 | + | b.get_extent != nil && | |
| 589 | + | b.current_frame_index != nil && | |
| 590 | + | b.begin_render_pass != nil && | |
| 591 | + | b.begin_default_pass != nil && | |
| 592 | + | b.end_render_pass != nil && | |
| 593 | + | b.set_viewport != nil && | |
| 594 | + | b.set_scissor != nil && | |
| 595 | + | b.set_depth_bias != nil && | |
| 596 | + | b.create_graphics_pipeline != nil && | |
| 597 | + | b.destroy_graphics_pipeline != nil && | |
| 598 | + | b.bind_graphics_pipeline != nil && | |
| 599 | + | b.push_constants != nil && | |
| 600 | + | b.create_buffer != nil && | |
| 601 | + | b.create_buffer_staged != nil && | |
| 602 | + | b.destroy_buffer != nil && | |
| 603 | + | b.map_buffer != nil && | |
| 604 | + | b.unmap_buffer != nil && | |
| 605 | + | b.get_buffer_mapped != nil && | |
| 606 | + | b.bind_vertex_buffer != nil && | |
| 607 | + | b.bind_index_buffer != nil && | |
| 608 | + | b.create_texture != nil && | |
| 609 | + | b.destroy_texture != nil && | |
| 610 | + | b.create_sampler != nil && | |
| 611 | + | b.destroy_sampler != nil && | |
| 612 | + | b.create_image != nil && | |
| 613 | + | b.create_image_view != nil && | |
| 614 | + | b.destroy_image != nil && | |
| 615 | + | b.create_descriptor_set_layout != nil && | |
| 616 | + | b.destroy_descriptor_set_layout != nil && | |
| 617 | + | b.create_descriptor_pool != nil && | |
| 618 | + | b.destroy_descriptor_pool != nil && | |
| 619 | + | b.allocate_descriptor_set != nil && | |
| 620 | + | b.bind_descriptor_set != nil && | |
| 621 | + | b.update_descriptor_image != nil && | |
| 622 | + | b.update_descriptor_buffer != nil && | |
| 623 | + | b.create_render_pass != nil && | |
| 624 | + | b.destroy_render_pass != nil && | |
| 625 | + | b.create_framebuffer != nil && | |
| 626 | + | b.destroy_framebuffer != nil && | |
| 627 | + | b.create_shader_module != nil && | |
| 628 | + | b.destroy_shader != nil && | |
| 629 | + | b.draw_indexed != nil && | |
| 630 | + | b.create_compute_pipeline != nil && | |
| 631 | + | b.destroy_compute_pipeline != nil && | |
| 632 | + | b.bind_compute_pipeline != nil && | |
| 633 | + | b.dispatch_compute != nil && | |
| 634 | + | b.compute_barrier != nil && | |
| 635 | + | b.get_default_render_pass != nil && | |
| 636 | + | b.get_depth_format != nil \ | |
| 637 | + | ) | |
| 544 | 638 | } | |
| 545 | 639 | ||
| 546 | 640 | // Initialized flag | |
| … | 1 unchanged lines hidden | ||
| … | 15 unchanged lines hidden | ||
| 16 | 16 | ||
| 17 | 17 | D3D11_State :: struct { | |
| 18 | 18 | // Core D3D11 objects | |
| 19 | - | device: ^d3d11.IDevice, | |
| 20 | - | ctx: ^d3d11.IDeviceContext, | |
| 21 | - | swap_chain: ^dxgi.ISwapChain1, | |
| 22 | - | feature_level: d3d11.FEATURE_LEVEL, | |
| 19 | + | device: ^d3d11.IDevice, | |
| 20 | + | ctx: ^d3d11.IDeviceContext, | |
| 21 | + | swap_chain: ^dxgi.ISwapChain1, | |
| 22 | + | feature_level: d3d11.FEATURE_LEVEL, | |
| 23 | 23 | ||
| 24 | 24 | // Backbuffer | |
| 25 | - | backbuffer_rtv: ^d3d11.IRenderTargetView, | |
| 26 | - | depth_tex: ^d3d11.ITexture2D, | |
| 27 | - | depth_dsv: ^d3d11.IDepthStencilView, | |
| 28 | - | width: u32, | |
| 29 | - | height: u32, | |
| 25 | + | backbuffer_rtv: ^d3d11.IRenderTargetView, | |
| 26 | + | depth_tex: ^d3d11.ITexture2D, | |
| 27 | + | depth_dsv: ^d3d11.IDepthStencilView, | |
| 28 | + | width: u32, | |
| 29 | + | height: u32, | |
| 30 | 30 | ||
| 31 | 31 | // Push constants emulation: constant buffer at slot b15 | |
| 32 | - | push_constant_buf: ^d3d11.IBuffer, | |
| 32 | + | push_constant_buf: ^d3d11.IBuffer, | |
| 33 | 33 | ||
| 34 | 34 | // Depth format | |
| 35 | - | depth_format: dxgi.FORMAT, | |
| 35 | + | depth_format: dxgi.FORMAT, | |
| 36 | 36 | ||
| 37 | 37 | // Default render pass handle | |
| 38 | - | default_render_pass: bk.Render_Pass_Handle, | |
| 38 | + | default_render_pass: bk.Render_Pass_Handle, | |
| 39 | 39 | ||
| 40 | 40 | // Current frame state | |
| 41 | - | current_frame: u32, | |
| 42 | - | frame_active: bool, | |
| 43 | - | clear_color: [4]f32, | |
| 41 | + | current_frame: u32, | |
| 42 | + | frame_active: bool, | |
| 43 | + | clear_color: [4]f32, | |
| 44 | 44 | ||
| 45 | 45 | // Current render pass state | |
| 46 | - | render_pass_active: bool, | |
| 46 | + | render_pass_active: bool, | |
| 47 | 47 | ||
| 48 | 48 | // Current pipeline state (for depth bias caching and vertex stride) | |
| 49 | - | current_rasterizer_desc: d3d11.RASTERIZER_DESC, | |
| 49 | + | current_rasterizer_desc: d3d11.RASTERIZER_DESC, | |
| 50 | 50 | current_rasterizer_state: ^d3d11.IRasterizerState, | |
| 51 | - | current_vertex_stride: u32, | |
| 51 | + | current_vertex_stride: u32, | |
| 52 | + | current_pipeline: bk.Pipeline_Handle, | |
| 52 | 53 | ||
| 53 | 54 | // Handle pools | |
| 54 | - | buffers: [MAX_BUFFERS]D3D11_Buffer_Entry, | |
| 55 | - | textures: [MAX_TEXTURES]D3D11_Texture_Entry, | |
| 56 | - | pipelines: [MAX_PIPELINES]D3D11_Pipeline_Entry, | |
| 57 | - | shaders: [MAX_SHADERS]D3D11_Shader_Entry, | |
| 58 | - | descriptors: [MAX_DESCRIPTORS]D3D11_Descriptor_Entry, | |
| 59 | - | render_passes: [MAX_RENDER_PASSES]D3D11_Render_Pass_Entry, | |
| 60 | - | framebuffers: [MAX_FRAMEBUFFERS]D3D11_Framebuffer_Entry, | |
| 61 | - | samplers: [MAX_SAMPLERS]D3D11_Sampler_Entry, | |
| 62 | - | ||
| 55 | + | buffers: [MAX_BUFFERS]D3D11_Buffer_Entry, | |
| 56 | + | textures: [MAX_TEXTURES]D3D11_Texture_Entry, | |
| 57 | + | pipelines: [MAX_PIPELINES]D3D11_Pipeline_Entry, | |
| 58 | + | shaders: [MAX_SHADERS]D3D11_Shader_Entry, | |
| 59 | + | descriptors: [MAX_DESCRIPTORS]D3D11_Descriptor_Entry, | |
| 60 | + | render_passes: [MAX_RENDER_PASSES]D3D11_Render_Pass_Entry, | |
| 61 | + | framebuffers: [MAX_FRAMEBUFFERS]D3D11_Framebuffer_Entry, | |
| 62 | + | samplers: [MAX_SAMPLERS]D3D11_Sampler_Entry, | |
| 63 | 63 | } | |
| 64 | 64 | ||
| 65 | 65 | // Pool sizes (same as Vulkan backend) | |
| 66 | - | MAX_BUFFERS :: 1024 | |
| 67 | - | MAX_TEXTURES :: 512 | |
| 68 | - | MAX_PIPELINES :: 128 | |
| 69 | - | MAX_SHADERS :: 256 | |
| 70 | - | MAX_DESCRIPTORS :: 512 | |
| 66 | + | MAX_BUFFERS :: 1024 | |
| 67 | + | MAX_TEXTURES :: 512 | |
| 68 | + | MAX_PIPELINES :: 128 | |
| 69 | + | MAX_SHADERS :: 256 | |
| 70 | + | MAX_DESCRIPTORS :: 512 | |
| 71 | 71 | MAX_RENDER_PASSES :: 32 | |
| 72 | - | MAX_FRAMEBUFFERS :: 64 | |
| 73 | - | MAX_SAMPLERS :: 64 | |
| 72 | + | MAX_FRAMEBUFFERS :: 64 | |
| 73 | + | MAX_SAMPLERS :: 64 | |
| 74 | 74 | ||
| 75 | 75 | // Push constant buffer slot (reserved, must not conflict with user cbuffers) | |
| 76 | 76 | // SM5.0 supports slots 0-13 (14 total). Slot 13 is the highest available. | |
| … | 14 unchanged lines hidden | ||
| 91 | 91 | } | |
| 92 | 92 | ||
| 93 | 93 | D3D11_Texture_Entry :: struct { | |
| 94 | - | texture: ^d3d11.ITexture2D, | |
| 95 | - | srv: ^d3d11.IShaderResourceView, | |
| 96 | - | rtv: ^d3d11.IRenderTargetView, | |
| 97 | - | dsv: ^d3d11.IDepthStencilView, | |
| 98 | - | usage: bk.Image_Usage_Flags, | |
| 99 | - | width: u32, | |
| 100 | - | height: u32, | |
| 101 | - | format: dxgi.FORMAT, | |
| 102 | - | active: bool, | |
| 94 | + | texture: ^d3d11.ITexture2D, | |
| 95 | + | srv: ^d3d11.IShaderResourceView, | |
| 96 | + | rtv: ^d3d11.IRenderTargetView, | |
| 97 | + | dsv: ^d3d11.IDepthStencilView, | |
| 98 | + | usage: bk.Image_Usage_Flags, | |
| 99 | + | width: u32, | |
| 100 | + | height: u32, | |
| 101 | + | format: dxgi.FORMAT, | |
| 102 | + | active: bool, | |
| 103 | 103 | } | |
| 104 | 104 | ||
| 105 | 105 | D3D11_Pipeline_Entry :: struct { | |
| 106 | 106 | // Graphics pipeline state | |
| 107 | - | vs: ^d3d11.IVertexShader, | |
| 108 | - | ps: ^d3d11.IPixelShader, | |
| 109 | - | cs: ^d3d11.IComputeShader, | |
| 110 | - | input_layout: ^d3d11.IInputLayout, | |
| 111 | - | rasterizer_state: ^d3d11.IRasterizerState, | |
| 112 | - | blend_state: ^d3d11.IBlendState, | |
| 113 | - | depth_stencil_state: ^d3d11.IDepthStencilState, | |
| 114 | - | topology: d3d11.PRIMITIVE_TOPOLOGY, | |
| 115 | - | rasterizer_desc: d3d11.RASTERIZER_DESC, | |
| 107 | + | vs: ^d3d11.IVertexShader, | |
| 108 | + | ps: ^d3d11.IPixelShader, | |
| 109 | + | cs: ^d3d11.IComputeShader, | |
| 110 | + | input_layout: ^d3d11.IInputLayout, | |
| 111 | + | rasterizer_state: ^d3d11.IRasterizerState, | |
| 112 | + | blend_state: ^d3d11.IBlendState, | |
| 113 | + | depth_stencil_state: ^d3d11.IDepthStencilState, | |
| 114 | + | topology: d3d11.PRIMITIVE_TOPOLOGY, | |
| 115 | + | rasterizer_desc: d3d11.RASTERIZER_DESC, | |
| 116 | 116 | ||
| 117 | 117 | // Pipeline layout info | |
| 118 | - | vertex_stride: u32, | |
| 119 | - | push_constant_size: u32, | |
| 118 | + | vertex_stride: u32, | |
| 119 | + | push_constant_size: u32, | |
| 120 | 120 | push_constant_stages: bk.Shader_Stage_Flags, | |
| 121 | - | ||
| 122 | - | is_compute: bool, | |
| 123 | - | active: bool, | |
| 121 | + | no_draw: bool, | |
| 122 | + | is_compute: bool, | |
| 123 | + | active: bool, | |
| 124 | 124 | } | |
| 125 | 125 | ||
| 126 | 126 | D3D11_Shader_Entry :: struct { | |
| 127 | - | vs_blob: ^d3d11.IBlob, // Keep VS blob for InputLayout creation (alias for d3d_common.ID3DBlob) | |
| 128 | - | vs: ^d3d11.IVertexShader, | |
| 129 | - | ps: ^d3d11.IPixelShader, | |
| 130 | - | cs: ^d3d11.IComputeShader, | |
| 131 | - | stage: bk.Shader_Stage, | |
| 132 | - | active: bool, | |
| 127 | + | vs_blob: ^d3d11.IBlob, // Keep VS blob for InputLayout creation (alias for d3d_common.ID3DBlob) | |
| 128 | + | vs: ^d3d11.IVertexShader, | |
| 129 | + | ps: ^d3d11.IPixelShader, | |
| 130 | + | cs: ^d3d11.IComputeShader, | |
| 131 | + | stage: bk.Shader_Stage, | |
| 132 | + | active: bool, | |
| 133 | 133 | } | |
| 134 | 134 | ||
| 135 | 135 | // Descriptor binding record (D3D11 has no descriptor objects) | |
| 136 | 136 | D3D11_Descriptor_Binding :: struct { | |
| 137 | - | binding: u32, | |
| 138 | - | type: bk.Descriptor_Type, | |
| 137 | + | binding: u32, | |
| 138 | + | type: bk.Descriptor_Type, | |
| 139 | 139 | // Resource references (filled by update_descriptor_*) | |
| 140 | - | buffer: bk.Buffer_Handle, | |
| 141 | - | texture: bk.Texture_Handle, | |
| 142 | - | sampler: bk.Sampler_Handle, | |
| 140 | + | buffer: bk.Buffer_Handle, | |
| 141 | + | texture: bk.Texture_Handle, | |
| 142 | + | sampler: bk.Sampler_Handle, | |
| 143 | 143 | buf_size: u64, | |
| 144 | 144 | } | |
| 145 | 145 | ||
| 146 | 146 | D3D11_Descriptor_Entry :: struct { | |
| 147 | - | kind: Descriptor_Kind, | |
| 147 | + | kind: Descriptor_Kind, | |
| 148 | 148 | // For set layout: binding metadata | |
| 149 | 149 | layout_bindings: [16]bk.Descriptor_Set_Layout_Binding, | |
| 150 | 150 | layout_count: u32, | |
| 151 | 151 | // For set: actual resource bindings | |
| 152 | - | bindings: [16]D3D11_Descriptor_Binding, | |
| 153 | - | binding_count: u32, | |
| 154 | - | active: bool, | |
| 152 | + | bindings: [16]D3D11_Descriptor_Binding, | |
| 153 | + | binding_count: u32, | |
| 154 | + | active: bool, | |
| 155 | 155 | } | |
| 156 | 156 | ||
| 157 | 157 | Descriptor_Kind :: enum { | |
| … | 8 unchanged lines hidden | ||
| 166 | 166 | } | |
| 167 | 167 | ||
| 168 | 168 | D3D11_Framebuffer_Entry :: struct { | |
| 169 | - | rtv: ^d3d11.IRenderTargetView, | |
| 170 | - | dsv: ^d3d11.IDepthStencilView, | |
| 171 | - | color_tex: bk.Texture_Handle, | |
| 172 | - | depth_tex: bk.Texture_Handle, | |
| 173 | - | width: u32, | |
| 174 | - | height: u32, | |
| 175 | - | active: bool, | |
| 169 | + | rtv: ^d3d11.IRenderTargetView, | |
| 170 | + | dsv: ^d3d11.IDepthStencilView, | |
| 171 | + | color_tex: bk.Texture_Handle, | |
| 172 | + | depth_tex: bk.Texture_Handle, | |
| 173 | + | width: u32, | |
| 174 | + | height: u32, | |
| 175 | + | active: bool, | |
| 176 | 176 | } | |
| 177 | 177 | ||
| 178 | 178 | D3D11_Sampler_Entry :: struct { | |
| … | 3 unchanged lines hidden | ||
| 182 | 182 | ||
| 183 | 183 | // --- Init --- | |
| 184 | 184 | ||
| 185 | - | init_d3d11_backend :: proc(surface: bk.Surface_Desc, width, height: u32, title: cstring) -> (backend: bk.Backend, ok: bool) { | |
| 185 | + | init_d3d11_backend :: proc( | |
| 186 | + | surface: bk.Surface_Desc, | |
| 187 | + | width, height: u32, | |
| 188 | + | title: cstring, | |
| 189 | + | ) -> ( | |
| 190 | + | backend: bk.Backend, | |
| 191 | + | ok: bool, | |
| 192 | + | ) { | |
| 186 | 193 | state := new(D3D11_State) | |
| 187 | 194 | if state == nil { | |
| 188 | 195 | log.error("gpu/d3d11: failed to allocate D3D11 state") | |
| … | 10 unchanged lines hidden | ||
| 199 | 206 | hwnd := dxgi.HWND(surface.win32.hwnd) | |
| 200 | 207 | ||
| 201 | 208 | // Create swap chain description | |
| 202 | - | sc_desc := dxgi.SWAP_CHAIN_DESC1{ | |
| 203 | - | Width = width, | |
| 204 | - | Height = height, | |
| 205 | - | Format = .R8G8B8A8_UNORM, | |
| 206 | - | SampleDesc = {Count = 1, Quality = 0}, | |
| 209 | + | sc_desc := dxgi.SWAP_CHAIN_DESC1 { | |
| 210 | + | Width = width, | |
| 211 | + | Height = height, | |
| 212 | + | Format = .R8G8B8A8_UNORM, | |
| 213 | + | SampleDesc = {Count = 1, Quality = 0}, | |
| 207 | 214 | BufferUsage = {.RENDER_TARGET_OUTPUT}, | |
| 208 | 215 | BufferCount = 2, | |
| 209 | - | SwapEffect = .FLIP_DISCARD, | |
| 210 | - | Scaling = .STRETCH, | |
| 216 | + | SwapEffect = .FLIP_DISCARD, | |
| 217 | + | Scaling = .STRETCH, | |
| 211 | 218 | } | |
| 212 | 219 | ||
| 213 | 220 | feature_levels := [?]d3d11.FEATURE_LEVEL{._11_1, ._11_0} | |
| … | 6 unchanged lines hidden | ||
| 220 | 227 | base_device: ^d3d11.IDevice | |
| 221 | 228 | base_ctx: ^d3d11.IDeviceContext | |
| 222 | 229 | result := d3d11.CreateDevice( | |
| 223 | - | nil, // default adapter | |
| 230 | + | nil, // default adapter | |
| 224 | 231 | .HARDWARE, | |
| 225 | - | nil, // no software rasterizer | |
| 232 | + | nil, // no software rasterizer | |
| 226 | 233 | flags, | |
| 227 | 234 | &feature_levels[0], | |
| 228 | 235 | u32(len(feature_levels)), | |
| … | 44 unchanged lines hidden | ||
| 273 | 280 | state.device, | |
| 274 | 281 | hwnd, | |
| 275 | 282 | &sc_desc, | |
| 276 | - | nil, // no fullscreen desc | |
| 277 | - | nil, // no restrict to output | |
| 283 | + | nil, // no fullscreen desc | |
| 284 | + | nil, // no restrict to output | |
| 278 | 285 | &state.swap_chain, | |
| 279 | 286 | ) | |
| 280 | 287 | if result < 0 { | |
| … | 19 unchanged lines hidden | ||
| 300 | 307 | } | |
| 301 | 308 | ||
| 302 | 309 | // Create push constant buffer | |
| 303 | - | pc_buf_desc := d3d11.BUFFER_DESC{ | |
| 310 | + | pc_buf_desc := d3d11.BUFFER_DESC { | |
| 304 | 311 | ByteWidth = PUSH_CONSTANT_MAX_SIZE, | |
| 305 | 312 | Usage = .DYNAMIC, | |
| 306 | 313 | BindFlags = {.CONSTANT_BUFFER}, | |
| … | 13 unchanged lines hidden | ||
| 320 | 327 | shutdown_d3d11() | |
| 321 | 328 | return {}, false | |
| 322 | 329 | } | |
| 323 | - | state.render_passes[rp_handle].desc = bk.Render_Pass_Desc{ | |
| 330 | + | state.render_passes[rp_handle].desc = bk.Render_Pass_Desc { | |
| 324 | 331 | has_color = true, | |
| 325 | 332 | has_depth = true, | |
| 326 | 333 | color_format = .R8G8B8A8_UNORM, | |
| … | 3 unchanged lines hidden | ||
| 330 | 337 | state.default_render_pass = rp_handle | |
| 331 | 338 | ||
| 332 | 339 | // Populate backend vtable | |
| 333 | - | backend = bk.Backend{ | |
| 334 | - | capabilities = bk.implemented_base_capabilities(1, PUSH_CONSTANT_MAX_SIZE), | |
| 340 | + | backend = bk.Backend { | |
| 341 | + | capabilities = bk.implemented_base_capabilities( | |
| 342 | + | 1, | |
| 343 | + | PUSH_CONSTANT_MAX_SIZE, | |
| 344 | + | ), | |
| 335 | 345 | ||
| 336 | 346 | // Lifecycle | |
| 337 | - | shutdown = shutdown_d3d11, | |
| 338 | - | wait_idle = wait_idle_d3d11, | |
| 347 | + | shutdown = shutdown_d3d11, | |
| 348 | + | wait_idle = wait_idle_d3d11, | |
| 339 | 349 | ||
| 340 | 350 | // Frame | |
| 341 | - | begin_frame = begin_frame_d3d11, | |
| 342 | - | end_frame = end_frame_d3d11, | |
| 343 | - | on_resize = on_resize_d3d11, | |
| 344 | - | get_extent = get_extent_d3d11, | |
| 345 | - | current_frame_index = get_current_frame_d3d11, | |
| 351 | + | begin_frame = begin_frame_d3d11, | |
| 352 | + | end_frame = end_frame_d3d11, | |
| 353 | + | on_resize = on_resize_d3d11, | |
| 354 | + | get_extent = get_extent_d3d11, | |
| 355 | + | current_frame_index = get_current_frame_d3d11, | |
| 346 | 356 | ||
| 347 | 357 | // Render pass | |
| 348 | - | begin_render_pass = begin_render_pass_d3d11, | |
| 349 | - | begin_default_pass = begin_default_pass_d3d11, | |
| 350 | - | end_render_pass = end_render_pass_d3d11, | |
| 351 | - | set_viewport = set_viewport_d3d11, | |
| 352 | - | set_scissor = set_scissor_d3d11, | |
| 353 | - | set_depth_bias = set_depth_bias_d3d11, | |
| 358 | + | begin_render_pass = begin_render_pass_d3d11, | |
| 359 | + | begin_default_pass = begin_default_pass_d3d11, | |
| 360 | + | end_render_pass = end_render_pass_d3d11, | |
| 361 | + | set_viewport = set_viewport_d3d11, | |
| 362 | + | set_scissor = set_scissor_d3d11, | |
| 363 | + | set_depth_bias = set_depth_bias_d3d11, | |
| 354 | 364 | ||
| 355 | 365 | // Pipeline | |
| 356 | - | create_graphics_pipeline = create_graphics_pipeline_d3d11, | |
| 357 | - | destroy_graphics_pipeline = destroy_graphics_pipeline_d3d11, | |
| 358 | - | bind_graphics_pipeline = bind_graphics_pipeline_d3d11, | |
| 359 | - | push_constants = push_constants_d3d11, | |
| 366 | + | create_graphics_pipeline = create_graphics_pipeline_d3d11, | |
| 367 | + | destroy_graphics_pipeline = destroy_graphics_pipeline_d3d11, | |
| 368 | + | bind_graphics_pipeline = bind_graphics_pipeline_d3d11, | |
| 369 | + | push_constants = push_constants_d3d11, | |
| 360 | 370 | ||
| 361 | 371 | // Buffers | |
| 362 | - | create_buffer = create_buffer_d3d11, | |
| 363 | - | create_buffer_staged = create_buffer_staged_d3d11, | |
| 364 | - | destroy_buffer = destroy_buffer_d3d11, | |
| 365 | - | map_buffer = map_buffer_d3d11, | |
| 366 | - | unmap_buffer = unmap_buffer_d3d11, | |
| 367 | - | get_buffer_mapped = get_buffer_mapped_d3d11, | |
| 368 | - | bind_vertex_buffer = bind_vertex_buffer_d3d11, | |
| 369 | - | bind_index_buffer = bind_index_buffer_d3d11, | |
| 372 | + | create_buffer = create_buffer_d3d11, | |
| 373 | + | create_buffer_staged = create_buffer_staged_d3d11, | |
| 374 | + | destroy_buffer = destroy_buffer_d3d11, | |
| 375 | + | map_buffer = map_buffer_d3d11, | |
| 376 | + | unmap_buffer = unmap_buffer_d3d11, | |
| 377 | + | get_buffer_mapped = get_buffer_mapped_d3d11, | |
| 378 | + | bind_vertex_buffer = bind_vertex_buffer_d3d11, | |
| 379 | + | bind_index_buffer = bind_index_buffer_d3d11, | |
| 370 | 380 | ||
| 371 | 381 | // Textures | |
| 372 | - | create_texture = create_texture_d3d11, | |
| 373 | - | destroy_texture = destroy_texture_d3d11, | |
| 382 | + | create_texture = create_texture_d3d11, | |
| 383 | + | destroy_texture = destroy_texture_d3d11, | |
| 374 | 384 | ||
| 375 | 385 | // Samplers | |
| 376 | - | create_sampler = create_sampler_d3d11, | |
| 377 | - | destroy_sampler = destroy_sampler_d3d11, | |
| 386 | + | create_sampler = create_sampler_d3d11, | |
| 387 | + | destroy_sampler = destroy_sampler_d3d11, | |
| 378 | 388 | ||
| 379 | 389 | // Images | |
| 380 | - | create_image = create_image_d3d11, | |
| 381 | - | create_image_view = create_image_view_d3d11, | |
| 382 | - | destroy_image = destroy_image_d3d11, | |
| 390 | + | create_image = create_image_d3d11, | |
| 391 | + | create_image_view = create_image_view_d3d11, | |
| 392 | + | destroy_image = destroy_image_d3d11, | |
| 383 | 393 | ||
| 384 | 394 | // Descriptors | |
| 385 | 395 | create_descriptor_set_layout = create_descriptor_set_layout_d3d11, | |
| … | 6 unchanged lines hidden | ||
| 392 | 402 | update_descriptor_buffer = update_descriptor_buffer_d3d11, | |
| 393 | 403 | ||
| 394 | 404 | // Render pass objects | |
| 395 | - | create_render_pass = create_render_pass_d3d11, | |
| 396 | - | destroy_render_pass = destroy_render_pass_d3d11, | |
| 397 | - | create_framebuffer = create_framebuffer_d3d11, | |
| 398 | - | destroy_framebuffer = destroy_framebuffer_d3d11, | |
| 405 | + | create_render_pass = create_render_pass_d3d11, | |
| 406 | + | destroy_render_pass = destroy_render_pass_d3d11, | |
| 407 | + | create_framebuffer = create_framebuffer_d3d11, | |
| 408 | + | destroy_framebuffer = destroy_framebuffer_d3d11, | |
| 399 | 409 | ||
| 400 | 410 | // Shaders | |
| 401 | - | create_shader_module = create_shader_module_d3d11, | |
| 402 | - | destroy_shader = destroy_shader_d3d11, | |
| 411 | + | create_shader_module = create_shader_module_d3d11, | |
| 412 | + | destroy_shader = destroy_shader_d3d11, | |
| 403 | 413 | ||
| 404 | 414 | // Draw | |
| 405 | - | draw_indexed = draw_indexed_d3d11, | |
| 415 | + | draw_indexed = draw_indexed_d3d11, | |
| 406 | 416 | ||
| 407 | 417 | // Compute | |
| 408 | - | create_compute_pipeline = create_compute_pipeline_d3d11, | |
| 409 | - | destroy_compute_pipeline = destroy_compute_pipeline_d3d11, | |
| 410 | - | bind_compute_pipeline = bind_compute_pipeline_d3d11, | |
| 411 | - | dispatch_compute = dispatch_compute_d3d11, | |
| 412 | - | compute_barrier = compute_barrier_d3d11, | |
| 418 | + | create_compute_pipeline = create_compute_pipeline_d3d11, | |
| 419 | + | destroy_compute_pipeline = destroy_compute_pipeline_d3d11, | |
| 420 | + | bind_compute_pipeline = bind_compute_pipeline_d3d11, | |
| 421 | + | dispatch_compute = dispatch_compute_d3d11, | |
| 422 | + | compute_barrier = compute_barrier_d3d11, | |
| 413 | 423 | ||
| 414 | 424 | // Sync | |
| 415 | - | get_default_render_pass = get_default_render_pass_d3d11, | |
| 416 | - | get_depth_format = get_depth_format_d3d11, | |
| 425 | + | get_default_render_pass = get_default_render_pass_d3d11, | |
| 426 | + | get_depth_format = get_depth_format_d3d11, | |
| 417 | 427 | } | |
| 418 | 428 | ||
| 419 | 429 | bk.backend_initialized = true | |
| … | 8 unchanged lines hidden | ||
| 428 | 438 | ||
| 429 | 439 | @(private) | |
| 430 | 440 | alloc_buffer_handle :: proc() -> (bk.Buffer_Handle, bool) { | |
| 431 | - | for i in 1..<u64(MAX_BUFFERS) { | |
| 441 | + | for i in 1 ..< u64(MAX_BUFFERS) { | |
| 432 | 442 | if !g_d3d.buffers[i].active { | |
| 433 | 443 | return bk.Buffer_Handle(i), true | |
| 434 | 444 | } | |
| … | 3 unchanged lines hidden | ||
| 438 | 448 | ||
| 439 | 449 | @(private) | |
| 440 | 450 | alloc_texture_handle :: proc() -> (bk.Texture_Handle, bool) { | |
| 441 | - | for i in 1..<u64(MAX_TEXTURES) { | |
| 451 | + | for i in 1 ..< u64(MAX_TEXTURES) { | |
| 442 | 452 | if !g_d3d.textures[i].active { | |
| 443 | 453 | return bk.Texture_Handle(i), true | |
| 444 | 454 | } | |
| … | 3 unchanged lines hidden | ||
| 448 | 458 | ||
| 449 | 459 | @(private) | |
| 450 | 460 | alloc_pipeline_handle :: proc() -> (bk.Pipeline_Handle, bool) { | |
| 451 | - | for i in 1..<u64(MAX_PIPELINES) { | |
| 461 | + | for i in 1 ..< u64(MAX_PIPELINES) { | |
| 452 | 462 | if !g_d3d.pipelines[i].active { | |
| 453 | 463 | return bk.Pipeline_Handle(i), true | |
| 454 | 464 | } | |
| … | 3 unchanged lines hidden | ||
| 458 | 468 | ||
| 459 | 469 | @(private) | |
| 460 | 470 | alloc_shader_handle :: proc() -> (bk.Shader_Handle, bool) { | |
| 461 | - | for i in 1..<u64(MAX_SHADERS) { | |
| 471 | + | for i in 1 ..< u64(MAX_SHADERS) { | |
| 462 | 472 | if !g_d3d.shaders[i].active { | |
| 463 | 473 | return bk.Shader_Handle(i), true | |
| 464 | 474 | } | |
| … | 3 unchanged lines hidden | ||
| 468 | 478 | ||
| 469 | 479 | @(private) | |
| 470 | 480 | alloc_descriptor_handle :: proc() -> (bk.Descriptor_Handle, bool) { | |
| 471 | - | for i in 1..<u64(MAX_DESCRIPTORS) { | |
| 481 | + | for i in 1 ..< u64(MAX_DESCRIPTORS) { | |
| 472 | 482 | if !g_d3d.descriptors[i].active { | |
| 473 | 483 | return bk.Descriptor_Handle(i), true | |
| 474 | 484 | } | |
| … | 3 unchanged lines hidden | ||
| 478 | 488 | ||
| 479 | 489 | @(private) | |
| 480 | 490 | alloc_render_pass_handle :: proc() -> (bk.Render_Pass_Handle, bool) { | |
| 481 | - | for i in 1..<u64(MAX_RENDER_PASSES) { | |
| 491 | + | for i in 1 ..< u64(MAX_RENDER_PASSES) { | |
| 482 | 492 | if !g_d3d.render_passes[i].active { | |
| 483 | 493 | return bk.Render_Pass_Handle(i), true | |
| 484 | 494 | } | |
| … | 3 unchanged lines hidden | ||
| 488 | 498 | ||
| 489 | 499 | @(private) | |
| 490 | 500 | alloc_framebuffer_handle :: proc() -> (bk.Framebuffer_Handle, bool) { | |
| 491 | - | for i in 1..<u64(MAX_FRAMEBUFFERS) { | |
| 501 | + | for i in 1 ..< u64(MAX_FRAMEBUFFERS) { | |
| 492 | 502 | if !g_d3d.framebuffers[i].active { | |
| 493 | 503 | return bk.Framebuffer_Handle(i), true | |
| 494 | 504 | } | |
| … | 3 unchanged lines hidden | ||
| 498 | 508 | ||
| 499 | 509 | @(private) | |
| 500 | 510 | alloc_sampler_handle :: proc() -> (bk.Sampler_Handle, bool) { | |
| 501 | - | for i in 1..<u64(MAX_SAMPLERS) { | |
| 511 | + | for i in 1 ..< u64(MAX_SAMPLERS) { | |
| 502 | 512 | if !g_d3d.samplers[i].active { | |
| 503 | 513 | return bk.Sampler_Handle(i), true | |
| 504 | 514 | } | |
| … | 16 unchanged lines hidden | ||
| 521 | 531 | // Create RTV with SRGB format for correct gamma. | |
| 522 | 532 | // The swapchain is R8G8B8A8_UNORM but we view it as SRGB so the GPU | |
| 523 | 533 | // applies linear→sRGB conversion on write, matching Vulkan's B8G8R8A8_SRGB. | |
| 524 | - | rtv_desc := d3d11.RENDER_TARGET_VIEW_DESC{ | |
| 534 | + | rtv_desc := d3d11.RENDER_TARGET_VIEW_DESC { | |
| 525 | 535 | Format = .R8G8B8A8_UNORM_SRGB, | |
| 526 | 536 | ViewDimension = .TEXTURE2D, | |
| 527 | 537 | } | |
| … | 7 unchanged lines hidden | ||
| 535 | 545 | ||
| 536 | 546 | @(private) | |
| 537 | 547 | create_depth_buffer :: proc(state: ^D3D11_State, width, height: u32) -> bool { | |
| 538 | - | depth_desc := d3d11.TEXTURE2D_DESC{ | |
| 539 | - | Width = width, | |
| 540 | - | Height = height, | |
| 541 | - | MipLevels = 1, | |
| 542 | - | ArraySize = 1, | |
| 543 | - | Format = state.depth_format, | |
| 548 | + | depth_desc := d3d11.TEXTURE2D_DESC { | |
| 549 | + | Width = width, | |
| 550 | + | Height = height, | |
| 551 | + | MipLevels = 1, | |
| 552 | + | ArraySize = 1, | |
| 553 | + | Format = state.depth_format, | |
| 544 | 554 | SampleDesc = {Count = 1, Quality = 0}, | |
| 545 | - | Usage = .DEFAULT, | |
| 546 | - | BindFlags = {.DEPTH_STENCIL}, | |
| 555 | + | Usage = .DEFAULT, | |
| 556 | + | BindFlags = {.DEPTH_STENCIL}, | |
| 547 | 557 | } | |
| 548 | 558 | ||
| 549 | 559 | result := state.device->CreateTexture2D(&depth_desc, nil, &state.depth_tex) | |
| … | 31 unchanged lines hidden | ||
| … | 9 unchanged lines hidden | ||
| 10 | 10 | @(private) | |
| 11 | 11 | to_dxgi_format :: proc(fmt: bk.Format) -> dxgi.FORMAT { | |
| 12 | 12 | switch fmt { | |
| 13 | - | case .Undefined: return .UNKNOWN | |
| 14 | - | case .R8G8B8A8_SRGB: return .R8G8B8A8_UNORM_SRGB | |
| 15 | - | case .R8G8B8A8_UNORM: return .R8G8B8A8_UNORM | |
| 16 | - | case .B8G8R8A8_SRGB: return .B8G8R8A8_UNORM_SRGB | |
| 17 | - | case .D32_SFLOAT: return .D32_FLOAT | |
| 18 | - | case .D32_SFLOAT_S8_UINT: return .D32_FLOAT_S8X24_UINT | |
| 19 | - | case .D24_UNORM_S8_UINT: return .D24_UNORM_S8_UINT | |
| 13 | + | case .Undefined: | |
| 14 | + | return .UNKNOWN | |
| 15 | + | case .R8G8B8A8_SRGB: | |
| 16 | + | return .R8G8B8A8_UNORM_SRGB | |
| 17 | + | case .R8G8B8A8_UNORM: | |
| 18 | + | return .R8G8B8A8_UNORM | |
| 19 | + | case .B8G8R8A8_SRGB: | |
| 20 | + | return .B8G8R8A8_UNORM_SRGB | |
| 21 | + | case .D32_SFLOAT: | |
| 22 | + | return .D32_FLOAT | |
| 23 | + | case .D32_SFLOAT_S8_UINT: | |
| 24 | + | return .D32_FLOAT_S8X24_UINT | |
| 25 | + | case .D24_UNORM_S8_UINT: | |
| 26 | + | return .D24_UNORM_S8_UINT | |
| 20 | 27 | } | |
| 21 | 28 | return .UNKNOWN | |
| 22 | 29 | } | |
| … | 1 unchanged lines hidden | ||
| 24 | 31 | @(private) | |
| 25 | 32 | from_dxgi_format :: proc(fmt: dxgi.FORMAT) -> bk.Format { | |
| 26 | 33 | #partial switch fmt { | |
| 27 | - | case .R8G8B8A8_UNORM_SRGB: return .R8G8B8A8_SRGB | |
| 28 | - | case .R8G8B8A8_UNORM: return .R8G8B8A8_UNORM | |
| 29 | - | case .B8G8R8A8_UNORM_SRGB: return .B8G8R8A8_SRGB | |
| 30 | - | case .D32_FLOAT: return .D32_SFLOAT | |
| 31 | - | case .D32_FLOAT_S8X24_UINT: return .D32_SFLOAT_S8_UINT | |
| 32 | - | case .D24_UNORM_S8_UINT: return .D24_UNORM_S8_UINT | |
| 33 | - | case: return .Undefined | |
| 34 | + | case .R8G8B8A8_UNORM_SRGB: | |
| 35 | + | return .R8G8B8A8_SRGB | |
| 36 | + | case .R8G8B8A8_UNORM: | |
| 37 | + | return .R8G8B8A8_UNORM | |
| 38 | + | case .B8G8R8A8_UNORM_SRGB: | |
| 39 | + | return .B8G8R8A8_SRGB | |
| 40 | + | case .D32_FLOAT: | |
| 41 | + | return .D32_SFLOAT | |
| 42 | + | case .D32_FLOAT_S8X24_UINT: | |
| 43 | + | return .D32_SFLOAT_S8_UINT | |
| 44 | + | case .D24_UNORM_S8_UINT: | |
| 45 | + | return .D24_UNORM_S8_UINT | |
| 46 | + | case: | |
| 47 | + | return .Undefined | |
| 34 | 48 | } | |
| 35 | 49 | } | |
| 36 | 50 | ||
| … | 2 unchanged lines hidden | ||
| 39 | 53 | @(private) | |
| 40 | 54 | to_d3d11_topology :: proc(t: bk.Topology) -> d3d11.PRIMITIVE_TOPOLOGY { | |
| 41 | 55 | switch t { | |
| 42 | - | case .Triangle_List: return .TRIANGLELIST | |
| 43 | - | case .Triangle_Strip: return .TRIANGLESTRIP | |
| 44 | - | case .Line_List: return .LINELIST | |
| 45 | - | case .Point_List: return .POINTLIST | |
| 56 | + | case .Triangle_List: | |
| 57 | + | return .TRIANGLELIST | |
| 58 | + | case .Triangle_Strip: | |
| 59 | + | return .TRIANGLESTRIP | |
| 60 | + | case .Line_List: | |
| 61 | + | return .LINELIST | |
| 62 | + | case .Point_List: | |
| 63 | + | return .POINTLIST | |
| 46 | 64 | } | |
| 47 | 65 | return .TRIANGLELIST | |
| 48 | 66 | } | |
| … | 3 unchanged lines hidden | ||
| 52 | 70 | @(private) | |
| 53 | 71 | to_d3d11_cull_mode :: proc(c: bk.Cull_Mode) -> d3d11.CULL_MODE { | |
| 54 | 72 | switch c { | |
| 55 | - | case .None: return .NONE | |
| 56 | - | case .Front: return .FRONT | |
| 57 | - | case .Back: return .BACK | |
| 58 | - | case .Front_And_Back: return .BACK // D3D11 has no front+back; approximate with back | |
| 73 | + | case .None: | |
| 74 | + | return .NONE | |
| 75 | + | case .Front: | |
| 76 | + | return .FRONT | |
| 77 | + | case .Back: | |
| 78 | + | return .BACK | |
| 79 | + | case .Front_And_Back: | |
| 80 | + | return .BACK // D3D11 has no front+back; approximate with back | |
| 59 | 81 | } | |
| 60 | 82 | return .NONE | |
| 61 | 83 | } | |
| … | 28 unchanged lines hidden | ||
| 90 | 112 | @(private) | |
| 91 | 113 | to_d3d11_address_mode :: proc(m: bk.Address_Mode) -> d3d11.TEXTURE_ADDRESS_MODE { | |
| 92 | 114 | switch m { | |
| 93 | - | case .Repeat: return .WRAP | |
| 94 | - | case .Clamp_To_Edge: return .CLAMP | |
| 95 | - | case .Clamp_To_Border: return .BORDER | |
| 115 | + | case .Repeat: | |
| 116 | + | return .WRAP | |
| 117 | + | case .Clamp_To_Edge: | |
| 118 | + | return .CLAMP | |
| 119 | + | case .Clamp_To_Border: | |
| 120 | + | return .BORDER | |
| 96 | 121 | } | |
| 97 | 122 | return .WRAP | |
| 98 | 123 | } | |
| … | 3 unchanged lines hidden | ||
| 102 | 127 | @(private) | |
| 103 | 128 | to_d3d11_compare_func :: proc(op: bk.Compare_Op) -> d3d11.COMPARISON_FUNC { | |
| 104 | 129 | switch op { | |
| 105 | - | case .Never: return .NEVER | |
| 106 | - | case .Less: return .LESS | |
| 107 | - | case .Less_Or_Equal: return .LESS_EQUAL | |
| 108 | - | case .Always: return .ALWAYS | |
| 130 | + | case .Never: | |
| 131 | + | return .NEVER | |
| 132 | + | case .Less: | |
| 133 | + | return .LESS | |
| 134 | + | case .Less_Or_Equal: | |
| 135 | + | return .LESS_EQUAL | |
| 136 | + | case .Always: | |
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.
Inline diff hidden to keep this page fast.