| 269 | } |
| 270 | |
| 271 | void CommandList::writeVolatileBuffer(Buffer* buffer, const void* data, size_t dataSize) |
| 272 | { |
| 273 | VolatileBufferState& state = m_VolatileBufferStates[buffer]; |
| 274 | |
| 275 | if (!state.initialized) |
| 276 | { |
| 277 | state.minVersion = int(buffer->desc.maxVersions); |
| 278 | state.maxVersion = -1; |
| 279 | state.initialized = true; |
| 280 | } |
| 281 | |
| 282 | std::array<uint64_t, uint32_t(CommandQueue::Count)> queueCompletionValues = { |
| 283 | getQueueLastFinishedID(m_Device, CommandQueue::Graphics), |
| 284 | getQueueLastFinishedID(m_Device, CommandQueue::Compute), |
| 285 | getQueueLastFinishedID(m_Device, CommandQueue::Copy) |
| 286 | }; |
| 287 | |
| 288 | uint32_t searchStart = buffer->versionSearchStart; |
| 289 | uint32_t maxVersions = buffer->desc.maxVersions; |
| 290 | uint32_t version = 0; |
| 291 | |
| 292 | uint64_t originalVersionInfo = 0; |
| 293 | |
| 294 | // Since versionTracking[] can be accessed by multiple threads concurrently, |
| 295 | // perform the search in a loop ending with compare_exchange until the exchange is successful. |
| 296 | while (true) |
| 297 | { |
| 298 | bool found = false; |
| 299 | |
| 300 | // Search through the versions of this buffer, looking for either unused (0) |
| 301 | // or submitted and already finished versions |
| 302 | |
| 303 | for (uint32_t searchIndex = 0; searchIndex < maxVersions; searchIndex++) |
| 304 | { |
| 305 | version = searchIndex + searchStart; |
| 306 | version = (version >= maxVersions) ? (version - maxVersions) : version; |
| 307 | |
| 308 | originalVersionInfo = buffer->versionTracking[version]; |
| 309 | |
| 310 | if (originalVersionInfo == 0) |
| 311 | { |
| 312 | // Previously unused version - definitely available |
| 313 | found = true; |
| 314 | break; |
| 315 | } |
| 316 | |
| 317 | // Decode the bitfield |
| 318 | bool isSubmitted = (originalVersionInfo & c_VersionSubmittedFlag) != 0; |
| 319 | uint32_t queueIndex = uint32_t(originalVersionInfo >> c_VersionQueueShift) & c_VersionQueueMask; |
| 320 | uint64_t id = originalVersionInfo & c_VersionIDMask; |
| 321 | |
| 322 | // If the version is in a recorded but not submitted command list, |
| 323 | // we can't use it. So, only compare the version ID for submitted CLs. |
| 324 | if (isSubmitted) |
| 325 | { |
| 326 | // Versions can potentially be used in CLs submitted to different queues. |
| 327 | // So we store the queue index and use look at the last finished CL in that queue. |
| 328 |
nothing calls this directly
no test coverage detected