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.',
)
option(
'gallium-d3d12-graphics',
type : 'feature',
value : 'auto',
description : 'build gallium d3d12 with graphics pipeline support.',
)
option(
'radv-build-id',
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,
_mesa_key_pointer_equal);
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);
util_dynarray_init(&batch->local_bos, NULL);
batch->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
batch->objects = _mesa_set_create(NULL,
_mesa_hash_pointer,
_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;
util_dynarray_init(&batch->zombie_samplers, NULL);
util_dynarray_init(&batch->local_bos, NULL);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
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))))
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;
}
@ -138,6 +149,7 @@ delete_object(set_entry *entry)
object->Release();
}
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void
delete_query(set_entry *entry)
{
@ -145,6 +157,7 @@ delete_query(set_entry *entry)
if (pipe_reference(&query->reference, nullptr))
d3d12_destroy_query(query);
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
bool
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->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->objects, delete_object);
_mesa_set_clear(batch->queries, delete_query);
util_dynarray_foreach(&batch->local_bos, d3d12_bo*, bo) {
(*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_foreach(&batch->zombie_samplers, d3d12_descriptor_handle, handle)
d3d12_descriptor_handle_free(handle);
util_dynarray_clear(&batch->zombie_samplers);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (d3d12_screen(ctx->base.screen)->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
_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);
d3d12_descriptor_heap_clear(batch->sampler_heap);
_mesa_set_clear(batch->queries, delete_query);
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())) {
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);
batch->cmdalloc->Release();
d3d12_descriptor_heap_free(batch->sampler_heap);
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);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (d3d12_screen(ctx->base.screen)->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
d3d12_descriptor_heap_free(batch->sampler_heap);
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->objects, NULL);
_mesa_set_destroy(batch->queries, NULL);
util_dynarray_fini(&batch->zombie_samplers);
util_dynarray_fini(&batch->local_bos);
}
@ -210,9 +232,6 @@ void
d3d12_start_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
{
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);
/* Create or reset global command list */
@ -223,7 +242,7 @@ d3d12_start_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
return;
}
} else {
if (FAILED(screen->dev->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT,
if (FAILED(screen->dev->CreateCommandList(0, screen->queue_type,
batch->cmdalloc, NULL,
IID_PPV_ARGS(&ctx->cmdlist)))) {
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);
ctx->cmdlist_dirty = ~0;
for (int i = 0; i < PIPE_SHADER_TYPES; ++i)
ctx->shader_dirty[i] = ~0;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
ID3D12DescriptorHeap* heaps[2] = { d3d12_descriptor_heap_get(batch->view_heap),
d3d12_descriptor_heap_get(batch->sampler_heap) };
ctx->cmdlist->SetDescriptorHeaps(2, heaps);
if (!ctx->queries_disabled)
d3d12_resume_queries(ctx);
if (ctx->current_predication)
d3d12_enable_predication(ctx);
ctx->cmdlist_dirty = ~0;
for (int i = 0; i < PIPE_SHADER_TYPES; ++i)
ctx->shader_dirty[i] = ~0;
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;
}
@ -256,8 +282,10 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
{
struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (!ctx->queries_disabled)
d3d12_suspend_queries(ctx);
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
if (FAILED(ctx->cmdlist->Close())) {
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);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
set_foreach_remove(batch->queries, entry) {
d3d12_query *query = (struct d3d12_query *)entry->key;
if (pipe_reference(&query->reference, nullptr))
@ -291,6 +320,7 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
else
query->fence_value = screen->fence_value;
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
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->dst.resource->format));
if (!info->render_condition_enable && ctx->current_predication) {
d3d12_enable_predication(ctx);
if (D3D12_DEBUG_BLIT & d3d12_debug)
debug_printf("D3D12 BLIT: Re-enable predication\n");
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (d3d12_screen(pctx->screen)->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
if (!info->render_condition_enable && ctx->current_predication) {
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.SampleDesc.Count = 1;
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;
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);
util_unreference_framebuffer_state(&ctx->fb);
util_blitter_destroy(ctx->blitter);
d3d12_end_batch(ctx, d3d12_current_batch(ctx));
for (unsigned i = 0; i < ARRAY_SIZE(ctx->batches); ++i)
d3d12_destroy_batch(ctx, &ctx->batches[i]);
@ -102,33 +101,41 @@ d3d12_context_destroy(struct pipe_context *pctx)
ctx->cmdlist2->Release();
if (ctx->cmdlist8)
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_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);
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);
}
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void *
d3d12_create_vertex_elements_state(struct pipe_context *pctx,
unsigned num_elements,
@ -1823,6 +1830,8 @@ d3d12_set_shader_images(struct pipe_context *pctx,
ctx->shader_dirty[shader] |= D3D12_SHADER_DIRTY_IMAGE;
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
void
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
@ -1846,6 +1855,8 @@ d3d12_invalidate_context_bindings(struct d3d12_context *ctx, struct d3d12_resour
}
}
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
bool
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;
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
void
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);
}
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void
d3d12_clear_render_target(struct pipe_context *pctx,
struct pipe_surface *psurf,
@ -2193,6 +2207,8 @@ d3d12_clear(struct pipe_context *pctx,
}
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
static void
d3d12_flush(struct pipe_context *pipe,
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);
}
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void
d3d12_init_null_sampler(struct d3d12_context *ctx)
{
@ -2274,6 +2292,9 @@ d3d12_get_timestamp(struct pipe_context *pctx)
return result.u64;
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
static void
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);
}
}
d3d12_invalidate_context_bindings(ctx, res);
}
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
static void
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 delete_buffer_id)
{
struct d3d12_context *ctx = d3d12_context(pctx);
struct d3d12_resource *dst = d3d12_resource(pdst);
struct d3d12_resource *src = d3d12_resource(psrc);
@ -2320,7 +2340,12 @@ d3d12_replace_buffer_storage(struct pipe_context *pctx,
d3d12_bo_reference(src->bo);
dst->bo = src->bo;
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);
}
@ -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);
if (!ctx)
return NULL;
@ -2460,151 +2500,183 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
ctx->base.priv = priv;
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_resource = d3d12_flush_resource;
ctx->base.fence_server_signal = d3d12_signal;
ctx->base.fence_server_sync = d3d12_wait;
ctx->base.memory_barrier = d3d12_memory_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->gfx_pipeline_state.sample_mask = ~0;
ctx->has_flat_varyings = false;
ctx->missing_dual_src_outputs = false;
ctx->manual_depth_range = false;
d3d12_context_surface_init(&ctx->base);
ctx->flags = flags;
d3d12_context_resource_init(&ctx->base);
d3d12_context_query_init(&ctx->base);
d3d12_context_blit_init(&ctx->base);
#ifdef HAVE_GALLIUM_D3D12_VIDEO
// Add d3d12 video functions entrypoints
ctx->base.create_video_codec = d3d12_video_create_codec;
ctx->base.create_video_buffer = d3d12_video_buffer_create;
ctx->base.video_buffer_from_handle = d3d12_video_buffer_from_handle;
#endif
slab_create_child(&ctx->transfer_pool, &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,
PIPE_USAGE_DEFAULT,
0, false);
PIPE_USAGE_DEFAULT,
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
(void)screen->dev->QueryInterface(&ctx->dev_config);
#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;
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]);
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);
list_addtail(&ctx->context_list_entry, &screen->context_list);
if (screen->context_id_count > 0)

