diff --git a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp index f48f677aab3..0144410a234 100644 --- a/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp +++ b/src/gallium/drivers/d3d12/d3d12_bufmgr.cpp @@ -88,14 +88,14 @@ d3d12_bo_wrap_res(ID3D12Resource *res, enum pipe_format format) } struct d3d12_bo * -d3d12_bo_new(ID3D12Device *dev, uint64_t size, uint64_t alignment) +d3d12_bo_new(ID3D12Device *dev, uint64_t size, const pb_desc *pb_desc) { ID3D12Resource *res; D3D12_RESOURCE_DESC res_desc; res_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; res_desc.Format = DXGI_FORMAT_UNKNOWN; - res_desc.Alignment = alignment; + res_desc.Alignment = pb_desc->alignment; res_desc.Width = size; res_desc.Height = 1; res_desc.DepthOrArraySize = 1; @@ -105,7 +105,13 @@ d3d12_bo_new(ID3D12Device *dev, uint64_t size, uint64_t alignment) res_desc.Flags = D3D12_RESOURCE_FLAG_NONE; res_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - D3D12_HEAP_PROPERTIES heap_pris = dev->GetCustomHeapProperties(0, D3D12_HEAP_TYPE_UPLOAD); + D3D12_HEAP_TYPE heap_type = D3D12_HEAP_TYPE_DEFAULT; + if (pb_desc->usage & PB_USAGE_CPU_READ) + heap_type = D3D12_HEAP_TYPE_READBACK; + else if (pb_desc->usage & PB_USAGE_CPU_WRITE) + heap_type = D3D12_HEAP_TYPE_UPLOAD; + + D3D12_HEAP_PROPERTIES heap_pris = dev->GetCustomHeapProperties(0, heap_type); HRESULT hres = dev->CreateCommittedResource(&heap_pris, D3D12_HEAP_FLAG_NONE, &res_desc, @@ -287,17 +293,19 @@ d3d12_bufmgr_create_buffer(struct pb_manager *pmgr, buf->range.Begin = 0; buf->range.End = size; - buf->bo = d3d12_bo_new(mgr->dev, size, pb_desc->alignment); + buf->bo = d3d12_bo_new(mgr->dev, size, pb_desc); if (!buf->bo) { FREE(buf); return NULL; } - buf->map = d3d12_bo_map(buf->bo, &buf->range); - if (!buf->map) { - d3d12_bo_unreference(buf->bo); - FREE(buf); - return NULL; + if (pb_desc->usage & PB_USAGE_CPU_READ_WRITE) { + buf->map = d3d12_bo_map(buf->bo, &buf->range); + if (!buf->map) { + d3d12_bo_unreference(buf->bo); + FREE(buf); + return NULL; + } } return &buf->base; diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index 7bc1ff428de..944341b0169 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -1313,8 +1313,9 @@ d3d12_create_stream_output_target(struct pipe_context *pctx, cso->base.buffer_size = buffer_size; cso->base.context = pctx; - util_range_add(pres, &res->valid_buffer_range, buffer_offset, - buffer_offset + buffer_size); + if (res->bo && res->bo->buffer && d3d12_buffer(res->bo->buffer)->map) + util_range_add(pres, &res->valid_buffer_range, buffer_offset, + buffer_offset + buffer_size); return &cso->base; } diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp b/src/gallium/drivers/d3d12/d3d12_resource.cpp index 7ec82ab438e..6f15d4f92ab 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource.cpp +++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp @@ -46,7 +46,9 @@ static bool can_map_directly(struct pipe_resource *pres) { return pres->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_LINEAR) || - pres->target == PIPE_BUFFER; + (pres->target == PIPE_BUFFER && + pres->usage != PIPE_USAGE_DEFAULT && + pres->usage != PIPE_USAGE_IMMUTABLE); } static void @@ -118,11 +120,25 @@ init_buffer(struct d3d12_screen *screen, * element state */ assert(templ->format == d3d12_emulated_vtx_format(templ->format)); - /* Don't use slab buffer manager for GPU writable buffers */ - bufmgr = templ->bind & PIPE_BIND_STREAM_OUTPUT ? screen->cache_bufmgr - : screen->slab_bufmgr; + switch (templ->usage) { + case PIPE_USAGE_DEFAULT: + case PIPE_USAGE_IMMUTABLE: + bufmgr = screen->cache_bufmgr; + buf_desc.usage = (pb_usage_flags)PB_USAGE_GPU_READ_WRITE; + break; + case PIPE_USAGE_DYNAMIC: + case PIPE_USAGE_STREAM: + bufmgr = screen->slab_bufmgr; + buf_desc.usage = (pb_usage_flags)(PB_USAGE_CPU_WRITE | PB_USAGE_GPU_READ); + break; + case PIPE_USAGE_STAGING: + bufmgr = screen->readback_slab_bufmgr; + buf_desc.usage = (pb_usage_flags)(PB_USAGE_GPU_WRITE | PB_USAGE_CPU_READ_WRITE); + break; + default: + unreachable("Invalid pipe usage"); + } buf_desc.alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; - buf_desc.usage = (pb_usage_flags)PB_USAGE_ALL; res->dxgi_format = DXGI_FORMAT_UNKNOWN; buf = bufmgr->create_buffer(bufmgr, templ->width0, &buf_desc); if (!buf) diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp index 0cb388277e2..44e44729440 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp @@ -863,7 +863,7 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow struct pb_desc desc; desc.alignment = D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT; - desc.usage = (pb_usage_flags)PB_USAGE_ALL; + desc.usage = (pb_usage_flags)(PB_USAGE_CPU_WRITE | PB_USAGE_GPU_READ); screen->bufmgr = d3d12_bufmgr_create(screen); screen->cache_bufmgr = pb_cache_manager_create(screen->bufmgr, 0xfffff, 2, 0, 64 * 1024 * 1024);