Harbor

Changelog ce112d7235a9

add sampled proof paths

@sky · 1 month ago · parent 2926f470fec8
0 added 3 modified 0 deleted
examples/parity_backend_features/main.odin +85 -4 modified
65 unchanged lines hidden
66 66 end
67 67 `
68 68
69 + BLUE_FRAGMENT_SHADER :: `
70 + fragment main
71 + out color: vec4
72 + do
73 + color = vec4(64.0 / 255.0, 64.0 / 255.0, 240.0 / 255.0, 1.0)
74 + end
75 + `
76 +
77 + SAMPLE_FRAGMENT_SHADER :: `
78 + group frame = 0
79 + @binding(0) texture offscreen_color: sampler2D
80 + end
81 +
82 + fragment main
83 + in uv: vec2
84 + out color: vec4
85 + do
86 + color = sample(offscreen_color, uv)
87 + end
88 + `
89 +
69 90 quad_vertices :: proc(x0, y0, x1, y1: f32) -> [6]resource.Mesh_Vertex_PNU {
70 91 n := [3]f32{0, 0, 1}
71 92 return {
45 unchanged lines hidden
117 138 indirect_geometry: ir.Resource_Handle,
118 139 instance_data: ir.Resource_Handle,
119 140 indirect_args: ir.Resource_Handle,
141 + offscreen_geometry: ir.Resource_Handle,
142 + sample_geometry: ir.Resource_Handle,
120 143 ) {
121 144 frame = ir.init_frame_ir()
122 145 color = ir.add_texture(&frame, "proof-color", WIDTH, HEIGHT, .R8G8B8A8_UNORM, {.Color_Attachment, .Sampled}, .Transient)
123 146 secondary := ir.add_texture(&frame, "mrt-secondary", WIDTH, HEIGHT, .R8G8B8A8_UNORM, {.Color_Attachment, .Sampled}, .Transient)
147 + offscreen := ir.add_texture(&frame, "offscreen-sampled-proof", WIDTH, HEIGHT, .R8G8B8A8_UNORM, {.Color_Attachment, .Sampled}, .Transient)
148 + sampler := ir.add_sampler(&frame, "nearest-sampler", {
149 + mag_filter = .Nearest,
150 + min_filter = .Nearest,
151 + address_mode_u = .Clamp_To_Edge,
152 + address_mode_v = .Clamp_To_Edge,
153 + mipmap_mode = .Nearest,
154 + }, .Transient)
124 155 mrt_geometry = ir.add_buffer(&frame, "mrt-vertices", u64(6 * size_of(resource.Mesh_Vertex_PNU)), {.Vertex}, {.Host_Visible, .Host_Coherent}, .Transient)
125 156 indirect_geometry = ir.add_buffer(&frame, "indirect-vertices", u64(6 * size_of(resource.Mesh_Vertex_PNU)), {.Vertex}, {.Host_Visible, .Host_Coherent}, .Transient)
126 157 instance_data = ir.add_buffer(&frame, "instances", u64(size_of(Instance_PNUC)), {.Vertex}, {.Host_Visible, .Host_Coherent}, .Transient)
127 158 indirect_args = ir.add_buffer(&frame, "indirect-args", u64(size_of(bk.Indirect_Draw_Args)), {.Indirect_Argument}, {.Host_Visible, .Host_Coherent}, .Transient)
159 + offscreen_geometry = ir.add_buffer(&frame, "offscreen-vertices", u64(6 * size_of(resource.Mesh_Vertex_PNU)), {.Vertex}, {.Host_Visible, .Host_Coherent}, .Transient)
160 + sample_geometry = ir.add_buffer(&frame, "sample-vertices", u64(6 * size_of(resource.Mesh_Vertex_PNU)), {.Vertex}, {.Host_Visible, .Host_Coherent}, .Transient)
128 161
162 + vs := ir.add_shader_source(&frame, "parity_backend_features.vert", .Vertex, VERTEX_SHADER)
163 + blue_fs := ir.add_shader_source(&frame, "parity_backend_features_blue.frag", .Fragment, BLUE_FRAGMENT_SHADER)
164 + offscreen_pass_desc := ir.Pass_Desc{kind = .Render, name = "write-offscreen-sampled"}
165 + _ = ir.pass_add_color_target(&offscreen_pass_desc, ir.make_color_target(offscreen, .R8G8B8A8_UNORM, .Clear, .Store, {16.0 / 255.0, 16.0 / 255.0, 24.0 / 255.0, 1}))
166 + ir.pass_set_viewport(&offscreen_pass_desc, {x = 0, y = 0, width = f32(WIDTH), height = f32(HEIGHT), min_depth = 0, max_depth = 1})
167 + ir.pass_set_scissor(&offscreen_pass_desc, {x = 0, y = 0, width = WIDTH, height = HEIGHT})
168 + offscreen_pass := ir.add_pass(&frame, offscreen_pass_desc)
169 + offscreen_target := ir.add_target(&frame, {kind = .Offscreen, name = "offscreen-sampled-target", width = WIDTH, height = HEIGHT, pass = offscreen_pass, color_format = .R8G8B8A8_UNORM, color_resource = offscreen})
170 + offscreen_state := ir.default_graphics_pipeline_state()
171 + offscreen_state.vertex_shader = vs
172 + offscreen_state.fragment_shader = blue_fs
173 + offscreen_pipeline := ir.add_graphics_pipeline(&frame, "offscreen-blue", offscreen_state)
174 + _ = ir.add_draw_packet(&frame, offscreen_pass, offscreen_pipeline, .Vertex_Stream, {
175 + target = offscreen_target,
176 + geometry = {kind = .Vertex_Stream, resource = offscreen_geometry, vertex_count = 6},
177 + order = .Strict,
178 + })
179 +
129 180 pass_desc := ir.Pass_Desc{kind = .Render, name = "backend-feature-proof"}
130 181 _ = ir.pass_add_color_target(&pass_desc, ir.make_color_target(color, .R8G8B8A8_UNORM, .Clear, .Store, {16.0 / 255.0, 16.0 / 255.0, 24.0 / 255.0, 1}))
131 182 _ = ir.pass_add_color_target(&pass_desc, ir.make_color_target(secondary, .R8G8B8A8_UNORM, .Clear, .Store, {0, 0, 0, 1}))
2 unchanged lines hidden
134 185 pass := ir.add_pass(&frame, pass_desc)
135 186 target := ir.add_target(&frame, {kind = .Offscreen, name = "proof-target", width = WIDTH, height = HEIGHT, pass = pass, color_format = .R8G8B8A8_UNORM, color_resource = color})
136 187
137 - vs := ir.add_shader_source(&frame, "parity_backend_features.vert", .Vertex, VERTEX_SHADER)
138 188 red_fs := ir.add_shader_source(&frame, "parity_backend_features_red.frag", .Fragment, RED_FRAGMENT_SHADER)
139 189 red_state := ir.default_graphics_pipeline_state()
140 190 red_state.vertex_shader = vs
24 unchanged lines hidden
165 215 },
166 216 order = .Strict,
167 217 })
218 + layout_desc := ir.make_descriptor_set_layout("offscreen-sampled-layout")
219 + _ = ir.descriptor_layout_add_binding(&layout_desc, 0, .Combined_Image_Sampler, 1, {.Fragment})
220 + layout := ir.add_descriptor_set_layout(&frame, layout_desc)
221 + set_desc := ir.make_descriptor_set("offscreen-sampled-set", layout)
222 + _ = ir.descriptor_set_bind_texture_sampler(&set_desc, 0, offscreen, sampler)
223 + set := ir.add_descriptor_set(&frame, set_desc)
224 + sample_fs := ir.add_shader_source(&frame, "parity_backend_features_sample.frag", .Fragment, SAMPLE_FRAGMENT_SHADER)
225 + sample_state := ir.default_graphics_pipeline_state()
226 + sample_state.vertex_shader = vs
227 + sample_state.fragment_shader = sample_fs
228 + sample_pipeline_desc := ir.Pipeline_Desc {
229 + kind = .Graphics,
230 + name = "sample-offscreen",
231 + graphics = sample_state,
232 + }
233 + _ = ir.pipeline_add_descriptor_layout(&sample_pipeline_desc, layout)
234 + sample_pipeline := ir.add_pipeline(&frame, sample_pipeline_desc)
235 + material := ir.add_material(&frame, {name = "sample-offscreen", pipeline = sample_pipeline, descriptor_set = set})
236 + _ = ir.add_draw_packet(&frame, pass, sample_pipeline, .Vertex_Stream, {
237 + target = target,
238 + material = material,
239 + geometry = {kind = .Vertex_Stream, resource = sample_geometry, vertex_count = 6},
240 + order = .Strict,
241 + sort_key = 2,
242 + })
168 243 return
169 244 }
170 245
9 unchanged lines hidden
180 255 fail("parity_backend_features: backend readback unsupported")
181 256 }
182 257
183 - frame, color, mrt_geometry, indirect_geometry, instance_data, indirect_args := make_frame()
258 + frame, color, mrt_geometry, indirect_geometry, instance_data, indirect_args, offscreen_geometry, sample_geometry := make_frame()
184 259 defer ir.destroy_frame_ir(&frame)
185 260 exec := compiler.init_execution_state(backend)
186 261 defer compiler.destroy_execution_state(&exec)
4 unchanged lines hidden
191 266 indirect_buffer, indirect_ok := compiler.prepared_buffer(&exec, indirect_geometry)
192 267 instance_buffer, instance_ok := compiler.prepared_buffer(&exec, instance_data)
193 268 args_buffer, args_ok := compiler.prepared_buffer(&exec, indirect_args)
194 - if !mrt_ok || !indirect_ok || !instance_ok || !args_ok {
269 + offscreen_buffer, offscreen_ok := compiler.prepared_buffer(&exec, offscreen_geometry)
270 + sample_buffer, sample_ok := compiler.prepared_buffer(&exec, sample_geometry)
271 + if !mrt_ok || !indirect_ok || !instance_ok || !args_ok || !offscreen_ok || !sample_ok {
195 272 fail("parity_backend_features: failed to resolve prepared buffers")
196 273 }
197 274 mrt_vertices := quad_vertices(-0.85, -0.5, -0.35, 0.5)
198 275 indirect_vertices := quad_vertices(-0.25, -0.5, 0.25, 0.5)
276 + offscreen_vertices := quad_vertices(-1, -1, 1, 1)
277 + sample_vertices := quad_vertices(0.35, -0.5, 0.85, 0.5)
199 278 instance := Instance_PNUC{normal = {0, 0, 1}, color = {64.0 / 255.0, 240.0 / 255.0, 64.0 / 255.0, 1}}
200 279 args := bk.Indirect_Draw_Args{vertex_count = 6, instance_count = 1}
201 280 if !write_bytes(backend, mrt_buffer, raw_data(mrt_vertices[:]), len(mrt_vertices) * size_of(resource.Mesh_Vertex_PNU)) ||
202 281 !write_bytes(backend, indirect_buffer, raw_data(indirect_vertices[:]), len(indirect_vertices) * size_of(resource.Mesh_Vertex_PNU)) ||
203 282 !write_bytes(backend, instance_buffer, &instance, size_of(Instance_PNUC)) ||
204 - !write_bytes(backend, args_buffer, &args, size_of(bk.Indirect_Draw_Args)) {
283 + !write_bytes(backend, args_buffer, &args, size_of(bk.Indirect_Draw_Args)) ||
284 + !write_bytes(backend, offscreen_buffer, raw_data(offscreen_vertices[:]), len(offscreen_vertices) * size_of(resource.Mesh_Vertex_PNU)) ||
285 + !write_bytes(backend, sample_buffer, raw_data(sample_vertices[:]), len(sample_vertices) * size_of(resource.Mesh_Vertex_PNU)) {
205 286 fail("parity_backend_features: failed to upload proof buffers")
206 287 }
207 288 if !compiler.execute_prepared_planned_frame(&exec, &frame, {0, 0, 0, 1}) {
20 unchanged lines hidden
examples/parity_resource_sync/main.odin +141 -3 modified
1 1 package main
2 2
3 3 import "core:fmt"
4 + import "core:mem"
4 5 import "core:os"
5 6
6 7 import app "../../app"
8 + import bk "../../backend"
7 9 import compiler "../../compiler"
8 10 import gpu "../.."
9 11 import ir "../../render_ir"
52 unchanged lines hidden
62 64 end
63 65 `
64 66
67 + OFFSCREEN_FRAGMENT_SHADER :: `
68 + fragment main
69 + out color: vec4
70 + do
71 + color = vec4(64.0 / 255.0, 128.0 / 255.0, 240.0 / 255.0, 1.0)
72 + end
73 + `
74 +
75 + SAMPLE_FRAGMENT_SHADER :: `
76 + group frame = 0
77 + @binding(0) texture offscreen_color: sampler2D
78 + end
79 +
80 + fragment main
81 + in uv: vec2
82 + out color: vec4
83 + do
84 + color = sample(offscreen_color, uv)
85 + end
86 + `
87 +
88 + quad_vertices :: proc(x0, y0, x1, y1: f32) -> [6]resource.Mesh_Vertex_PNU {
89 + n := [3]f32{0, 0, 1}
90 + return {
91 + {position = {x0, y0, 0}, normal = n, tex_coord = {0, 1}},
92 + {position = {x1, y0, 0}, normal = n, tex_coord = {1, 1}},
93 + {position = {x1, y1, 0}, normal = n, tex_coord = {1, 0}},
94 + {position = {x0, y0, 0}, normal = n, tex_coord = {0, 1}},
95 + {position = {x1, y1, 0}, normal = n, tex_coord = {1, 0}},
96 + {position = {x0, y1, 0}, normal = n, tex_coord = {0, 0}},
97 + }
98 + }
99 +
100 + write_bytes :: proc(backend: ^bk.Backend, buffer: bk.Buffer_Handle, data: rawptr, size: int) -> bool {
101 + mapped := backend.map_buffer(buffer)
102 + if mapped == nil {
103 + return false
104 + }
105 + mem.copy(mapped, data, size)
106 + backend.unmap_buffer(buffer)
107 + return true
108 + }
109 +
65 110 write_ppm_rgba8 :: proc(path: string, rgba: []u8, width, height: u32) -> bool {
66 111 if len(path) == 0 {
67 112 return false
16 unchanged lines hidden
84 129 os.exit(1)
85 130 }
86 131
87 - make_frame :: proc() -> (frame: ir.Frame_IR, color: ir.Resource_Handle) {
132 + make_frame :: proc() -> (frame: ir.Frame_IR, color: ir.Resource_Handle, sample_geometry: ir.Resource_Handle) {
88 133 frame = ir.init_frame_ir()
89 134 color = ir.add_texture(&frame, "proof-color", WIDTH, HEIGHT, .R8G8B8A8_UNORM, {.Color_Attachment, .Sampled}, .Transient)
135 + offscreen := ir.add_texture(&frame, "offscreen-sampled-proof", WIDTH, HEIGHT, .R8G8B8A8_UNORM, {.Color_Attachment, .Sampled}, .Transient)
136 + sampler := ir.add_sampler(&frame, "nearest-sampler", {
137 + mag_filter = .Nearest,
138 + min_filter = .Nearest,
139 + address_mode_u = .Clamp_To_Edge,
140 + address_mode_v = .Clamp_To_Edge,
141 + mipmap_mode = .Nearest,
142 + }, .Transient)
90 143 vertices := ir.add_buffer(
91 144 &frame,
92 145 "compute-written-vertices",
2 unchanged lines hidden
95 148 {.Device_Local},
96 149 .Transient,
97 150 )
151 + sample_geometry = ir.add_buffer(
152 + &frame,
153 + "sample-quad",
154 + u64(6 * size_of(resource.Mesh_Vertex_PNU)),
155 + {.Vertex},
156 + {.Host_Visible, .Host_Coherent},
157 + .Transient,
158 + )
98 159 compute_shader := ir.add_shader_source(&frame, "parity_resource_sync.comp", .Compute, COMPUTE_SHADER)
99 160 compute_pipeline := ir.add_compute_pipeline(
100 161 &frame,
9 unchanged lines hidden
110 171 }}
111 172 _ = ir.add_compute_dispatch(&frame, compute_pass, compute_pipeline, 0, {1, 1, 1}, storage[:])
112 173
174 + offscreen_pass_desc := ir.Pass_Desc{kind = .Render, name = "write-offscreen-sampled"}
175 + _ = ir.pass_add_color_target(
176 + &offscreen_pass_desc,
177 + ir.make_color_target(offscreen, .R8G8B8A8_UNORM, .Clear, .Store, {16.0 / 255.0, 16.0 / 255.0, 24.0 / 255.0, 1}),
178 + )
179 + ir.pass_set_viewport(&offscreen_pass_desc, {x = 0, y = 0, width = f32(WIDTH), height = f32(HEIGHT), min_depth = 0, max_depth = 1})
180 + ir.pass_set_scissor(&offscreen_pass_desc, {x = 0, y = 0, width = WIDTH, height = HEIGHT})
181 + offscreen_pass := ir.add_pass(&frame, offscreen_pass_desc)
182 + offscreen_target := ir.add_target(
183 + &frame,
184 + {
185 + kind = .Offscreen,
186 + name = "offscreen-sampled-target",
187 + width = WIDTH,
188 + height = HEIGHT,
189 + pass = offscreen_pass,
190 + color_format = .R8G8B8A8_UNORM,
191 + color_resource = offscreen,
192 + clear_color = {16.0 / 255.0, 16.0 / 255.0, 24.0 / 255.0, 1},
193 + },
194 + )
195 + vs := ir.add_shader_source(&frame, "parity_resource_sync.vert", .Vertex, VERTEX_SHADER)
196 + offscreen_fs := ir.add_shader_source(&frame, "parity_resource_sync_offscreen.frag", .Fragment, OFFSCREEN_FRAGMENT_SHADER)
197 + offscreen_state := ir.default_graphics_pipeline_state()
198 + offscreen_state.vertex_shader = vs
199 + offscreen_state.fragment_shader = offscreen_fs
200 + offscreen_pipeline := ir.add_graphics_pipeline(&frame, "offscreen-blue", offscreen_state)
201 + _ = ir.add_draw_packet(
202 + &frame,
203 + offscreen_pass,
204 + offscreen_pipeline,
205 + .Vertex_Stream,
206 + {
207 + target = offscreen_target,
208 + geometry = {kind = .Vertex_Stream, resource = vertices, vertex_count = 6},
209 + order = .Strict,
210 + },
211 + )
212 +
113 213 pass_desc := ir.Pass_Desc{kind = .Render, name = "draw-compute-output"}
114 214 _ = ir.pass_add_color_target(
115 215 &pass_desc,
15 unchanged lines hidden
131 231 clear_color = {16.0 / 255.0, 16.0 / 255.0, 24.0 / 255.0, 1},
132 232 },
133 233 )
134 - vs := ir.add_shader_source(&frame, "parity_resource_sync.vert", .Vertex, VERTEX_SHADER)
135 234 fs := ir.add_shader_source(&frame, "parity_resource_sync.frag", .Fragment, FRAGMENT_SHADER)
136 235 state := ir.default_graphics_pipeline_state()
137 236 state.vertex_shader = vs
10 unchanged lines hidden
148 247 order = .Strict,
149 248 },
150 249 )
250 + layout_desc := ir.make_descriptor_set_layout("offscreen-sampled-layout")
251 + _ = ir.descriptor_layout_add_binding(&layout_desc, 0, .Combined_Image_Sampler, 1, {.Fragment})
252 + layout := ir.add_descriptor_set_layout(&frame, layout_desc)
253 + set_desc := ir.make_descriptor_set("offscreen-sampled-set", layout)
254 + _ = ir.descriptor_set_bind_texture_sampler(&set_desc, 0, offscreen, sampler)
255 + set := ir.add_descriptor_set(&frame, set_desc)
256 + sample_fs := ir.add_shader_source(&frame, "parity_resource_sync_sample.frag", .Fragment, SAMPLE_FRAGMENT_SHADER)
257 + sample_state := ir.default_graphics_pipeline_state()
258 + sample_state.vertex_shader = vs
259 + sample_state.fragment_shader = sample_fs
260 + sample_pipeline_desc := ir.Pipeline_Desc {
261 + kind = .Graphics,
262 + name = "sample-offscreen",
263 + graphics = sample_state,
264 + }
265 + _ = ir.pipeline_add_descriptor_layout(&sample_pipeline_desc, layout)
266 + sample_pipeline := ir.add_pipeline(&frame, sample_pipeline_desc)
267 + material := ir.add_material(&frame, {name = "sample-offscreen", pipeline = sample_pipeline, descriptor_set = set})
268 + _ = ir.add_draw_packet(
269 + &frame,
270 + pass,
271 + sample_pipeline,
272 + .Vertex_Stream,
273 + {
274 + target = target,
275 + material = material,
276 + geometry = {kind = .Vertex_Stream, resource = sample_geometry, vertex_count = 6},
277 + order = .Strict,
278 + sort_key = 1,
279 + },
280 + )
151 281 return
152 282 }
153 283
9 unchanged lines hidden
163 293 fail("parity_resource_sync: backend readback unsupported")
164 294 }
165 295
166 - frame, color := make_frame()
296 + frame, color, sample_geometry := make_frame()
167 297 defer ir.destroy_frame_ir(&frame)
168 298 exec := compiler.init_execution_state(backend)
169 299 defer compiler.destroy_execution_state(&exec)
170 300 if !compiler.prepare_planned_frame(&exec, &frame) {
171 301 fail("parity_resource_sync: failed to prepare planned frame")
172 302 }
303 + sample_buffer, sample_ok := compiler.prepared_buffer(&exec, sample_geometry)
304 + if !sample_ok {
305 + fail("parity_resource_sync: failed to resolve sample geometry")
306 + }
307 + sample_vertices := quad_vertices(0.0, -1.0, 1.0, 1.0)
308 + if !write_bytes(backend, sample_buffer, raw_data(sample_vertices[:]), len(sample_vertices) * size_of(resource.Mesh_Vertex_PNU)) {
309 + fail("parity_resource_sync: failed to upload sample geometry")
310 + }
173 311 if !compiler.execute_prepared_planned_frame(&exec, &frame, {0, 0, 0, 1}) {
174 312 fail("parity_resource_sync: failed to execute planned frame")
175 313 }
18 unchanged lines hidden
tests/compiler_executor_test.odin modified

Diff hidden because this file has more than 800 lines.