| 263 | |
| 264 | |
| 265 | void Tr2IndirectDrawBuffer::CopyArguments() |
| 266 | { |
| 267 | |
| 268 | #if TRINITY_PLATFORM == TRINITY_DIRECTX12 |
| 269 | USE_MAIN_THREAD_RENDER_CONTEXT(); |
| 270 | |
| 271 | |
| 272 | /* |
| 273 | * Because we use a ring buffer for the arguments, we get a discontinuity in the copies |
| 274 | * if we end up wrapping around. This code batches the copy operations into up to 2 |
| 275 | * continuous copy ranges to minimize the GPU performance cost in all cases. |
| 276 | */ |
| 277 | |
| 278 | struct CopyRange |
| 279 | { |
| 280 | int32_t start; |
| 281 | int32_t end; |
| 282 | }; |
| 283 | |
| 284 | CopyRange copyRanges[2]; |
| 285 | int copyIndex = -1; |
| 286 | |
| 287 | for( auto it = begin( m_regions ); it != end( m_regions ); ++it ) |
| 288 | { |
| 289 | if( it->copied ) |
| 290 | { |
| 291 | continue; |
| 292 | } |
| 293 | |
| 294 | it->copied = true; |
| 295 | |
| 296 | if( copyIndex == -1 || copyRanges[copyIndex].end != it->start ) |
| 297 | { |
| 298 | //First copy, or copy is discontinuous with previous copy, so move on to the next batch. |
| 299 | copyIndex++; |
| 300 | |
| 301 | CCP_ASSERT( copyIndex < 2 ); //We shouldn't ever need more than two copies. |
| 302 | |
| 303 | //Restart the range at the start of this region |
| 304 | copyRanges[copyIndex].start = it->start; |
| 305 | } |
| 306 | //Expand the range to cover this region. |
| 307 | copyRanges[copyIndex].end = it->end; |
| 308 | } |
| 309 | |
| 310 | if( copyIndex == -1 ) |
| 311 | { |
| 312 | return; //Nothing to copy |
| 313 | } |
| 314 | |
| 315 | GPU_REGION( renderContext, "Copy arguments" ); |
| 316 | |
| 317 | { |
| 318 | D3D12_RESOURCE_TRANSITION_BARRIER transition = { |
| 319 | m_defaultBuffer, |
| 320 | 0, |
| 321 | D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT, |
| 322 | D3D12_RESOURCE_STATE_COPY_DEST |
no test coverage detected