View File

@ -245,6 +245,7 @@ struct d3d12_context {
bool has_flat_varyings;
bool missing_dual_src_outputs;
bool manual_depth_range;
uint flags;
struct d3d12_gfx_pipeline_state gfx_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;
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) {
D3D12_RESOURCE_DESC1 desc1 = {
desc.Dimension,

View File

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

View File

@ -118,7 +118,7 @@ d3d12_get_video_mem(struct pipe_screen *pscreen)
}
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);
@ -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
d3d12_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
{
@ -715,18 +741,22 @@ d3d12_is_format_supported(struct pipe_screen *pscreen,
void
d3d12_deinit_screen(struct d3d12_screen *screen)
{
if (screen->rtv_pool) {
d3d12_descriptor_pool_free(screen->rtv_pool);
screen->rtv_pool = nullptr;
}
if (screen->dsv_pool) {
d3d12_descriptor_pool_free(screen->dsv_pool);
screen->dsv_pool = nullptr;
}
if (screen->view_pool) {
d3d12_descriptor_pool_free(screen->view_pool);
screen->view_pool = nullptr;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
if (screen->rtv_pool) {
d3d12_descriptor_pool_free(screen->rtv_pool);
screen->rtv_pool = nullptr;
}
if (screen->dsv_pool) {
d3d12_descriptor_pool_free(screen->dsv_pool);
screen->dsv_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) {
screen->readback_slab_bufmgr->destroy(screen->readback_slab_bufmgr);
screen->readback_slab_bufmgr = nullptr;
@ -776,8 +806,12 @@ d3d12_destroy_screen(struct d3d12_screen *screen)
slab_destroy_parent(&screen->transfer_pool);
mtx_destroy(&screen->submit_mutex);
mtx_destroy(&screen->descriptor_pool_mutex);
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
d3d12_varying_cache_destroy(screen);
mtx_destroy(&screen->varying_info_mutex);
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
if (screen->d3d12_mod)
util_dl_close(screen->d3d12_mod);
glsl_type_singleton_decref();
@ -982,8 +1016,10 @@ create_device(util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory
if (factory) {
factory->SetFlags(D3D12_DEVICE_FACTORY_FLAG_ALLOW_RETURNING_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))))
debug_printf("D3D12: D3D12CreateDevice failed\n");
/* Fallback to D3D_FEATURE_LEVEL_11_0 for D3D12 versions without generic support */
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 {
typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown*, D3D_FEATURE_LEVEL, REFIID, void**);
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");
return NULL;
}
if (FAILED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&dev))))
debug_printf("D3D12: D3D12CreateDevice failed\n");
/* Fallback to D3D_FEATURE_LEVEL_11_0 for D3D12 versions without generic support */
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;
@ -1333,8 +1371,11 @@ d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LU
for (unsigned i = 0; i < 16; ++i)
screen->context_id_list[i] = 15 - i;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
d3d12_varying_cache_init(screen);
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);
@ -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_compute_param = d3d12_get_compute_param;
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.flush_frontbuffer = d3d12_flush_frontbuffer;
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;
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_1,
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");
return false;
}
screen->max_feature_level = feature_levels.MaxSupportedFeatureLevel;
static const D3D_SHADER_MODEL valid_shader_models[] = {
D3D_SHADER_MODEL_6_8,
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,
};
for (UINT i = 0; i < ARRAY_SIZE(valid_shader_models); ++i) {
D3D12_FEATURE_DATA_SHADER_MODEL shader_model = { valid_shader_models[i] };
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;
screen->max_feature_level = feature_levels.MaxSupportedFeatureLevel;
screen->queue_type = (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) ? D3D12_COMMAND_LIST_TYPE_DIRECT : D3D12_COMMAND_LIST_TYPE_COMPUTE;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
static const D3D_SHADER_MODEL valid_shader_models[] = {
D3D_SHADER_MODEL_6_8,
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,
};
for (UINT i = 0; i < ARRAY_SIZE(valid_shader_models); ++i) {
D3D12_FEATURE_DATA_SHADER_MODEL shader_model = { valid_shader_models[i] };
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;
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
queue_desc.Type = screen->queue_type;
queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queue_desc.NodeMask = 0;
@ -1676,44 +1725,47 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter)
if (!screen->readback_slab_bufmgr)
return false;
screen->rtv_pool = d3d12_descriptor_pool_new(screen,
D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
64);
screen->dsv_pool = d3d12_descriptor_pool_new(screen,
D3D12_DESCRIPTOR_HEAP_TYPE_DSV,
64);
screen->view_pool = d3d12_descriptor_pool_new(screen,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
1024);
if (!screen->rtv_pool || !screen->dsv_pool || !screen->view_pool)
return false;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
if (screen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) {
screen->rtv_pool = d3d12_descriptor_pool_new(screen,
D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
64);
screen->dsv_pool = d3d12_descriptor_pool_new(screen,
D3D12_DESCRIPTOR_HEAP_TYPE_DSV,
64);
screen->view_pool = d3d12_descriptor_pool_new(screen,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
1024);
if (!screen->rtv_pool || !screen->dsv_pool || !screen->view_pool)
return false;
d3d12_init_null_srvs(screen);
d3d12_init_null_uavs(screen);
d3d12_init_null_rtv(screen);
d3d12_init_null_srvs(screen);
d3d12_init_null_uavs(screen);
d3d12_init_null_rtv(screen);
screen->have_load_at_vertex = can_attribute_at_vertex(screen);
screen->support_shader_images = can_shader_image_load_all_formats(screen);
screen->have_load_at_vertex = can_attribute_at_vertex(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
ID3D12Device8 *dev8;
if (SUCCEEDED(screen->dev->QueryInterface(&dev8))) {
dev8->Release();
screen->support_create_not_resident = true;
}
screen->dev->QueryInterface(&screen->dev10);
ID3D12Device8 *dev8;
if (SUCCEEDED(screen->dev->QueryInterface(&dev8))) {
dev8->Release();
screen->support_create_not_resident = true;
}
screen->dev->QueryInterface(&screen->dev10);
#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;
struct mesa_sha1 sha1_ctx;
uint8_t sha1[SHA1_DIGEST_LENGTH];

View File

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

View File

@ -25,6 +25,7 @@
#include "d3d12_resource.h"
#include "d3d12_video_dec.h"
#include "d3d12_residency.h"
#include "d3d12_context.h"
#include "util/format/u_format.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.interlaced = tmpl->interlaced;
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
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_surface surface_template = {};
if (!pipe->create_surface)
return nullptr;
// 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)
// 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
# 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(
'd3d12_batch.cpp',
'd3d12_blit.cpp',
'd3d12_bufmgr.cpp',
'd3d12_cmd_signature.cpp',
'd3d12_compiler.cpp',
'd3d12_compute_transforms.cpp',
'd3d12_context.cpp',
'd3d12_descriptor_pool.cpp',
'd3d12_draw.cpp',
'd3d12_fence.cpp',
'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_resource.cpp',
'd3d12_resource_state.cpp',
'd3d12_root_signature.cpp',
'd3d12_screen.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
files_libd3d12 += [
'd3d12_video_dec.cpp',
@ -129,6 +146,8 @@ libd3d12 = static_library(
gnu_symbol_visibility : 'hidden',
include_directories : [inc_include, inc_src, inc_mesa, inc_gallium, inc_gallium_aux],
dependencies: [idep_nir_headers, idep_libdxil_compiler, dep_dxheaders],
c_args: libd3d12_compiler_args,
cpp_args: libd3d12_compiler_args,
)
driver_d3d12 = declare_dependency(