@@ -1165,6 +1165,24 @@ uint8_t *RenderingDeviceDriverD3D12::buffer_persistent_map_advance(BufferID p_bu
11651165 return buf_info->persistent_ptr + buf_info->frame_idx * buf_info->size ;
11661166}
11671167
1168+ uint64_t RenderingDeviceDriverD3D12::buffer_get_dynamic_offsets (Span<BufferID> p_buffers) {
1169+ uint64_t mask = 0u ;
1170+ uint64_t shift = 0u ;
1171+
1172+ for (const BufferID &buf : p_buffers) {
1173+ const BufferInfo *buf_info = (const BufferInfo *)buf.id ;
1174+ if (!buf_info->is_dynamic ()) {
1175+ continue ;
1176+ }
1177+ const BufferDynamicInfo *dyn_buf = (const BufferDynamicInfo *)buf.id ;
1178+ mask |= dyn_buf->frame_idx << shift;
1179+ // We can encode the frame index in 2 bits since frame_count won't be > 4.
1180+ shift += 2UL ;
1181+ }
1182+
1183+ return mask;
1184+ }
1185+
11681186uint64_t RenderingDeviceDriverD3D12::buffer_get_device_address (BufferID p_buffer) {
11691187 const BufferInfo *buf_info = (const BufferInfo *)p_buffer.id ;
11701188 return buf_info->resource ->GetGPUVirtualAddress ();
@@ -2183,27 +2201,36 @@ bool RenderingDeviceDriverD3D12::sampler_is_format_supported_for_filter(DataForm
21832201/* *** VERTEX ARRAY ****/
21842202/* *********************/
21852203
2186- RDD::VertexFormatID RenderingDeviceDriverD3D12::vertex_format_create (VectorView <VertexAttribute> p_vertex_attribs) {
2204+ RDD::VertexFormatID RenderingDeviceDriverD3D12::vertex_format_create (Span <VertexAttribute> p_vertex_attribs, const VertexAttributeBindingsMap &p_vertex_bindings ) {
21872205 VertexFormatInfo *vf_info = VersatileResource::allocate<VertexFormatInfo>(resources_allocator);
2188-
21892206 vf_info->input_elem_descs .resize (p_vertex_attribs.size ());
2190- vf_info->vertex_buffer_strides .resize (p_vertex_attribs.size ());
2207+
2208+ uint32_t max_binding = 0 ;
21912209 for (uint32_t i = 0 ; i < p_vertex_attribs.size (); i++) {
2192- vf_info->input_elem_descs [i] = {};
2193- vf_info->input_elem_descs [i].SemanticName = " TEXCOORD" ;
2194- vf_info->input_elem_descs [i].SemanticIndex = p_vertex_attribs[i].location ;
2195- vf_info->input_elem_descs [i].Format = RD_TO_D3D12_FORMAT[p_vertex_attribs[i].format ].general_format ;
2196- vf_info->input_elem_descs [i].InputSlot = i; // TODO: Can the same slot be used if data comes from the same buffer (regardless format)?
2197- vf_info->input_elem_descs [i].AlignedByteOffset = p_vertex_attribs[i].offset ;
2198- if (p_vertex_attribs[i].frequency == VERTEX_FREQUENCY_INSTANCE) {
2199- vf_info->input_elem_descs [i].InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
2200- vf_info->input_elem_descs [i].InstanceDataStepRate = 1 ;
2210+ D3D12_INPUT_ELEMENT_DESC &input_element_desc = vf_info->input_elem_descs [i];
2211+ const VertexAttribute &vertex_attrib = p_vertex_attribs[i];
2212+ const VertexAttributeBinding &vertex_binding = p_vertex_bindings[vertex_attrib.binding ];
2213+
2214+ input_element_desc = {};
2215+ input_element_desc.SemanticName = " TEXCOORD" ;
2216+ input_element_desc.SemanticIndex = vertex_attrib.location ;
2217+ input_element_desc.Format = RD_TO_D3D12_FORMAT[vertex_attrib.format ].general_format ;
2218+ input_element_desc.InputSlot = vertex_attrib.binding ;
2219+ input_element_desc.AlignedByteOffset = vertex_attrib.offset ;
2220+ if (vertex_binding.frequency == VERTEX_FREQUENCY_INSTANCE) {
2221+ input_element_desc.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
2222+ input_element_desc.InstanceDataStepRate = 1 ;
22012223 } else {
2202- vf_info-> input_elem_descs [i] .InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
2203- vf_info-> input_elem_descs [i] .InstanceDataStepRate = 0 ;
2224+ input_element_desc .InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
2225+ input_element_desc .InstanceDataStepRate = 0 ;
22042226 }
22052227
2206- vf_info->vertex_buffer_strides [i] = p_vertex_attribs[i].stride ;
2228+ max_binding = MAX (max_binding, vertex_attrib.binding + 1 );
2229+ }
2230+
2231+ vf_info->vertex_buffer_strides .resize (max_binding);
2232+ for (const VertexAttributeBindingsMap::KV &vertex_binding_pair : p_vertex_bindings) {
2233+ vf_info->vertex_buffer_strides [vertex_binding_pair.key ] = vertex_binding_pair.value .stride ;
22072234 }
22082235
22092236 return VertexFormatID (vf_info);
@@ -5378,7 +5405,7 @@ void RenderingDeviceDriverD3D12::command_render_draw_indirect_count(CommandBuffe
53785405 cmd_buf_info->cmd_list ->ExecuteIndirect (indirect_cmd_signatures.draw .Get (), p_max_draw_count, indirect_buf_info->resource , p_offset, count_buf_info->resource , p_count_buffer_offset);
53795406}
53805407
5381- void RenderingDeviceDriverD3D12::command_render_bind_vertex_buffers (CommandBufferID p_cmd_buffer, uint32_t p_binding_count, const BufferID *p_buffers, const uint64_t *p_offsets) {
5408+ void RenderingDeviceDriverD3D12::command_render_bind_vertex_buffers (CommandBufferID p_cmd_buffer, uint32_t p_binding_count, const BufferID *p_buffers, const uint64_t *p_offsets, uint64_t p_dynamic_offsets ) {
53825409 CommandBufferInfo *cmd_buf_info = (CommandBufferInfo *)p_cmd_buffer.id ;
53835410
53845411 DEV_ASSERT (cmd_buf_info->render_pass_state .current_subpass != UINT32_MAX);
@@ -5390,8 +5417,15 @@ void RenderingDeviceDriverD3D12::command_render_bind_vertex_buffers(CommandBuffe
53905417 for (uint32_t i = 0 ; i < p_binding_count; i++) {
53915418 BufferInfo *buffer_info = (BufferInfo *)p_buffers[i].id ;
53925419
5420+ uint32_t dynamic_offset = 0 ;
5421+ if (buffer_info->is_dynamic ()) {
5422+ uint64_t buffer_frame_idx = p_dynamic_offsets & 0x3 ; // Assuming max 4 frames.
5423+ p_dynamic_offsets >>= 2 ;
5424+ dynamic_offset = buffer_frame_idx * buffer_info->size ;
5425+ }
5426+
53935427 cmd_buf_info->render_pass_state .vertex_buffer_views [i] = {};
5394- cmd_buf_info->render_pass_state .vertex_buffer_views [i].BufferLocation = buffer_info->resource ->GetGPUVirtualAddress () + p_offsets[i];
5428+ cmd_buf_info->render_pass_state .vertex_buffer_views [i].BufferLocation = buffer_info->resource ->GetGPUVirtualAddress () + dynamic_offset + p_offsets[i];
53955429 cmd_buf_info->render_pass_state .vertex_buffer_views [i].SizeInBytes = buffer_info->size - p_offsets[i];
53965430 if (!barrier_capabilities.enhanced_barriers_supported ) {
53975431 _resource_transition_batch (cmd_buf_info, buffer_info, 0 , 1 , D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
0 commit comments