When trying to re-create my vertex buffers, my app crashes and I get this error:

D3D12 ERROR: ID3D12Resource2::: CORRUPTION: An ID3D12Resource object (0x000001DDEBA98FC0:'Vertex Buffer Default Resource Heap') is referenced by GPU operations in-flight on Command Queue (0x000001DDEB80E3A0:'Unnamed ID3D12CommandQueue Object'). It is not safe to final-release objects that may have GPU operations pending. This can result in application instability. [ EXECUTION ERROR #921: OBJECT_DELETED_WHILE_STILL_IN_USE]

Here is my function called create_vertex_buffers():

// a triangle
Vertex verts[] = {
    Vertex(0.0f, 0.5f, 0.5f),
    Vertex(0.5f, -0.5f, 0.5f),
    Vertex(-0.5f, -0.5f, 0.5f),

const UINT verts_size = sizeof(verts);

// create default heap
auto buffer = CD3DX12_RESOURCE_DESC::Buffer(verts_size);
auto heap_properties1 = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
    &heap_properties1, // a default heap
    D3D12_HEAP_FLAG_NONE, // no flags
    &buffer, // resource description for a buffer

// create upload heap
// upload heaps are used to upload data to the GPU. CPU can write to it, GPU can read from it
// We will upload the vertex buffer using this heap to the default heap
auto heap_properties2 = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);
auto buffer2 = CD3DX12_RESOURCE_DESC::Buffer(verts_size);
    &heap_properties2, // upload heap
    D3D12_HEAP_FLAG_NONE, // no flags
    &buffer2, // resource description for a buffer

D3D12_SUBRESOURCE_DATA vertex_data = {};
vertex_data.pData = reinterpret_cast<BYTE*>(verts); // pointer to our vertex array
vertex_data.RowPitch = verts_size; // size of all our triangle vertex data
vertex_data.SlicePitch = verts_size; // also the size of our triangle vertex data

UpdateSubresources(command_list.Get(), vertex_buffer.Get(), vertex_buffer_upload.Get(), 0, 0, 1, &vertex_data);

command_list->ResourceBarrier(1, &transition);

vertex_buffer_view.BufferLocation = vertex_buffer->GetGPUVirtualAddress();
vertex_buffer_view.StrideInBytes = sizeof(Vertex);
vertex_buffer_view.SizeInBytes = verts_size;

It is my function for creating the vertex upload and default buffers. I implement it into my command queue like this:

command_list->ResourceBarrier(1, &barrier);

// -------------------------+
create_vertex_buffers(); // | <== This is where I'm calling it!!
// -------------------------+

CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle(rtv_descriptor_heap->GetCPUDescriptorHandleForHeapStart(), frame_index, rtv_descriptor_size);
CD3DX12_CPU_DESCRIPTOR_HANDLE dsv_handle(depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart());

command_list->OMSetRenderTargets(1, &rtv_handle, FALSE, &dsv_handle);

command_list->ClearRenderTargetView(rtv_handle, color, 0, nullptr);
command_list->ClearDepthStencilView(depth_stencil_descriptor_heap->GetCPUDescriptorHandleForHeapStart(), D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);

command_list->SetGraphicsRootSignature(root_signature.Get()); // set the root signature
command_list->RSSetViewports(1, &viewport); // set the viewports
command_list->RSSetScissorRects(1, &scissor_rect); // set the scissor rects
command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // set the primitive topology
command_list->IASetVertexBuffers(0, 1, &vertex_buffer_view); // set the vertex buffer (using the vertex buffer view)
command_list->DrawInstanced(3, 1, 0, 0); // finally draw 3 vertices (draw the triangle)

barrier = CD3DX12_RESOURCE_BARRIER::Transition(render_targets[frame_index].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
command_list->ResourceBarrier(1, &barrier);

I have tried adding a fence after creating the resources and waiting for that fence before calling DrawInstanced(), in case it's still making them once it's started drawing. I tried moving where I call create_vertex_buffers().

I'm unsure of when I should be creating these buffers. I'm planning on later only creating them when necessary, which will be every so often, not every frame.


1 Answer 1


You seem to be recreating the vertex buffer resources in every render frame. You should be calling create_vertex_buffers() only once, for example immediately after you have created your device, swapchain, PSOs and root signatures.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .