rafx_plugins/features/tile_layer/jobs/
write.rs1use rafx::render_feature_write_job_prelude::*;
2
3use super::*;
4use rafx::api::{
5 RafxIndexBufferBinding, RafxIndexType, RafxPrimitiveTopology, RafxVertexAttributeRate,
6 RafxVertexBufferBinding,
7};
8use rafx::framework::{MaterialPassResource, ResourceArc, VertexDataLayout, VertexDataSetLayout};
9use rafx::render_features::{BeginSubmitNodeBatchArgs, RenderSubmitNodeArgs};
10use std::marker::PhantomData;
11
12#[derive(Clone, Debug, Copy, Default)]
14#[repr(C)]
15pub struct TileLayerVertex {
16 pub position: [f32; 3],
17 pub uv: [f32; 2],
18}
19
20lazy_static::lazy_static! {
21 pub static ref TILE_LAYER_VERTEX_LAYOUT : VertexDataSetLayout = {
22 use rafx::api::RafxFormat;
23 VertexDataLayout::build_vertex_layout(&TileLayerVertex::default(), RafxVertexAttributeRate::Vertex, |builder, vertex| {
24 builder.add_member(&vertex.position, "POSITION", RafxFormat::R32G32B32_SFLOAT);
25 builder.add_member(&vertex.uv, "TEXCOORD", RafxFormat::R32G32_SFLOAT);
26 }).into_set(RafxPrimitiveTopology::TriangleList)
27 };
28}
29
30pub struct TileLayerWriteJob<'write> {
31 tile_layer_material_pass: Option<ResourceArc<MaterialPassResource>>,
32 render_objects: TileLayerRenderObjectSet,
33 _frame_packet: Box<TileLayerFramePacket>,
34 submit_packet: Box<TileLayerSubmitPacket>,
35 phantom: PhantomData<&'write ()>,
36}
37
38impl<'write> TileLayerWriteJob<'write> {
39 pub fn new(
40 _write_context: &RenderJobWriteContext<'write>,
41 frame_packet: Box<TileLayerFramePacket>,
42 submit_packet: Box<TileLayerSubmitPacket>,
43 render_objects: TileLayerRenderObjectSet,
44 ) -> Arc<dyn RenderFeatureWriteJob<'write> + 'write> {
45 Arc::new(Self {
46 tile_layer_material_pass: {
47 frame_packet
48 .per_frame_data()
49 .get()
50 .tile_layer_material_pass
51 .clone()
52 },
53 render_objects,
54 _frame_packet: frame_packet,
55 submit_packet,
56 phantom: Default::default(),
57 })
58 }
59}
60
61impl<'write> RenderFeatureWriteJob<'write> for TileLayerWriteJob<'write> {
62 fn begin_submit_node_batch(
63 &self,
64 write_context: &mut RenderJobCommandBufferContext,
65 args: BeginSubmitNodeBatchArgs,
66 ) -> RafxResult<()> {
67 if !args.feature_changed {
68 return Ok(());
69 }
70
71 profiling::scope!(super::render_feature_debug_constants().begin_submit_node_batch);
72
73 let command_buffer = &write_context.command_buffer;
74
75 let pipeline = write_context
76 .resource_context()
77 .graphics_pipeline_cache()
78 .get_or_create_graphics_pipeline(
79 Some(args.render_phase_index),
80 self.tile_layer_material_pass.as_ref().unwrap(),
81 &write_context.render_target_meta,
82 &TILE_LAYER_VERTEX_LAYOUT,
83 )
84 .unwrap();
85
86 command_buffer.cmd_bind_pipeline(&pipeline.get_raw().pipeline)?;
87
88 Ok(())
89 }
90
91 fn render_submit_node(
92 &self,
93 write_context: &mut RenderJobCommandBufferContext,
94 args: RenderSubmitNodeArgs,
95 ) -> RafxResult<()> {
96 profiling::scope!(super::render_feature_debug_constants().render_submit_node);
97
98 let command_buffer = &write_context.command_buffer;
99
100 let view_submit_packet = self.submit_packet.view_submit_packet(args.view_frame_index);
101
102 let per_view_submit_data = view_submit_packet.per_view_submit_data().get();
103
104 per_view_submit_data
106 .descriptor_set_arc
107 .as_ref()
108 .unwrap()
109 .bind(command_buffer)?;
110
111 let submit_node = view_submit_packet
112 .get_submit_node_data_from_render_phase(args.render_phase_index, args.submit_node_id);
113
114 let render_objects = self.render_objects.read();
115 let tile_layer_render_object = render_objects.get_id(&submit_node.render_object_id);
116 tile_layer_render_object
117 .per_layer_descriptor_set
118 .bind(command_buffer)?;
119
120 for draw_call in &tile_layer_render_object.draw_call_data {
121 command_buffer.cmd_bind_vertex_buffers(
122 0,
123 &[RafxVertexBufferBinding {
124 buffer: &tile_layer_render_object.vertex_buffer.get_raw().buffer,
125 byte_offset: draw_call.vertex_data_offset_in_bytes as u64,
126 }],
127 )?;
128
129 command_buffer.cmd_bind_index_buffer(&RafxIndexBufferBinding {
130 buffer: &tile_layer_render_object.index_buffer.get_raw().buffer,
131 byte_offset: draw_call.index_data_offset_in_bytes as u64,
132 index_type: RafxIndexType::Uint16,
133 })?;
134
135 command_buffer.cmd_draw_indexed(draw_call.index_count, 0, 0)?;
136 }
137
138 Ok(())
139 }
140
141 fn feature_debug_constants(&self) -> &'static RenderFeatureDebugConstants {
142 super::render_feature_debug_constants()
143 }
144
145 fn feature_index(&self) -> RenderFeatureIndex {
146 super::render_feature_index()
147 }
148}