diff --git a/.gitlab-ci/windows/quick_gl.txt b/.gitlab-ci/windows/quick_gl.txt index 052823d94b5..7b73007fc1b 100644 --- a/.gitlab-ci/windows/quick_gl.txt +++ b/.gitlab-ci/windows/quick_gl.txt @@ -623,7 +623,6 @@ spec/arb_direct_state_access/create-transformfeedbacks: skip spec/arb_direct_state_access/getcompressedtextureimage: skip spec/arb_direct_state_access/gettextureimage-formats: crash spec/arb_direct_state_access/gettransformfeedback: skip -spec/arb_direct_state_access/texture-buffer: fail spec/arb_direct_state_access/textures-storage/cube array texture: skip spec/arb_direct_state_access/transformfeedback-bufferbase: skip spec/arb_direct_state_access/transformfeedback-bufferrange: skip @@ -2388,7 +2387,6 @@ spec/arb_texture_barrier/arb_texture_barrier-blending-in-shader 512 42 8 8 4: sk spec/arb_texture_barrier/arb_texture_barrier-blending-in-shader 512 42 8 8 7: skip spec/arb_texture_barrier/arb_texture_barrier-blending-in-shader 512 42 8 8 8: skip spec/arb_texture_buffer_object/bufferstorage: skip -spec/arb_texture_buffer_object/data-sync: fail spec/arb_texture_buffer_object/indexed: skip spec/arb_texture_buffer_object/negative-unsupported: skip spec/arb_texture_buffer_object/subdata-sync: fail @@ -4749,8 +4747,8 @@ wgl/wgl-sanity: skip summary: name: results ---- -------- - pass: 13303 - fail: 535 + pass: 13305 + fail: 533 crash: 67 skip: 4126 timeout: 0 diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index e64d687ba10..1e81dc0e7bf 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -33,6 +33,7 @@ #include "d3d12_screen.h" #include "d3d12_surface.h" +#include "util/u_atomic.h" #include "util/u_blitter.h" #include "util/u_dual_blend.h" #include "util/u_framebuffer.h" @@ -790,37 +791,16 @@ component_mapping(enum pipe_swizzle swizzle, D3D12_SHADER_COMPONENT_MAPPING id) } } -static struct pipe_sampler_view * -d3d12_create_sampler_view(struct pipe_context *pctx, - struct pipe_resource *texture, - const struct pipe_sampler_view *state) +void +d3d12_init_sampler_view_descriptor(struct d3d12_sampler_view *sampler_view) { - struct d3d12_screen *screen = d3d12_screen(pctx->screen); + struct pipe_sampler_view *state = &sampler_view->base; + struct pipe_resource *texture = state->texture; struct d3d12_resource *res = d3d12_resource(texture); - struct d3d12_sampler_view *sampler_view = CALLOC_STRUCT(d3d12_sampler_view); + struct d3d12_screen *screen = d3d12_screen(texture->screen); - sampler_view->base = *state; - sampler_view->base.texture = NULL; - pipe_resource_reference(&sampler_view->base.texture, texture); - sampler_view->base.reference.count = 1; - sampler_view->base.context = pctx; - sampler_view->mip_levels = state->u.tex.last_level - state->u.tex.first_level + 1; - sampler_view->array_size = texture->array_size; - - D3D12_SHADER_RESOURCE_VIEW_DESC desc = {}; struct d3d12_format_info format_info = d3d12_get_format_info(state->format, state->target); - pipe_swizzle swizzle[4] = { - format_info.swizzle[sampler_view->base.swizzle_r], - format_info.swizzle[sampler_view->base.swizzle_g], - format_info.swizzle[sampler_view->base.swizzle_b], - format_info.swizzle[sampler_view->base.swizzle_a] - }; - - sampler_view->swizzle_override_r = swizzle[0]; - sampler_view->swizzle_override_g = swizzle[1]; - sampler_view->swizzle_override_b = swizzle[2]; - sampler_view->swizzle_override_a = swizzle[3]; - + D3D12_SHADER_RESOURCE_VIEW_DESC desc = {}; desc.Format = d3d12_get_resource_srv_format(state->format, state->target); desc.ViewDimension = view_dimension(state->target, texture->nr_samples); @@ -828,17 +808,17 @@ d3d12_create_sampler_view(struct pipe_context *pctx, * for cube maps, and we sampling is not supported for integer textures, so we have to * handle this SRV as if it were a 2D texture array */ if ((desc.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBE || - desc.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBEARRAY) && - util_format_is_pure_integer(state->format)) { + desc.ViewDimension == D3D12_SRV_DIMENSION_TEXTURECUBEARRAY) && + util_format_is_pure_integer(state->format)) { desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; } desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( - component_mapping(swizzle[0], D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0), - component_mapping(swizzle[1], D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1), - component_mapping(swizzle[2], D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2), - component_mapping(swizzle[3], D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3) - ); + component_mapping((pipe_swizzle)sampler_view->swizzle_override_r, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0), + component_mapping((pipe_swizzle)sampler_view->swizzle_override_g, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1), + component_mapping((pipe_swizzle)sampler_view->swizzle_override_b, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2), + component_mapping((pipe_swizzle)sampler_view->swizzle_override_a, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3) + ); unsigned array_size = state->u.tex.last_layer - state->u.tex.first_layer + 1; switch (desc.ViewDimension) { @@ -912,12 +892,46 @@ d3d12_create_sampler_view(struct pipe_context *pctx, unreachable("Invalid SRV dimension"); } + screen->dev->CreateShaderResourceView(d3d12_resource_resource(res), &desc, + sampler_view->handle.cpu_handle); +} + +static struct pipe_sampler_view * +d3d12_create_sampler_view(struct pipe_context *pctx, + struct pipe_resource *texture, + const struct pipe_sampler_view *state) +{ + struct d3d12_screen *screen = d3d12_screen(pctx->screen); + struct d3d12_resource *res = d3d12_resource(texture); + struct d3d12_sampler_view *sampler_view = CALLOC_STRUCT(d3d12_sampler_view); + + sampler_view->base = *state; + sampler_view->base.texture = NULL; + pipe_resource_reference(&sampler_view->base.texture, texture); + sampler_view->base.reference.count = 1; + sampler_view->base.context = pctx; + sampler_view->mip_levels = state->u.tex.last_level - state->u.tex.first_level + 1; + sampler_view->array_size = texture->array_size; + sampler_view->texture_generation_id = p_atomic_read(&res->generation_id); + + struct d3d12_format_info format_info = d3d12_get_format_info(state->format, state->target); + pipe_swizzle swizzle[4] = { + format_info.swizzle[sampler_view->base.swizzle_r], + format_info.swizzle[sampler_view->base.swizzle_g], + format_info.swizzle[sampler_view->base.swizzle_b], + format_info.swizzle[sampler_view->base.swizzle_a] + }; + + sampler_view->swizzle_override_r = swizzle[0]; + sampler_view->swizzle_override_g = swizzle[1]; + sampler_view->swizzle_override_b = swizzle[2]; + sampler_view->swizzle_override_a = swizzle[3]; + mtx_lock(&screen->descriptor_pool_mutex); d3d12_descriptor_pool_alloc_handle(screen->view_pool, &sampler_view->handle); mtx_unlock(&screen->descriptor_pool_mutex); - screen->dev->CreateShaderResourceView(d3d12_resource_resource(res), &desc, - sampler_view->handle.cpu_handle); + d3d12_init_sampler_view_descriptor(sampler_view); return &sampler_view->base; } @@ -1833,6 +1847,56 @@ d3d12_get_timestamp(struct pipe_context *pctx) return result.u64; } +static void +d3d12_rebind_buffer(struct d3d12_context *ctx, struct d3d12_resource *res) +{ + if (res->base.b.bind & PIPE_BIND_VERTEX_BUFFER) { + for (unsigned i = 0; i < ctx->num_vbs; ++i) { + struct pipe_vertex_buffer *buf = &ctx->vbs[i]; + + if (!buf->is_user_buffer && &res->base.b == buf->buffer.resource) { + ctx->vbvs[i].BufferLocation = d3d12_resource_gpu_virtual_address(res) + buf->buffer_offset; + ctx->state_dirty |= D3D12_DIRTY_VERTEX_BUFFERS; + } + } + } + + if (res->base.b.bind & PIPE_BIND_STREAM_OUTPUT) { + for (unsigned i = 0; i < ctx->gfx_pipeline_state.num_so_targets; ++i) { + struct d3d12_stream_output_target *target = (struct d3d12_stream_output_target *)ctx->so_targets[i]; + assert(!target || target->fill_buffer != &res->base.b); + if (target && target->base.buffer == &res->base.b) { + fill_stream_output_buffer_view(&ctx->so_buffer_views[i], target); + ctx->state_dirty |= D3D12_DIRTY_STREAM_OUTPUT; + } + + assert(!ctx->fake_so_targets[i] || ctx->fake_so_targets[i]->buffer != &res->base.b); + } + } + + d3d12_invalidate_context_bindings(ctx, res); +} + +static void +d3d12_replace_buffer_storage(struct pipe_context *pctx, + struct pipe_resource *pdst, + struct pipe_resource *psrc, + unsigned minimum_num_rebinds, + 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); + + struct d3d12_bo *old_bo = dst->bo; + d3d12_bo_reference(src->bo); + dst->bo = src->bo; + p_atomic_inc(&dst->generation_id); + d3d12_rebind_buffer(ctx, dst); + d3d12_bo_unreference(old_bo); +} + struct pipe_context * d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) { @@ -1986,6 +2050,13 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) return NULL; } + if (flags & PIPE_CONTEXT_PREFER_THREADED) + return threaded_context_create(&ctx->base, + &screen->transfer_pool, + d3d12_replace_buffer_storage, + NULL, + &ctx->threaded_context); + return &ctx->base; } diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index 9332aa8dfa0..089e93b6fe8 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -114,6 +114,7 @@ struct d3d12_sampler_view { struct d3d12_descriptor_handle handle; unsigned mip_levels; unsigned array_size; + unsigned texture_generation_id; unsigned swizzle_override_r:3; /**< PIPE_SWIZZLE_x for red component */ unsigned swizzle_override_g:3; /**< PIPE_SWIZZLE_x for green component */ unsigned swizzle_override_b:3; /**< PIPE_SWIZZLE_x for blue component */ @@ -150,6 +151,7 @@ struct d3d12_context { struct pipe_context base; struct slab_child_pool transfer_pool; struct slab_child_pool transfer_pool_unsync; + struct threaded_context *threaded_context; struct primconvert_context *primconvert; struct blitter_context *blitter; struct u_suballocator query_allocator; @@ -314,4 +316,7 @@ d3d12_context_query_init(struct pipe_context *pctx); bool d3d12_need_zero_one_depth_range(struct d3d12_context *ctx); +void +d3d12_init_sampler_view_descriptor(struct d3d12_sampler_view *sampler_view); + #endif diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index a76e73d4660..a7512f55001 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -105,6 +105,13 @@ fill_srv_descriptors(struct d3d12_context *ctx, descs[desc_idx] = view->handle.cpu_handle; d3d12_batch_reference_sampler_view(batch, view); + struct d3d12_resource *res = d3d12_resource(view->base.texture); + /* If this is a buffer that's been replaced, re-create the descriptor */ + if (view->texture_generation_id != res->generation_id) { + d3d12_init_sampler_view_descriptor(view); + view->texture_generation_id = res->generation_id; + } + D3D12_RESOURCE_STATES state = (stage == PIPE_SHADER_FRAGMENT) ? D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; diff --git a/src/gallium/drivers/d3d12/d3d12_fence.cpp b/src/gallium/drivers/d3d12/d3d12_fence.cpp index 453c72b55e8..2772f26e691 100644 --- a/src/gallium/drivers/d3d12/d3d12_fence.cpp +++ b/src/gallium/drivers/d3d12/d3d12_fence.cpp @@ -145,6 +145,7 @@ fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx, { bool ret = d3d12_fence_finish(d3d12_fence(pfence), timeout_ns); if (ret && pctx) { + pctx = threaded_context_unwrap_sync(pctx); struct d3d12_context *ctx = d3d12_context(pctx); d3d12_foreach_submitted_batch(ctx, batch) d3d12_reset_batch(ctx, batch, 0); diff --git a/src/gallium/drivers/d3d12/d3d12_resource.h b/src/gallium/drivers/d3d12/d3d12_resource.h index 06bb4742637..a6df8be215d 100644 --- a/src/gallium/drivers/d3d12/d3d12_resource.h +++ b/src/gallium/drivers/d3d12/d3d12_resource.h @@ -47,6 +47,7 @@ struct d3d12_resource { unsigned dt_stride; struct util_range valid_buffer_range; uint32_t bind_counts[PIPE_SHADER_TYPES][D3D12_RESOURCE_BINDING_TYPES]; + unsigned generation_id; }; struct d3d12_transfer { diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp index 1322714273f..21bdb0dd1a6 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp @@ -647,6 +647,7 @@ d3d12_flush_frontbuffer(struct pipe_screen * pscreen, void *map = winsys->displaytarget_map(winsys, res->dt, 0); if (map) { + pctx = threaded_context_unwrap_sync(pctx); pipe_transfer *transfer = nullptr; void *res_map = pipe_texture_map(pctx, pres, level, layer, PIPE_MAP_READ, 0, 0, u_minify(pres->width0, level),