@@ -396,8 +396,12 @@ bool GSDevice11::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
396396 }
397397 }
398398
399+ bd = {};
400+
399401 if (m_features.accurate_prims )
400402 {
403+ bd.Usage = D3D11_USAGE_DEFAULT;
404+ bd.CPUAccessFlags = 0 ;
401405 bd.ByteWidth = ACCURATE_PRIMS_BUFFER_SIZE;
402406 bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
403407 bd.StructureByteStride = sizeof (AccuratePrimsEdgeData);
@@ -410,16 +414,19 @@ bool GSDevice11::Create(GSVSyncMode vsync_mode, bool allow_present_throttle)
410414 }
411415
412416 const CD3D11_SHADER_RESOURCE_VIEW_DESC accurate_prims_b_srv_desc (
413- D3D11_SRV_DIMENSION_BUFFER, DXGI_FORMAT_UNKNOWN, 0 , ACCURATE_PRIMS_BUFFER_SIZE / sizeof (AccuratePrimsEdgeData));
414- if (FAILED (m_dev->CreateShaderResourceView (m_accurate_prims_b.get (), &accurate_prims_b_srv_desc, m_accurate_prims_b_srv.put ())))
417+ D3D11_SRV_DIMENSION_BUFFER, DXGI_FORMAT_UNKNOWN, 0 ,
418+ ACCURATE_PRIMS_BUFFER_SIZE / sizeof (AccuratePrimsEdgeData));
419+
420+ if (FAILED (m_dev->CreateShaderResourceView (m_accurate_prims_b.get (), &accurate_prims_b_srv_desc,
421+ m_accurate_prims_b_srv.put ())))
415422 {
416423 Console.Error (" D3D11: Failed to create accurate prims buffer SRV." );
417424 return false ;
418425 }
419426
420427 // If MAX_TEXTURES changes, please change the register for this buffer in the shader.
421428 static_assert (MAX_TEXTURES == 5 );
422- m_ctx->PSSetShaderResources (MAX_TEXTURES , 1 , m_accurate_prims_b_srv.addressof ());
429+ m_ctx->PSSetShaderResources (5 , 1 , m_accurate_prims_b_srv.addressof ());
423430 }
424431
425432 // rasterizer
@@ -2326,29 +2333,18 @@ bool GSDevice11::SetupAccuratePrims(GSHWDrawConfig& config)
23262333 if (size > ACCURATE_PRIMS_BUFFER_SIZE)
23272334 return false ;
23282335
2329- D3D11_MAP type = D3D11_MAP_WRITE_NO_OVERWRITE;
2330-
2331- pxAssert (m_accurate_prims_b_pos % sizeof (AccuratePrimsEdgeData) == 0 );
2332-
2333- if (m_accurate_prims_b_pos + size > ACCURATE_PRIMS_BUFFER_SIZE)
2334- {
2335- m_accurate_prims_b_pos = 0 ;
2336- type = D3D11_MAP_WRITE_DISCARD;
2337- }
2338-
2339- D3D11_MAPPED_SUBRESOURCE m;
2340- if (FAILED (m_ctx->Map (m_accurate_prims_b.get (), 0 , type, 0 , &m)))
2341- return false ;
2342-
2343- void * map = static_cast <u8 *>(m.pData ) + m_accurate_prims_b_pos;
2344-
2345- GSVector4i::storent (map, config.accurate_prims_edge_data ->data (), size);
2346-
2347- m_ctx->Unmap (m_accurate_prims_b.get (), 0 );
2348-
2349- config.cb_ps .accurate_prims_base_index .x = m_accurate_prims_b_pos / sizeof (AccuratePrimsEdgeData);
2350-
2351- m_accurate_prims_b_pos += size;
2336+ // Performance note: UpdateSubresource() copies data to a temp staging buffer to avoid stalling the GPU,
2337+ // so a manual ring buffer is not needed here like VK/DX12.
2338+ D3D11_BOX dst_region{};
2339+ dst_region.left = 0 ;
2340+ dst_region.right = size;
2341+ dst_region.top = 0 ;
2342+ dst_region.bottom = 1 ;
2343+ dst_region.front = 0 ;
2344+ dst_region.back = 1 ;
2345+ m_ctx->UpdateSubresource (m_accurate_prims_b.get (), 0 , &dst_region, config.accurate_prims_edge_data ->data (), size, 0 );
2346+
2347+ config.cb_ps .accurate_prims_base_index .x = 0 ; // No offsetting needed like DX12/VK since we don't use a ring buffer.
23522348 }
23532349 return true ;
23542350}
0 commit comments