nx_d3d11_min.nx source
↩ module page · 55 lines · 2748 B
1// nx_d3d11_min.nx -- D0 of the D3D-game ladder: the END-TO-END SPINE. Models the D3D11 device+swapchain object model
2// and the exact startup call sequence a game makes on frame 0 -- D3D11CreateDeviceAndSwapChain -> GetBuffer(backbuffer)
3// -> ClearRenderTargetView -> [draw region] -> Present -- and drives it through OUR real backend (nx_swgpu framebuffer)
4// and OUR real present (nx_swapchain -> PPM). Proves API-surface -> backend -> present as ONE working path.
5// HONEST SCOPE: this is the ARCHITECTURE spine (the object model + call sequence backed by the real backend/present),
6// NOT yet a COM-vtable d3d11.dll a Windows game loads unchanged -- that (real IUnknown/GUID vtables + the dll shim) is a
7// later rung. Correctness before perf: the software backend is correct-but-slow. license_tier: ORIGINAL
8import "nx_syscalls.nx"
9import "nx_swgpu.nx"
10import "nx_swapchain.nx"
11
12// device+swapchain context: [0]=swgpu backbuffer base, [1]=width, [2]=height
13func d3d_create_device_and_swapchain(reqw: i64, reqh: i64) -> *i64 {
14 let ctx: *i64 = sys_mmap(64) as *i64
15 let bb: i64 = (sys_mmap(swgpu_bytes())) as i64
16 sg_reset(bb)
17 ctx[0] = bb
18 ctx[1] = W // backbuffer = the backend's native 512x384; arbitrary-resolution swapchains = a later rung
19 ctx[2] = H
20 return ctx
21}
22func d3d_backbuffer(ctx: *i64) -> *i64 { return sg_fb(ctx[0]) } // GetBuffer(0) + CreateRenderTargetView
23func d3d_width(ctx: *i64) -> i64 { return ctx[1] }
24func d3d_height(ctx: *i64) -> i64 { return ctx[2] }
25
26func d3d_pack(r: i64, g: i64, b: i64) -> i64 { return (r & 255) | ((g & 255) << 8) | ((b & 255) << 16) }
27
28// ClearRenderTargetView: fill the whole backbuffer with a color -- the per-frame clear every game issues.
29func d3d_clear_rtv(ctx: *i64, r: i64, g: i64, b: i64) -> i64 {
30 let fb: *i64 = d3d_backbuffer(ctx)
31 let packed: i64 = d3d_pack(r, g, b)
32 let n: i64 = ctx[1] * ctx[2]
33 var i: i64 = 0
34 while i < n { fb[i] = packed; i = i + 1 }
35 return 0
36}
37
38// a scissored fill over [x0,x1)x[y0,y1) -- models a viewport/scissor draw region (RSSetScissorRects + a colored draw).
39func d3d_fill_rect(ctx: *i64, x0: i64, y0: i64, x1: i64, y1: i64, r: i64, g: i64, b: i64) -> i64 {
40 let fb: *i64 = d3d_backbuffer(ctx)
41 let w: i64 = ctx[1]
42 let packed: i64 = d3d_pack(r, g, b)
43 var y: i64 = y0
44 while y < y1 {
45 var x: i64 = x0
46 while x < x1 { fb[y*w + x] = packed; x = x + 1 }
47 y = y + 1
48 }
49 return 0
50}
51
52// Present: hand the backbuffer to the swapchain -> a real PPM frame in `out`. returns bytes (or NX_SWAP_ERR_*).
53func d3d_present(ctx: *i64, out: *u8, out_cap: i64) -> i64 {
54 return nx_swap_present(d3d_backbuffer(ctx), ctx[1], ctx[2], NX_SWAP_DEST_PPM_BUFFER, out, out_cap)
55}