d3d12: Add partial media, compute, graphics support with CORE and GENERIC feature levels

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27997>
This commit is contained in:
Sil Vilerino 2023-08-02 12:58:17 -04:00 committed by Marge Bot
parent 0cd023bf6a
commit 55e377e965
12 changed files with 486 additions and 302 deletions

View file

@ -678,6 +678,13 @@ option(
description : 'build gallium d3d12 with video support.', description : 'build gallium d3d12 with video support.',
) )
option(
'gallium-d3d12-graphics',
type : 'feature',
value : 'auto',
description : 'build gallium d3d12 with graphics pipeline support.',
)
option( option(
'radv-build-id', 'radv-build-id',
type : 'string', type : 'string',

View file

@ -58,43 +58,54 @@ d3d12_init_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
batch->bos = _mesa_hash_table_create(NULL, _mesa_hash_pointer, batch->bos = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal); _mesa_key_pointer_equal);
batch->sampler_tables = _mesa_hash_table_create(NULL, d3d12_sampler_desc_table_key_hash,
d3d12_sampler_desc_table_key_equals); util_dynarray_init(&batch->local_bos, NULL);
batch->sampler_views = _mesa_set_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
batch->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer, batch->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal); _mesa_key_pointer_equal);
batch->objects = _mesa_set_create(NULL, batch->objects = _mesa_set_create(NULL,
_mesa_hash_pointer, _mesa_hash_pointer,
_mesa_key_pointer_equal); _mesa_key_pointer_equal);
batch->queries = _mesa_set_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
if (!batch->bos || !batch->sampler_tables || !batch->sampler_views || !batch->surfaces || !batch->objects) if (!batch->bos || !batch->surfaces || !batch->objects)
return false; return false;
util_dynarray_init(&batch->zombie_samplers, NULL); #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
util_dynarray_init(&batch->local_bos, NULL); if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
batch->queries = _mesa_set_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
if (FAILED(screen->dev->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, batch->view_heap =
d3d12_descriptor_heap_new(screen->dev,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
8096);
batch->sampler_tables = _mesa_hash_table_create(NULL, d3d12_sampler_desc_table_key_hash,
d3d12_sampler_desc_table_key_equals);
batch->sampler_views = _mesa_set_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
if (!batch->sampler_tables || !batch->sampler_views || !batch->view_heap || !batch->queries)
return false;
util_dynarray_init(&batch->zombie_samplers, NULL);
batch->sampler_heap =
d3d12_descriptor_heap_new(screen->dev,
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
1024);
if (!batch->sampler_heap)
return false;
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
if (FAILED(screen->dev->CreateCommandAllocator(screen->queue_type,
IID_PPV_ARGS(&batch->cmdalloc)))) IID_PPV_ARGS(&batch->cmdalloc))))
return false; return false;
batch->sampler_heap =
d3d12_descriptor_heap_new(screen->dev,
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
1024);
batch->view_heap =
d3d12_descriptor_heap_new(screen->dev,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
8096);
if (!batch->sampler_heap && !batch->view_heap)
return false;
return true; return true;
} }
@ -138,6 +149,7 @@ delete_object(set_entry *entry)
object->Release(); object->Release();
} }
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void static void
delete_query(set_entry *entry) delete_query(set_entry *entry)
{ {
@ -145,6 +157,7 @@ delete_query(set_entry *entry)
if (pipe_reference(&query->reference, nullptr)) if (pipe_reference(&query->reference, nullptr))
d3d12_destroy_query(query); d3d12_destroy_query(query);
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
bool bool
d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t timeout_ns) d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t timeout_ns)
@ -160,12 +173,8 @@ d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t
} }
_mesa_hash_table_clear(batch->bos, delete_bo_entry); _mesa_hash_table_clear(batch->bos, delete_bo_entry);
_mesa_hash_table_clear(batch->sampler_tables, delete_sampler_view_table);
_mesa_set_clear(batch->sampler_views, delete_sampler_view);
_mesa_set_clear(batch->surfaces, delete_surface); _mesa_set_clear(batch->surfaces, delete_surface);
_mesa_set_clear(batch->objects, delete_object); _mesa_set_clear(batch->objects, delete_object);
_mesa_set_clear(batch->queries, delete_query);
util_dynarray_foreach(&batch->local_bos, d3d12_bo*, bo) { util_dynarray_foreach(&batch->local_bos, d3d12_bo*, bo) {
(*bo)->local_reference_mask[batch->ctx_id] &= ~(1 << batch->ctx_index); (*bo)->local_reference_mask[batch->ctx_id] &= ~(1 << batch->ctx_index);
@ -173,12 +182,19 @@ d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t
} }
util_dynarray_clear(&batch->local_bos); util_dynarray_clear(&batch->local_bos);
util_dynarray_foreach(&batch->zombie_samplers, d3d12_descriptor_handle, handle) #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
d3d12_descriptor_handle_free(handle); if (d3d12_screen(ctx->base.screen)->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
util_dynarray_clear(&batch->zombie_samplers); _mesa_hash_table_clear(batch->sampler_tables, delete_sampler_view_table);
_mesa_set_clear(batch->sampler_views, delete_sampler_view);
d3d12_descriptor_heap_clear(batch->view_heap); _mesa_set_clear(batch->queries, delete_query);
d3d12_descriptor_heap_clear(batch->sampler_heap); util_dynarray_foreach(&batch->zombie_samplers, d3d12_descriptor_handle, handle)
d3d12_descriptor_handle_free(handle);
util_dynarray_clear(&batch->zombie_samplers);
d3d12_descriptor_heap_clear(batch->view_heap);
d3d12_descriptor_heap_clear(batch->sampler_heap);
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
if (FAILED(batch->cmdalloc->Reset())) { if (FAILED(batch->cmdalloc->Reset())) {
debug_printf("D3D12: resetting ID3D12CommandAllocator failed\n"); debug_printf("D3D12: resetting ID3D12CommandAllocator failed\n");
@ -194,15 +210,21 @@ d3d12_destroy_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
{ {
d3d12_reset_batch(ctx, batch, OS_TIMEOUT_INFINITE); d3d12_reset_batch(ctx, batch, OS_TIMEOUT_INFINITE);
batch->cmdalloc->Release(); batch->cmdalloc->Release();
d3d12_descriptor_heap_free(batch->sampler_heap);
d3d12_descriptor_heap_free(batch->view_heap); #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
_mesa_hash_table_destroy(batch->bos, NULL); if (d3d12_screen(ctx->base.screen)->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
_mesa_hash_table_destroy(batch->sampler_tables, NULL); d3d12_descriptor_heap_free(batch->sampler_heap);
_mesa_set_destroy(batch->sampler_views, NULL); d3d12_descriptor_heap_free(batch->view_heap);
_mesa_hash_table_destroy(batch->bos, NULL);
_mesa_hash_table_destroy(batch->sampler_tables, NULL);
_mesa_set_destroy(batch->sampler_views, NULL);
_mesa_set_destroy(batch->queries, NULL);
util_dynarray_fini(&batch->zombie_samplers);
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
_mesa_set_destroy(batch->surfaces, NULL); _mesa_set_destroy(batch->surfaces, NULL);
_mesa_set_destroy(batch->objects, NULL); _mesa_set_destroy(batch->objects, NULL);
_mesa_set_destroy(batch->queries, NULL);
util_dynarray_fini(&batch->zombie_samplers);
util_dynarray_fini(&batch->local_bos); util_dynarray_fini(&batch->local_bos);
} }
@ -210,9 +232,6 @@ void
d3d12_start_batch(struct d3d12_context *ctx, struct d3d12_batch *batch) d3d12_start_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
{ {
struct d3d12_screen *screen = d3d12_screen(ctx->base.screen); struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);
ID3D12DescriptorHeap* heaps[2] = { d3d12_descriptor_heap_get(batch->view_heap),
d3d12_descriptor_heap_get(batch->sampler_heap) };
d3d12_reset_batch(ctx, batch, OS_TIMEOUT_INFINITE); d3d12_reset_batch(ctx, batch, OS_TIMEOUT_INFINITE);
/* Create or reset global command list */ /* Create or reset global command list */
@ -223,7 +242,7 @@ d3d12_start_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
return; return;
} }
} else { } else {
if (FAILED(screen->dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, if (FAILED(screen->dev->CreateCommandList(0, screen->queue_type,
batch->cmdalloc, NULL, batch->cmdalloc, NULL,
IID_PPV_ARGS(&ctx->cmdlist)))) { IID_PPV_ARGS(&ctx->cmdlist)))) {
debug_printf("D3D12: creating ID3D12GraphicsCommandList failed\n"); debug_printf("D3D12: creating ID3D12GraphicsCommandList failed\n");
@ -238,15 +257,22 @@ d3d12_start_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
} }
} }
ctx->cmdlist->SetDescriptorHeaps(2, heaps); #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
ctx->cmdlist_dirty = ~0; if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
for (int i = 0; i < PIPE_SHADER_TYPES; ++i) ID3D12DescriptorHeap* heaps[2] = { d3d12_descriptor_heap_get(batch->view_heap),
ctx->shader_dirty[i] = ~0; d3d12_descriptor_heap_get(batch->sampler_heap) };
ctx->cmdlist->SetDescriptorHeaps(2, heaps);
if (!ctx->queries_disabled) ctx->cmdlist_dirty = ~0;
d3d12_resume_queries(ctx); for (int i = 0; i < PIPE_SHADER_TYPES; ++i)
if (ctx->current_predication) ctx->shader_dirty[i] = ~0;
d3d12_enable_predication(ctx);
if (!ctx->queries_disabled)
d3d12_resume_queries(ctx);
if (ctx->current_predication)
d3d12_enable_predication(ctx);
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
batch->submit_id = ++ctx->submit_id; batch->submit_id = ++ctx->submit_id;
} }
@ -256,8 +282,10 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
{ {
struct d3d12_screen *screen = d3d12_screen(ctx->base.screen); struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (!ctx->queries_disabled) if (!ctx->queries_disabled)
d3d12_suspend_queries(ctx); d3d12_suspend_queries(ctx);
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
if (FAILED(ctx->cmdlist->Close())) { if (FAILED(ctx->cmdlist->Close())) {
debug_printf("D3D12: closing ID3D12GraphicsCommandList failed\n"); debug_printf("D3D12: closing ID3D12GraphicsCommandList failed\n");
@ -284,6 +312,7 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
batch->fence = d3d12_create_fence(screen); batch->fence = d3d12_create_fence(screen);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
set_foreach_remove(batch->queries, entry) { set_foreach_remove(batch->queries, entry) {
d3d12_query *query = (struct d3d12_query *)entry->key; d3d12_query *query = (struct d3d12_query *)entry->key;
if (pipe_reference(&query->reference, nullptr)) if (pipe_reference(&query->reference, nullptr))
@ -291,6 +320,7 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
else else
query->fence_value = screen->fence_value; query->fence_value = screen->fence_value;
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
mtx_unlock(&screen->submit_mutex); mtx_unlock(&screen->submit_mutex);
} }

View file

@ -951,11 +951,15 @@ d3d12_blit(struct pipe_context *pctx,
util_format_short_name(info->src.resource->format), util_format_short_name(info->src.resource->format),
util_format_short_name(info->dst.resource->format)); util_format_short_name(info->dst.resource->format));
if (!info->render_condition_enable && ctx->current_predication) { #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
d3d12_enable_predication(ctx); if (d3d12_screen(pctx->screen)->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
if (D3D12_DEBUG_BLIT & d3d12_debug) if (!info->render_condition_enable && ctx->current_predication) {
debug_printf("D3D12 BLIT: Re-enable predication\n"); d3d12_enable_predication(ctx);
if (D3D12_DEBUG_BLIT & d3d12_debug)
debug_printf("D3D12 BLIT: Re-enable predication\n");
}
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
} }

View file

@ -127,7 +127,7 @@ d3d12_bo_new(struct d3d12_screen *screen, uint64_t size, const pb_desc *pb_desc)
res_desc.MipLevels = 1; res_desc.MipLevels = 1;
res_desc.SampleDesc.Count = 1; res_desc.SampleDesc.Count = 1;
res_desc.SampleDesc.Quality = 0; res_desc.SampleDesc.Quality = 0;
res_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; res_desc.Flags = (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) ? D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS : D3D12_RESOURCE_FLAG_NONE;
res_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; res_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
D3D12_HEAP_TYPE heap_type = D3D12_HEAP_TYPE_DEFAULT; D3D12_HEAP_TYPE heap_type = D3D12_HEAP_TYPE_DEFAULT;

View file

@ -93,7 +93,6 @@ d3d12_context_destroy(struct pipe_context *pctx)
pctx->destroy_query(pctx, ctx->timestamp_query); pctx->destroy_query(pctx, ctx->timestamp_query);
util_unreference_framebuffer_state(&ctx->fb); util_unreference_framebuffer_state(&ctx->fb);
util_blitter_destroy(ctx->blitter);
d3d12_end_batch(ctx, d3d12_current_batch(ctx)); d3d12_end_batch(ctx, d3d12_current_batch(ctx));
for (unsigned i = 0; i < ARRAY_SIZE(ctx->batches); ++i) for (unsigned i = 0; i < ARRAY_SIZE(ctx->batches); ++i)
d3d12_destroy_batch(ctx, &ctx->batches[i]); d3d12_destroy_batch(ctx, &ctx->batches[i]);
@ -102,33 +101,41 @@ d3d12_context_destroy(struct pipe_context *pctx)
ctx->cmdlist2->Release(); ctx->cmdlist2->Release();
if (ctx->cmdlist8) if (ctx->cmdlist8)
ctx->cmdlist8->Release(); ctx->cmdlist8->Release();
d3d12_descriptor_pool_free(ctx->sampler_pool);
util_primconvert_destroy(ctx->primconvert); #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if ((screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) && !(ctx->flags & PIPE_CONTEXT_MEDIA_ONLY)) {
util_blitter_destroy(ctx->blitter);
d3d12_compute_pipeline_state_cache_destroy(ctx);
d3d12_root_signature_cache_destroy(ctx);
d3d12_cmd_signature_cache_destroy(ctx);
d3d12_compute_transform_cache_destroy(ctx);
d3d12_descriptor_pool_free(ctx->sampler_pool);
d3d12_gs_variant_cache_destroy(ctx);
d3d12_tcs_variant_cache_destroy(ctx);
d3d12_gfx_pipeline_state_cache_destroy(ctx);
util_primconvert_destroy(ctx->primconvert);
pipe_resource_reference(&ctx->pstipple.texture, nullptr);
pipe_sampler_view_reference(&ctx->pstipple.sampler_view, nullptr);
util_dynarray_fini(&ctx->recently_destroyed_bos);
FREE(ctx->pstipple.sampler_cso);
if (pctx->stream_uploader)
u_upload_destroy(pctx->stream_uploader);
if (pctx->const_uploader)
u_upload_destroy(pctx->const_uploader);
if (!ctx->queries_disabled) {
u_suballocator_destroy(&ctx->query_allocator);
}
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
slab_destroy_child(&ctx->transfer_pool); slab_destroy_child(&ctx->transfer_pool);
slab_destroy_child(&ctx->transfer_pool_unsync); slab_destroy_child(&ctx->transfer_pool_unsync);
d3d12_gs_variant_cache_destroy(ctx);
d3d12_tcs_variant_cache_destroy(ctx);
d3d12_gfx_pipeline_state_cache_destroy(ctx);
d3d12_compute_pipeline_state_cache_destroy(ctx);
d3d12_root_signature_cache_destroy(ctx);
d3d12_cmd_signature_cache_destroy(ctx);
d3d12_compute_transform_cache_destroy(ctx);
d3d12_context_state_table_destroy(ctx); d3d12_context_state_table_destroy(ctx);
pipe_resource_reference(&ctx->pstipple.texture, nullptr);
pipe_sampler_view_reference(&ctx->pstipple.sampler_view, nullptr);
util_dynarray_fini(&ctx->recently_destroyed_bos);
FREE(ctx->pstipple.sampler_cso);
u_suballocator_destroy(&ctx->query_allocator);
if (pctx->stream_uploader)
u_upload_destroy(pctx->stream_uploader);
if (pctx->const_uploader)
u_upload_destroy(pctx->const_uploader);
FREE(ctx); FREE(ctx);
} }
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void * static void *
d3d12_create_vertex_elements_state(struct pipe_context *pctx, d3d12_create_vertex_elements_state(struct pipe_context *pctx,
unsigned num_elements, unsigned num_elements,
@ -1823,6 +1830,8 @@ d3d12_set_shader_images(struct pipe_context *pctx,
ctx->shader_dirty[shader] |= D3D12_SHADER_DIRTY_IMAGE; ctx->shader_dirty[shader] |= D3D12_SHADER_DIRTY_IMAGE;
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
void void
d3d12_invalidate_context_bindings(struct d3d12_context *ctx, struct d3d12_resource *res) { d3d12_invalidate_context_bindings(struct d3d12_context *ctx, struct d3d12_resource *res) {
// For each shader type, if the resource is currently bound as CBV, SRV, or UAV // For each shader type, if the resource is currently bound as CBV, SRV, or UAV
@ -1846,6 +1855,8 @@ d3d12_invalidate_context_bindings(struct d3d12_context *ctx, struct d3d12_resour
} }
} }
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
bool bool
d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor) d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor)
{ {
@ -2008,6 +2019,8 @@ d3d12_disable_fake_so_buffers(struct d3d12_context *ctx)
return true; return true;
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
void void
d3d12_flush_cmdlist(struct d3d12_context *ctx) d3d12_flush_cmdlist(struct d3d12_context *ctx)
{ {
@ -2031,6 +2044,7 @@ d3d12_flush_cmdlist_and_wait(struct d3d12_context *ctx)
d3d12_reset_batch(ctx, batch, OS_TIMEOUT_INFINITE); d3d12_reset_batch(ctx, batch, OS_TIMEOUT_INFINITE);
} }
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void static void
d3d12_clear_render_target(struct pipe_context *pctx, d3d12_clear_render_target(struct pipe_context *pctx,
struct pipe_surface *psurf, struct pipe_surface *psurf,
@ -2193,6 +2207,8 @@ d3d12_clear(struct pipe_context *pctx,
} }
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
static void static void
d3d12_flush(struct pipe_context *pipe, d3d12_flush(struct pipe_context *pipe,
struct pipe_fence_handle **fence, struct pipe_fence_handle **fence,
@ -2239,6 +2255,8 @@ d3d12_wait(struct pipe_context *pipe, struct pipe_fence_handle *pfence)
screen->cmdqueue->Wait(fence->cmdqueue_fence, fence->value); screen->cmdqueue->Wait(fence->cmdqueue_fence, fence->value);
} }
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void static void
d3d12_init_null_sampler(struct d3d12_context *ctx) d3d12_init_null_sampler(struct d3d12_context *ctx)
{ {
@ -2274,6 +2292,9 @@ d3d12_get_timestamp(struct pipe_context *pctx)
return result.u64; return result.u64;
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void static void
d3d12_rebind_buffer(struct d3d12_context *ctx, struct d3d12_resource *res) d3d12_rebind_buffer(struct d3d12_context *ctx, struct d3d12_resource *res)
{ {
@ -2300,9 +2321,9 @@ d3d12_rebind_buffer(struct d3d12_context *ctx, struct d3d12_resource *res)
assert(!ctx->fake_so_targets[i] || ctx->fake_so_targets[i]->buffer != &res->base.b); assert(!ctx->fake_so_targets[i] || ctx->fake_so_targets[i]->buffer != &res->base.b);
} }
} }
d3d12_invalidate_context_bindings(ctx, res); d3d12_invalidate_context_bindings(ctx, res);
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
static void static void
d3d12_replace_buffer_storage(struct pipe_context *pctx, d3d12_replace_buffer_storage(struct pipe_context *pctx,
@ -2312,7 +2333,6 @@ d3d12_replace_buffer_storage(struct pipe_context *pctx,
uint32_t rebind_mask, uint32_t rebind_mask,
uint32_t delete_buffer_id) uint32_t delete_buffer_id)
{ {
struct d3d12_context *ctx = d3d12_context(pctx);
struct d3d12_resource *dst = d3d12_resource(pdst); struct d3d12_resource *dst = d3d12_resource(pdst);
struct d3d12_resource *src = d3d12_resource(psrc); struct d3d12_resource *src = d3d12_resource(psrc);
@ -2320,7 +2340,12 @@ d3d12_replace_buffer_storage(struct pipe_context *pctx,
d3d12_bo_reference(src->bo); d3d12_bo_reference(src->bo);
dst->bo = src->bo; dst->bo = src->bo;
p_atomic_inc(&dst->generation_id); p_atomic_inc(&dst->generation_id);
d3d12_rebind_buffer(ctx, dst); #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
struct d3d12_context *ctx = d3d12_context(pctx);
if ((d3d12_screen(pctx->screen)->max_feature_level >= D3D_FEATURE_LEVEL_11_0)
&& !(ctx->flags & PIPE_CONTEXT_MEDIA_ONLY))
d3d12_rebind_buffer(ctx, dst);
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
d3d12_bo_unreference(old_bo); d3d12_bo_unreference(old_bo);
} }
@ -2452,6 +2477,21 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
} }
} }
if ((screen->max_feature_level < D3D_FEATURE_LEVEL_11_0) &&
!(flags & PIPE_CONTEXT_MEDIA_ONLY))
{
debug_printf("D3D12: Underlying screen maximum supported feature level is lower than D3D_FEATURE_LEVEL_11_0. The caller to context_create must pass PIPE_CONTEXT_MEDIA_ONLY in flags.\n");
return NULL;
}
#ifndef HAVE_GALLIUM_D3D12_VIDEO
if (flags & PIPE_CONTEXT_MEDIA_ONLY)
{
debug_printf("D3D12: context_create passed PIPE_CONTEXT_MEDIA_ONLY in flags but no media support found.\n");
return NULL;
}
#endif // ifndef HAVE_GALLIUM_D3D12_VIDEO
struct d3d12_context *ctx = CALLOC_STRUCT(d3d12_context); struct d3d12_context *ctx = CALLOC_STRUCT(d3d12_context);
if (!ctx) if (!ctx)
return NULL; return NULL;
@ -2460,151 +2500,183 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
ctx->base.priv = priv; ctx->base.priv = priv;
ctx->base.destroy = d3d12_context_destroy; ctx->base.destroy = d3d12_context_destroy;
ctx->base.create_vertex_elements_state = d3d12_create_vertex_elements_state;
ctx->base.bind_vertex_elements_state = d3d12_bind_vertex_elements_state;
ctx->base.delete_vertex_elements_state = d3d12_delete_vertex_elements_state;
ctx->base.create_blend_state = d3d12_create_blend_state;
ctx->base.bind_blend_state = d3d12_bind_blend_state;
ctx->base.delete_blend_state = d3d12_delete_blend_state;
ctx->base.create_depth_stencil_alpha_state = d3d12_create_depth_stencil_alpha_state;
ctx->base.bind_depth_stencil_alpha_state = d3d12_bind_depth_stencil_alpha_state;
ctx->base.delete_depth_stencil_alpha_state = d3d12_delete_depth_stencil_alpha_state;
ctx->base.create_rasterizer_state = d3d12_create_rasterizer_state;
ctx->base.bind_rasterizer_state = d3d12_bind_rasterizer_state;
ctx->base.delete_rasterizer_state = d3d12_delete_rasterizer_state;
ctx->base.create_sampler_state = d3d12_create_sampler_state;
ctx->base.bind_sampler_states = d3d12_bind_sampler_states;
ctx->base.delete_sampler_state = d3d12_delete_sampler_state;
ctx->base.create_sampler_view = d3d12_create_sampler_view;
ctx->base.set_sampler_views = d3d12_set_sampler_views;
ctx->base.sampler_view_destroy = d3d12_destroy_sampler_view;
ctx->base.create_vs_state = d3d12_create_vs_state;
ctx->base.bind_vs_state = d3d12_bind_vs_state;
ctx->base.delete_vs_state = d3d12_delete_vs_state;
ctx->base.create_fs_state = d3d12_create_fs_state;
ctx->base.bind_fs_state = d3d12_bind_fs_state;
ctx->base.delete_fs_state = d3d12_delete_fs_state;
ctx->base.create_gs_state = d3d12_create_gs_state;
ctx->base.bind_gs_state = d3d12_bind_gs_state;
ctx->base.delete_gs_state = d3d12_delete_gs_state;
ctx->base.create_tcs_state = d3d12_create_tcs_state;
ctx->base.bind_tcs_state = d3d12_bind_tcs_state;
ctx->base.delete_tcs_state = d3d12_delete_tcs_state;
ctx->base.create_tes_state = d3d12_create_tes_state;
ctx->base.bind_tes_state = d3d12_bind_tes_state;
ctx->base.delete_tes_state = d3d12_delete_tes_state;
ctx->base.set_patch_vertices = d3d12_set_patch_vertices;
ctx->base.set_tess_state = d3d12_set_tess_state;
ctx->base.create_compute_state = d3d12_create_compute_state;
ctx->base.bind_compute_state = d3d12_bind_compute_state;
ctx->base.delete_compute_state = d3d12_delete_compute_state;
ctx->base.set_polygon_stipple = d3d12_set_polygon_stipple;
ctx->base.set_vertex_buffers = d3d12_set_vertex_buffers;
ctx->base.set_viewport_states = d3d12_set_viewport_states;
ctx->base.set_scissor_states = d3d12_set_scissor_states;
ctx->base.set_constant_buffer = d3d12_set_constant_buffer;
ctx->base.set_framebuffer_state = d3d12_set_framebuffer_state;
ctx->base.set_clip_state = d3d12_set_clip_state;
ctx->base.set_blend_color = d3d12_set_blend_color;
ctx->base.set_sample_mask = d3d12_set_sample_mask;
ctx->base.set_stencil_ref = d3d12_set_stencil_ref;
ctx->base.create_stream_output_target = d3d12_create_stream_output_target;
ctx->base.stream_output_target_destroy = d3d12_stream_output_target_destroy;
ctx->base.set_stream_output_targets = d3d12_set_stream_output_targets;
ctx->base.set_shader_buffers = d3d12_set_shader_buffers;
ctx->base.set_shader_images = d3d12_set_shader_images;
ctx->base.get_timestamp = d3d12_get_timestamp;
ctx->base.clear = d3d12_clear;
ctx->base.clear_render_target = d3d12_clear_render_target;
ctx->base.clear_depth_stencil = d3d12_clear_depth_stencil;
ctx->base.draw_vbo = d3d12_draw_vbo;
ctx->base.launch_grid = d3d12_launch_grid;
ctx->base.flush = d3d12_flush; ctx->base.flush = d3d12_flush;
ctx->base.flush_resource = d3d12_flush_resource; ctx->base.flush_resource = d3d12_flush_resource;
ctx->base.fence_server_signal = d3d12_signal; ctx->base.fence_server_signal = d3d12_signal;
ctx->base.fence_server_sync = d3d12_wait; ctx->base.fence_server_sync = d3d12_wait;
ctx->base.memory_barrier = d3d12_memory_barrier; ctx->base.memory_barrier = d3d12_memory_barrier;
ctx->base.texture_barrier = d3d12_texture_barrier; ctx->base.texture_barrier = d3d12_texture_barrier;
ctx->base.get_sample_position = u_default_get_sample_position;
ctx->base.get_device_reset_status = d3d12_get_reset_status; ctx->base.get_device_reset_status = d3d12_get_reset_status;
ctx->gfx_pipeline_state.sample_mask = ~0;
ctx->has_flat_varyings = false; ctx->has_flat_varyings = false;
ctx->missing_dual_src_outputs = false; ctx->missing_dual_src_outputs = false;
ctx->manual_depth_range = false; ctx->manual_depth_range = false;
ctx->flags = flags;
d3d12_context_surface_init(&ctx->base);
d3d12_context_resource_init(&ctx->base); d3d12_context_resource_init(&ctx->base);
d3d12_context_query_init(&ctx->base);
d3d12_context_blit_init(&ctx->base); d3d12_context_blit_init(&ctx->base);
#ifdef HAVE_GALLIUM_D3D12_VIDEO #ifdef HAVE_GALLIUM_D3D12_VIDEO
// Add d3d12 video functions entrypoints
ctx->base.create_video_codec = d3d12_video_create_codec; ctx->base.create_video_codec = d3d12_video_create_codec;
ctx->base.create_video_buffer = d3d12_video_buffer_create; ctx->base.create_video_buffer = d3d12_video_buffer_create;
ctx->base.video_buffer_from_handle = d3d12_video_buffer_from_handle; ctx->base.video_buffer_from_handle = d3d12_video_buffer_from_handle;
#endif #endif
slab_create_child(&ctx->transfer_pool, &d3d12_screen(pscreen)->transfer_pool); slab_create_child(&ctx->transfer_pool, &d3d12_screen(pscreen)->transfer_pool);
slab_create_child(&ctx->transfer_pool_unsync, &d3d12_screen(pscreen)->transfer_pool); slab_create_child(&ctx->transfer_pool_unsync, &d3d12_screen(pscreen)->transfer_pool);
ctx->base.stream_uploader = u_upload_create_default(&ctx->base);
ctx->base.const_uploader = u_upload_create_default(&ctx->base);
u_suballocator_init(&ctx->so_allocator, &ctx->base, 4096, 0, u_suballocator_init(&ctx->so_allocator, &ctx->base, 4096, 0,
PIPE_USAGE_DEFAULT, PIPE_USAGE_DEFAULT,
0, false); 0, false);
struct primconvert_config cfg = {};
cfg.primtypes_mask = 1 << MESA_PRIM_POINTS |
1 << MESA_PRIM_LINES |
1 << MESA_PRIM_LINE_STRIP |
1 << MESA_PRIM_TRIANGLES |
1 << MESA_PRIM_TRIANGLE_STRIP;
cfg.restart_primtypes_mask = cfg.primtypes_mask;
cfg.fixed_prim_restart = true;
ctx->primconvert = util_primconvert_create_config(&ctx->base, &cfg);
if (!ctx->primconvert) {
debug_printf("D3D12: failed to create primconvert\n");
return NULL;
}
d3d12_gfx_pipeline_state_cache_init(ctx);
d3d12_compute_pipeline_state_cache_init(ctx);
d3d12_root_signature_cache_init(ctx);
d3d12_cmd_signature_cache_init(ctx);
d3d12_gs_variant_cache_init(ctx);
d3d12_tcs_variant_cache_init(ctx);
d3d12_compute_transform_cache_init(ctx);
d3d12_context_state_table_init(ctx);
ctx->D3D12SerializeVersionedRootSignature =
(PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)util_dl_get_proc_address(screen->d3d12_mod, "D3D12SerializeVersionedRootSignature");
#ifndef _GAMING_XBOX #ifndef _GAMING_XBOX
(void)screen->dev->QueryInterface(&ctx->dev_config); (void)screen->dev->QueryInterface(&ctx->dev_config);
#endif #endif
d3d12_context_state_table_init(ctx);
ctx->queries_disabled = true; // Disabled by default, re-enable if supported FL below
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if ((screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) && !(flags & PIPE_CONTEXT_MEDIA_ONLY)) {
ctx->base.create_compute_state = d3d12_create_compute_state;
ctx->base.bind_compute_state = d3d12_bind_compute_state;
ctx->base.delete_compute_state = d3d12_delete_compute_state;
ctx->base.set_shader_buffers = d3d12_set_shader_buffers;
d3d12_compute_pipeline_state_cache_init(ctx);
d3d12_root_signature_cache_init(ctx);
d3d12_cmd_signature_cache_init(ctx);
d3d12_compute_transform_cache_init(ctx);
ctx->D3D12SerializeVersionedRootSignature =
(PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)util_dl_get_proc_address(screen->d3d12_mod, "D3D12SerializeVersionedRootSignature");
ctx->base.create_sampler_view = d3d12_create_sampler_view;
ctx->base.sampler_view_destroy = d3d12_destroy_sampler_view;
ctx->base.stream_uploader = u_upload_create_default(&ctx->base);
ctx->base.const_uploader = u_upload_create_default(&ctx->base);
ctx->base.get_sample_position = u_default_get_sample_position;
ctx->base.create_vertex_elements_state = d3d12_create_vertex_elements_state;
ctx->base.bind_vertex_elements_state = d3d12_bind_vertex_elements_state;
ctx->base.delete_vertex_elements_state = d3d12_delete_vertex_elements_state;
ctx->base.create_blend_state = d3d12_create_blend_state;
ctx->base.bind_blend_state = d3d12_bind_blend_state;
ctx->base.delete_blend_state = d3d12_delete_blend_state;
ctx->base.create_depth_stencil_alpha_state = d3d12_create_depth_stencil_alpha_state;
ctx->base.bind_depth_stencil_alpha_state = d3d12_bind_depth_stencil_alpha_state;
ctx->base.delete_depth_stencil_alpha_state = d3d12_delete_depth_stencil_alpha_state;
ctx->base.create_rasterizer_state = d3d12_create_rasterizer_state;
ctx->base.bind_rasterizer_state = d3d12_bind_rasterizer_state;
ctx->base.delete_rasterizer_state = d3d12_delete_rasterizer_state;
ctx->base.create_sampler_state = d3d12_create_sampler_state;
ctx->base.bind_sampler_states = d3d12_bind_sampler_states;
ctx->base.delete_sampler_state = d3d12_delete_sampler_state;
ctx->base.set_sampler_views = d3d12_set_sampler_views;
ctx->base.create_vs_state = d3d12_create_vs_state;
ctx->base.bind_vs_state = d3d12_bind_vs_state;
ctx->base.delete_vs_state = d3d12_delete_vs_state;
ctx->base.create_fs_state = d3d12_create_fs_state;
ctx->base.bind_fs_state = d3d12_bind_fs_state;
ctx->base.delete_fs_state = d3d12_delete_fs_state;
ctx->base.create_gs_state = d3d12_create_gs_state;
ctx->base.bind_gs_state = d3d12_bind_gs_state;
ctx->base.delete_gs_state = d3d12_delete_gs_state;
ctx->base.create_tcs_state = d3d12_create_tcs_state;
ctx->base.bind_tcs_state = d3d12_bind_tcs_state;
ctx->base.delete_tcs_state = d3d12_delete_tcs_state;
ctx->base.create_tes_state = d3d12_create_tes_state;
ctx->base.bind_tes_state = d3d12_bind_tes_state;
ctx->base.delete_tes_state = d3d12_delete_tes_state;
ctx->base.set_patch_vertices = d3d12_set_patch_vertices;
ctx->base.set_tess_state = d3d12_set_tess_state;
ctx->base.set_polygon_stipple = d3d12_set_polygon_stipple;
ctx->base.set_vertex_buffers = d3d12_set_vertex_buffers;
ctx->base.set_viewport_states = d3d12_set_viewport_states;
ctx->base.set_scissor_states = d3d12_set_scissor_states;
ctx->base.set_constant_buffer = d3d12_set_constant_buffer;
ctx->base.set_framebuffer_state = d3d12_set_framebuffer_state;
ctx->base.set_clip_state = d3d12_set_clip_state;
ctx->base.set_blend_color = d3d12_set_blend_color;
ctx->base.set_sample_mask = d3d12_set_sample_mask;
ctx->base.set_stencil_ref = d3d12_set_stencil_ref;
ctx->base.create_stream_output_target = d3d12_create_stream_output_target;
ctx->base.stream_output_target_destroy = d3d12_stream_output_target_destroy;
ctx->base.set_stream_output_targets = d3d12_set_stream_output_targets;
ctx->base.set_shader_images = d3d12_set_shader_images;
ctx->base.clear = d3d12_clear;
ctx->base.clear_render_target = d3d12_clear_render_target;
ctx->base.clear_depth_stencil = d3d12_clear_depth_stencil;
ctx->base.draw_vbo = d3d12_draw_vbo;
ctx->base.launch_grid = d3d12_launch_grid;
ctx->base.get_timestamp = d3d12_get_timestamp;
ctx->base.get_sample_position = u_default_get_sample_position;
ctx->gfx_pipeline_state.sample_mask = ~0;
d3d12_context_surface_init(&ctx->base);
d3d12_context_query_init(&ctx->base);
ctx->queries_disabled = false;
struct primconvert_config cfg = {};
cfg.primtypes_mask = 1 << MESA_PRIM_POINTS |
1 << MESA_PRIM_LINES |
1 << MESA_PRIM_LINE_STRIP |
1 << MESA_PRIM_TRIANGLES |
1 << MESA_PRIM_TRIANGLE_STRIP;
cfg.restart_primtypes_mask = cfg.primtypes_mask;
cfg.fixed_prim_restart = true;
ctx->primconvert = util_primconvert_create_config(&ctx->base, &cfg);
if (!ctx->primconvert) {
debug_printf("D3D12: failed to create primconvert\n");
return NULL;
}
d3d12_gfx_pipeline_state_cache_init(ctx);
d3d12_gs_variant_cache_init(ctx);
d3d12_tcs_variant_cache_init(ctx);
ctx->sampler_pool = d3d12_descriptor_pool_new(screen,
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
64);
if (!ctx->sampler_pool) {
FREE(ctx);
return NULL;
}
d3d12_init_null_sampler(ctx);
ctx->blitter = util_blitter_create(&ctx->base);
if (!ctx->blitter)
return NULL;
if (!d3d12_init_polygon_stipple(&ctx->base)) {
debug_printf("D3D12: failed to initialize polygon stipple resources\n");
FREE(ctx);
return NULL;
}
#ifdef _WIN32
if (!(d3d12_debug & D3D12_DEBUG_EXPERIMENTAL) ||
(d3d12_debug & D3D12_DEBUG_DISASS))
ctx->dxil_validator = dxil_create_validator(NULL);
#endif
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
ctx->submit_id = (uint64_t)p_atomic_add_return(&screen->ctx_count, 1) << 32ull; ctx->submit_id = (uint64_t)p_atomic_add_return(&screen->ctx_count, 1) << 32ull;
for (unsigned i = 0; i < ARRAY_SIZE(ctx->batches); ++i) { for (unsigned i = 0; i < ARRAY_SIZE(ctx->batches); ++i) {
@ -2615,31 +2687,6 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
} }
d3d12_start_batch(ctx, &ctx->batches[0]); d3d12_start_batch(ctx, &ctx->batches[0]);
ctx->sampler_pool = d3d12_descriptor_pool_new(screen,
D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
64);
if (!ctx->sampler_pool) {
FREE(ctx);
return NULL;
}
d3d12_init_null_sampler(ctx);
#ifdef _WIN32
if (!(d3d12_debug & D3D12_DEBUG_EXPERIMENTAL) ||
(d3d12_debug & D3D12_DEBUG_DISASS))
ctx->dxil_validator = dxil_create_validator(NULL);
#endif
ctx->blitter = util_blitter_create(&ctx->base);
if (!ctx->blitter)
return NULL;
if (!d3d12_init_polygon_stipple(&ctx->base)) {
debug_printf("D3D12: failed to initialize polygon stipple resources\n");
FREE(ctx);
return NULL;
}
mtx_lock(&screen->submit_mutex); mtx_lock(&screen->submit_mutex);
list_addtail(&ctx->context_list_entry, &screen->context_list); list_addtail(&ctx->context_list_entry, &screen->context_list);
if (screen->context_id_count > 0) if (screen->context_id_count > 0)

View file

@ -245,6 +245,7 @@ struct d3d12_context {
bool has_flat_varyings; bool has_flat_varyings;
bool missing_dual_src_outputs; bool missing_dual_src_outputs;
bool manual_depth_range; bool manual_depth_range;
uint flags;
struct d3d12_gfx_pipeline_state gfx_pipeline_state; struct d3d12_gfx_pipeline_state gfx_pipeline_state;
struct d3d12_compute_pipeline_state compute_pipeline_state; struct d3d12_compute_pipeline_state compute_pipeline_state;

View file

@ -300,6 +300,18 @@ init_texture(struct d3d12_screen *screen,
HRESULT hres = E_FAIL; HRESULT hres = E_FAIL;
enum d3d12_residency_status init_residency; enum d3d12_residency_status init_residency;
if (heap) {
D3D12_FEATURE_DATA_PLACED_RESOURCE_SUPPORT_INFO capData;
capData.Dimension = desc.Dimension;
capData.Format = desc.Format;
capData.DestHeapProperties = heap->GetDesc().Properties;
capData.Supported = false;
if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_PLACED_RESOURCE_SUPPORT_INFO, &capData, sizeof(capData))) || !capData.Supported) {
debug_printf("D3D12: d3d12_resource_create_or_place cannot place a resource since D3D12_FEATURE_DATA_PLACED_RESOURCE_SUPPORT_INFO is not supported\n");
return false;
}
}
if (screen->opts12.RelaxedFormatCastingSupported) { if (screen->opts12.RelaxedFormatCastingSupported) {
D3D12_RESOURCE_DESC1 desc1 = { D3D12_RESOURCE_DESC1 desc1 = {
desc.Dimension, desc.Dimension,

View file

@ -275,7 +275,7 @@ ensure_state_fixup_cmdlist(struct d3d12_context *ctx, ID3D12CommandAllocator *al
if (!ctx->state_fixup_cmdlist) { if (!ctx->state_fixup_cmdlist) {
struct d3d12_screen *screen = d3d12_screen(ctx->base.screen); struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);
screen->dev->CreateCommandList(0, screen->dev->CreateCommandList(0,
D3D12_COMMAND_LIST_TYPE_DIRECT, screen->queue_type,
alloc, alloc,
nullptr, nullptr,
IID_PPV_ARGS(&ctx->state_fixup_cmdlist)); IID_PPV_ARGS(&ctx->state_fixup_cmdlist));

View file

@ -118,7 +118,7 @@ d3d12_get_video_mem(struct pipe_screen *pscreen)
} }
static int static int
d3d12_get_param(struct pipe_screen *pscreen, enum pipe_cap param) d3d12_get_param_default(struct pipe_screen *pscreen, enum pipe_cap param)
{ {
struct d3d12_screen *screen = d3d12_screen(pscreen); struct d3d12_screen *screen = d3d12_screen(pscreen);
@ -372,6 +372,32 @@ d3d12_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
} }
} }
static int
d3d12_get_generic_param(struct pipe_screen *pscreen, enum pipe_cap param)
{
struct d3d12_screen *screen = d3d12_screen(pscreen);
switch (param) {
case PIPE_CAP_ACCELERATED:
return screen->vendor_id != HW_VENDOR_MICROSOFT;
case PIPE_CAP_VIDEO_MEMORY:
return d3d12_get_video_mem(pscreen);
case PIPE_CAP_UMA:
return screen->architecture.UMA;
default:
return 0;
}
}
static int
d3d12_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
{
struct d3d12_screen *screen = d3d12_screen(pscreen);
if (screen->max_feature_level < D3D_FEATURE_LEVEL_11_0)
return d3d12_get_generic_param(pscreen, param);
return d3d12_get_param_default(pscreen, param);
}
static float static float
d3d12_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) d3d12_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
{ {
@ -715,18 +741,22 @@ d3d12_is_format_supported(struct pipe_screen *pscreen,
void void
d3d12_deinit_screen(struct d3d12_screen *screen) d3d12_deinit_screen(struct d3d12_screen *screen)
{ {
if (screen->rtv_pool) { #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
d3d12_descriptor_pool_free(screen->rtv_pool); if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
screen->rtv_pool = nullptr; if (screen->rtv_pool) {
} d3d12_descriptor_pool_free(screen->rtv_pool);
if (screen->dsv_pool) { screen->rtv_pool = nullptr;
d3d12_descriptor_pool_free(screen->dsv_pool); }
screen->dsv_pool = nullptr; if (screen->dsv_pool) {
} d3d12_descriptor_pool_free(screen->dsv_pool);
if (screen->view_pool) { screen->dsv_pool = nullptr;
d3d12_descriptor_pool_free(screen->view_pool); }
screen->view_pool = nullptr; if (screen->view_pool) {
d3d12_descriptor_pool_free(screen->view_pool);
screen->view_pool = nullptr;
}
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
if (screen->readback_slab_bufmgr) { if (screen->readback_slab_bufmgr) {
screen->readback_slab_bufmgr->destroy(screen->readback_slab_bufmgr); screen->readback_slab_bufmgr->destroy(screen->readback_slab_bufmgr);
screen->readback_slab_bufmgr = nullptr; screen->readback_slab_bufmgr = nullptr;
@ -776,8 +806,12 @@ d3d12_destroy_screen(struct d3d12_screen *screen)
slab_destroy_parent(&screen->transfer_pool); slab_destroy_parent(&screen->transfer_pool);
mtx_destroy(&screen->submit_mutex); mtx_destroy(&screen->submit_mutex);
mtx_destroy(&screen->descriptor_pool_mutex); mtx_destroy(&screen->descriptor_pool_mutex);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
d3d12_varying_cache_destroy(screen); d3d12_varying_cache_destroy(screen);
mtx_destroy(&screen->varying_info_mutex); mtx_destroy(&screen->varying_info_mutex);
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
if (screen->d3d12_mod) if (screen->d3d12_mod)
util_dl_close(screen->d3d12_mod); util_dl_close(screen->d3d12_mod);
glsl_type_singleton_decref(); glsl_type_singleton_decref();
@ -982,8 +1016,10 @@ create_device(util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory
if (factory) { if (factory) {
factory->SetFlags(D3D12_DEVICE_FACTORY_FLAG_ALLOW_RETURNING_EXISTING_DEVICE | factory->SetFlags(D3D12_DEVICE_FACTORY_FLAG_ALLOW_RETURNING_EXISTING_DEVICE |
D3D12_DEVICE_FACTORY_FLAG_ALLOW_RETURNING_INCOMPATIBLE_EXISTING_DEVICE); D3D12_DEVICE_FACTORY_FLAG_ALLOW_RETURNING_INCOMPATIBLE_EXISTING_DEVICE);
if (FAILED(factory->CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&dev)))) /* Fallback to D3D_FEATURE_LEVEL_11_0 for D3D12 versions without generic support */
debug_printf("D3D12: D3D12CreateDevice failed\n"); if (FAILED(factory->CreateDevice(adapter, D3D_FEATURE_LEVEL_1_0_GENERIC, IID_PPV_ARGS(&dev))))
if (FAILED(factory->CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&dev))))
debug_printf("D3D12: D3D12CreateDevice failed\n");
} else { } else {
typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown*, D3D_FEATURE_LEVEL, REFIID, void**); typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown*, D3D_FEATURE_LEVEL, REFIID, void**);
PFN_D3D12CREATEDEVICE D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)util_dl_get_proc_address(d3d12_mod, "D3D12CreateDevice"); PFN_D3D12CREATEDEVICE D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)util_dl_get_proc_address(d3d12_mod, "D3D12CreateDevice");
@ -991,8 +1027,10 @@ create_device(util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory
debug_printf("D3D12: failed to load D3D12CreateDevice from D3D12.DLL\n"); debug_printf("D3D12: failed to load D3D12CreateDevice from D3D12.DLL\n");
return NULL; return NULL;
} }
if (FAILED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&dev)))) /* Fallback to D3D_FEATURE_LEVEL_11_0 for D3D12 versions without generic support */
debug_printf("D3D12: D3D12CreateDevice failed\n"); if (FAILED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_1_0_GENERIC, IID_PPV_ARGS(&dev))))
if (FAILED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&dev))))
debug_printf("D3D12: D3D12CreateDevice failed\n");
} }
return dev; return dev;
@ -1333,8 +1371,11 @@ d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LU
for (unsigned i = 0; i < 16; ++i) for (unsigned i = 0; i < 16; ++i)
screen->context_id_list[i] = 15 - i; screen->context_id_list[i] = 15 - i;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
d3d12_varying_cache_init(screen); d3d12_varying_cache_init(screen);
mtx_init(&screen->varying_info_mutex, mtx_plain); mtx_init(&screen->varying_info_mutex, mtx_plain);
screen->base.get_compiler_options = d3d12_get_compiler_options;
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
slab_create_parent(&screen->transfer_pool, sizeof(struct d3d12_transfer), 16); slab_create_parent(&screen->transfer_pool, sizeof(struct d3d12_transfer), 16);
@ -1346,7 +1387,7 @@ d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LU
screen->base.get_shader_param = d3d12_get_shader_param; screen->base.get_shader_param = d3d12_get_shader_param;
screen->base.get_compute_param = d3d12_get_compute_param; screen->base.get_compute_param = d3d12_get_compute_param;
screen->base.is_format_supported = d3d12_is_format_supported; screen->base.is_format_supported = d3d12_is_format_supported;
screen->base.get_compiler_options = d3d12_get_compiler_options;
screen->base.context_create = d3d12_context_create; screen->base.context_create = d3d12_context_create;
screen->base.flush_frontbuffer = d3d12_flush_frontbuffer; screen->base.flush_frontbuffer = d3d12_flush_frontbuffer;
screen->base.get_device_luid = d3d12_get_adapter_luid; screen->base.get_device_luid = d3d12_get_adapter_luid;
@ -1572,6 +1613,8 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter)
D3D12_FEATURE_DATA_FEATURE_LEVELS feature_levels; D3D12_FEATURE_DATA_FEATURE_LEVELS feature_levels;
static const D3D_FEATURE_LEVEL levels[] = { static const D3D_FEATURE_LEVEL levels[] = {
D3D_FEATURE_LEVEL_1_0_GENERIC,
D3D_FEATURE_LEVEL_1_0_CORE,
D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_12_0,
@ -1585,26 +1628,32 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter)
debug_printf("D3D12: failed to get device feature levels\n"); debug_printf("D3D12: failed to get device feature levels\n");
return false; return false;
} }
screen->max_feature_level = feature_levels.MaxSupportedFeatureLevel;
static const D3D_SHADER_MODEL valid_shader_models[] = { screen->max_feature_level = feature_levels.MaxSupportedFeatureLevel;
D3D_SHADER_MODEL_6_8, screen->queue_type = (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) ? D3D12_COMMAND_LIST_TYPE_DIRECT : D3D12_COMMAND_LIST_TYPE_COMPUTE;
D3D_SHADER_MODEL_6_7, D3D_SHADER_MODEL_6_6, D3D_SHADER_MODEL_6_5, D3D_SHADER_MODEL_6_4,
D3D_SHADER_MODEL_6_3, D3D_SHADER_MODEL_6_2, D3D_SHADER_MODEL_6_1, D3D_SHADER_MODEL_6_0, #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
}; if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
for (UINT i = 0; i < ARRAY_SIZE(valid_shader_models); ++i) { static const D3D_SHADER_MODEL valid_shader_models[] = {
D3D12_FEATURE_DATA_SHADER_MODEL shader_model = { valid_shader_models[i] }; D3D_SHADER_MODEL_6_8,
if (SUCCEEDED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shader_model, sizeof(shader_model)))) { D3D_SHADER_MODEL_6_7, D3D_SHADER_MODEL_6_6, D3D_SHADER_MODEL_6_5, D3D_SHADER_MODEL_6_4,
static_assert(D3D_SHADER_MODEL_6_0 == 0x60 && SHADER_MODEL_6_0 == 0x60000, "Validating math below"); D3D_SHADER_MODEL_6_3, D3D_SHADER_MODEL_6_2, D3D_SHADER_MODEL_6_1, D3D_SHADER_MODEL_6_0,
static_assert(D3D_SHADER_MODEL_6_8 == 0x68 && SHADER_MODEL_6_8 == 0x60008, "Validating math below"); };
screen->max_shader_model = static_cast<dxil_shader_model>(((shader_model.HighestShaderModel & 0xf0) << 12) | for (UINT i = 0; i < ARRAY_SIZE(valid_shader_models); ++i) {
(shader_model.HighestShaderModel & 0xf)); D3D12_FEATURE_DATA_SHADER_MODEL shader_model = { valid_shader_models[i] };
break; if (SUCCEEDED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shader_model, sizeof(shader_model)))) {
static_assert(D3D_SHADER_MODEL_6_0 == 0x60 && SHADER_MODEL_6_0 == 0x60000, "Validating math below");
static_assert(D3D_SHADER_MODEL_6_8 == 0x68 && SHADER_MODEL_6_8 == 0x60008, "Validating math below");
screen->max_shader_model = static_cast<dxil_shader_model>(((shader_model.HighestShaderModel & 0xf0) << 12) |
(shader_model.HighestShaderModel & 0xf));
break;
}
} }
} }
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
D3D12_COMMAND_QUEUE_DESC queue_desc; D3D12_COMMAND_QUEUE_DESC queue_desc;
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; queue_desc.Type = screen->queue_type;
queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queue_desc.NodeMask = 0; queue_desc.NodeMask = 0;
@ -1676,44 +1725,47 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter)
if (!screen->readback_slab_bufmgr) if (!screen->readback_slab_bufmgr)
return false; return false;
screen->rtv_pool = d3d12_descriptor_pool_new(screen, #ifdef HAVE_GALLIUM_D3D12_GRAPHICS
D3D12_DESCRIPTOR_HEAP_TYPE_RTV, if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
64); screen->rtv_pool = d3d12_descriptor_pool_new(screen,
screen->dsv_pool = d3d12_descriptor_pool_new(screen, D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 64);
64); screen->dsv_pool = d3d12_descriptor_pool_new(screen,
screen->view_pool = d3d12_descriptor_pool_new(screen, D3D12_DESCRIPTOR_HEAP_TYPE_DSV,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 64);
1024); screen->view_pool = d3d12_descriptor_pool_new(screen,
if (!screen->rtv_pool || !screen->dsv_pool || !screen->view_pool) D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
return false; 1024);
if (!screen->rtv_pool || !screen->dsv_pool || !screen->view_pool)
return false;
d3d12_init_null_srvs(screen); d3d12_init_null_srvs(screen);
d3d12_init_null_uavs(screen); d3d12_init_null_uavs(screen);
d3d12_init_null_rtv(screen); d3d12_init_null_rtv(screen);
screen->have_load_at_vertex = can_attribute_at_vertex(screen); screen->have_load_at_vertex = can_attribute_at_vertex(screen);
screen->support_shader_images = can_shader_image_load_all_formats(screen); screen->support_shader_images = can_shader_image_load_all_formats(screen);
static constexpr uint64_t known_good_warp_version = 10ull << 48 | 22000ull << 16;
bool warp_with_broken_int64 =
(screen->vendor_id == HW_VENDOR_MICROSOFT && screen->driver_version < known_good_warp_version);
unsigned supported_int_sizes = 32 | (screen->opts1.Int64ShaderOps && !warp_with_broken_int64 ? 64 : 0);
unsigned supported_float_sizes = 32 | (screen->opts.DoublePrecisionFloatShaderOps ? 64 : 0);
dxil_get_nir_compiler_options(&screen->nir_options,
screen->max_shader_model,
supported_int_sizes,
supported_float_sizes);
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
#ifndef _GAMING_XBOX #ifndef _GAMING_XBOX
ID3D12Device8 *dev8; ID3D12Device8 *dev8;
if (SUCCEEDED(screen->dev->QueryInterface(&dev8))) { if (SUCCEEDED(screen->dev->QueryInterface(&dev8))) {
dev8->Release(); dev8->Release();
screen->support_create_not_resident = true; screen->support_create_not_resident = true;
} }
screen->dev->QueryInterface(&screen->dev10); screen->dev->QueryInterface(&screen->dev10);
#endif #endif
static constexpr uint64_t known_good_warp_version = 10ull << 48 | 22000ull << 16;
bool warp_with_broken_int64 =
(screen->vendor_id == HW_VENDOR_MICROSOFT && screen->driver_version < known_good_warp_version);
unsigned supported_int_sizes = 32 | (screen->opts1.Int64ShaderOps && !warp_with_broken_int64 ? 64 : 0);
unsigned supported_float_sizes = 32 | (screen->opts.DoublePrecisionFloatShaderOps ? 64 : 0);
dxil_get_nir_compiler_options(&screen->nir_options,
screen->max_shader_model,
supported_int_sizes,
supported_float_sizes);
const char *mesa_version = "Mesa " PACKAGE_VERSION MESA_GIT_SHA1; const char *mesa_version = "Mesa " PACKAGE_VERSION MESA_GIT_SHA1;
struct mesa_sha1 sha1_ctx; struct mesa_sha1 sha1_ctx;
uint8_t sha1[SHA1_DIGEST_LENGTH]; uint8_t sha1[SHA1_DIGEST_LENGTH];

View file

@ -108,6 +108,8 @@ struct d3d12_screen {
volatile uint32_t ctx_count; volatile uint32_t ctx_count;
volatile uint64_t resource_id_generator; volatile uint64_t resource_id_generator;
D3D12_COMMAND_LIST_TYPE queue_type;
/* capabilities */ /* capabilities */
D3D_FEATURE_LEVEL max_feature_level; D3D_FEATURE_LEVEL max_feature_level;
enum dxil_shader_model max_shader_model; enum dxil_shader_model max_shader_model;

View file

@ -25,6 +25,7 @@
#include "d3d12_resource.h" #include "d3d12_resource.h"
#include "d3d12_video_dec.h" #include "d3d12_video_dec.h"
#include "d3d12_residency.h" #include "d3d12_residency.h"
#include "d3d12_context.h"
#include "util/format/u_format.h" #include "util/format/u_format.h"
#include "util/u_inlines.h" #include "util/u_inlines.h"
@ -60,7 +61,13 @@ d3d12_video_buffer_create_impl(struct pipe_context *pipe,
pD3D12VideoBuffer->base.height = tmpl->height; pD3D12VideoBuffer->base.height = tmpl->height;
pD3D12VideoBuffer->base.interlaced = tmpl->interlaced; pD3D12VideoBuffer->base.interlaced = tmpl->interlaced;
pD3D12VideoBuffer->base.associated_data = nullptr; pD3D12VideoBuffer->base.associated_data = nullptr;
pD3D12VideoBuffer->base.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET | PIPE_BIND_CUSTOM;
pD3D12VideoBuffer->base.bind = PIPE_BIND_CUSTOM;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
struct d3d12_screen *dscreen = (struct d3d12_screen*) pipe->screen;
if (dscreen->max_feature_level >= D3D_FEATURE_LEVEL_11_0)
pD3D12VideoBuffer->base.bind |= (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW);
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
// Fill vtable // Fill vtable
pD3D12VideoBuffer->base.destroy = d3d12_video_buffer_destroy; pD3D12VideoBuffer->base.destroy = d3d12_video_buffer_destroy;
@ -231,6 +238,9 @@ d3d12_video_buffer_get_surfaces(struct pipe_video_buffer *buffer)
struct pipe_context * pipe = pD3D12VideoBuffer->base.context; struct pipe_context * pipe = pD3D12VideoBuffer->base.context;
struct pipe_surface surface_template = {}; struct pipe_surface surface_template = {};
if (!pipe->create_surface)
return nullptr;
// Some video frameworks iterate over [0..VL_MAX_SURFACES) and ignore the nullptr entries // Some video frameworks iterate over [0..VL_MAX_SURFACES) and ignore the nullptr entries
// So we have to null initialize the other surfaces not used from [num_planes..VL_MAX_SURFACES) // So we have to null initialize the other surfaces not used from [num_planes..VL_MAX_SURFACES)
// Like in src/gallium/frontends/va/surface.c // Like in src/gallium/frontends/va/surface.c

View file

@ -19,33 +19,50 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE. # IN THE SOFTWARE.
libd3d12_compiler_args = []
_with_gallium_d3d12_graphics = get_option('gallium-d3d12-graphics')
with_gallium_d3d12_graphics = false
if not _with_gallium_d3d12_graphics.disabled()
with_gallium_d3d12_graphics = true
libd3d12_compiler_args += '-DHAVE_GALLIUM_D3D12_GRAPHICS'
endif
if not with_gallium_d3d12_video and not with_gallium_d3d12_graphics
error('d3d12 gallium driver must have at least one of gallium-d3d12-video or gallium-d3d12-graphics enabled.')
endif
files_libd3d12 = files( files_libd3d12 = files(
'd3d12_batch.cpp', 'd3d12_batch.cpp',
'd3d12_blit.cpp', 'd3d12_blit.cpp',
'd3d12_bufmgr.cpp', 'd3d12_bufmgr.cpp',
'd3d12_cmd_signature.cpp',
'd3d12_compiler.cpp',
'd3d12_compute_transforms.cpp',
'd3d12_context.cpp', 'd3d12_context.cpp',
'd3d12_descriptor_pool.cpp',
'd3d12_draw.cpp', 'd3d12_draw.cpp',
'd3d12_fence.cpp', 'd3d12_fence.cpp',
'd3d12_format.c', 'd3d12_format.c',
'd3d12_gs_variant.cpp',
'd3d12_lower_image_casts.c',
'd3d12_lower_point_sprite.c',
'd3d12_nir_passes.c',
'd3d12_pipeline_state.cpp',
'd3d12_query.cpp',
'd3d12_residency.cpp', 'd3d12_residency.cpp',
'd3d12_resource.cpp', 'd3d12_resource.cpp',
'd3d12_resource_state.cpp', 'd3d12_resource_state.cpp',
'd3d12_root_signature.cpp',
'd3d12_screen.cpp', 'd3d12_screen.cpp',
'd3d12_surface.cpp', 'd3d12_surface.cpp',
'd3d12_tcs_variant.cpp',
) )
if with_gallium_d3d12_graphics
files_libd3d12 += [
'd3d12_cmd_signature.cpp',
'd3d12_compiler.cpp',
'd3d12_compute_transforms.cpp',
'd3d12_descriptor_pool.cpp',
'd3d12_nir_passes.c',
'd3d12_pipeline_state.cpp',
'd3d12_query.cpp',
'd3d12_root_signature.cpp',
'd3d12_gs_variant.cpp',
'd3d12_lower_image_casts.c',
'd3d12_lower_point_sprite.c',
'd3d12_tcs_variant.cpp',
]
endif
if with_gallium_d3d12_video if with_gallium_d3d12_video
files_libd3d12 += [ files_libd3d12 += [
'd3d12_video_dec.cpp', 'd3d12_video_dec.cpp',
@ -129,6 +146,8 @@ libd3d12 = static_library(
gnu_symbol_visibility : 'hidden', gnu_symbol_visibility : 'hidden',
include_directories : [inc_include, inc_src, inc_mesa, inc_gallium, inc_gallium_aux], include_directories : [inc_include, inc_src, inc_mesa, inc_gallium, inc_gallium_aux],
dependencies: [idep_nir_headers, idep_libdxil_compiler, dep_dxheaders], dependencies: [idep_nir_headers, idep_libdxil_compiler, dep_dxheaders],
c_args: libd3d12_compiler_args,
cpp_args: libd3d12_compiler_args,
) )
driver_d3d12 = declare_dependency( driver_d3d12 = declare_dependency(