wined3d: Avoid read-to-read resource barriers.
Guard against the most recent write operation instead. Accumulate read bindings to a) not issue unnecessary barriers when a resource has multiple read-only usages, and b) synchronize with all previous read bindings when writing. This is motivated by an issue where a program using a single buffer to store both indices and vertex attributes causes superfluous barriers on each draw call. Signed-off-by: Jan Sikorski <jsikorski@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
53371cc556
commit
b4e03a7c6e
|
@ -1582,22 +1582,38 @@ HRESULT wined3d_buffer_vk_init(struct wined3d_buffer_vk *buffer_vk, struct wined
|
||||||
void wined3d_buffer_vk_barrier(struct wined3d_buffer_vk *buffer_vk,
|
void wined3d_buffer_vk_barrier(struct wined3d_buffer_vk *buffer_vk,
|
||||||
struct wined3d_context_vk *context_vk, uint32_t bind_mask)
|
struct wined3d_context_vk *context_vk, uint32_t bind_mask)
|
||||||
{
|
{
|
||||||
|
uint32_t src_bind_mask = 0;
|
||||||
|
|
||||||
TRACE("buffer_vk %p, context_vk %p, bind_mask %s.\n",
|
TRACE("buffer_vk %p, context_vk %p, bind_mask %s.\n",
|
||||||
buffer_vk, context_vk, wined3d_debug_bind_flags(bind_mask));
|
buffer_vk, context_vk, wined3d_debug_bind_flags(bind_mask));
|
||||||
|
|
||||||
if (buffer_vk->bind_mask && buffer_vk->bind_mask != bind_mask)
|
if (bind_mask & ~WINED3D_READ_ONLY_BIND_MASK)
|
||||||
|
{
|
||||||
|
src_bind_mask = buffer_vk->bind_mask & WINED3D_READ_ONLY_BIND_MASK;
|
||||||
|
if (!src_bind_mask)
|
||||||
|
src_bind_mask = buffer_vk->bind_mask;
|
||||||
|
|
||||||
|
buffer_vk->bind_mask = bind_mask;
|
||||||
|
}
|
||||||
|
else if ((buffer_vk->bind_mask & bind_mask) != bind_mask)
|
||||||
|
{
|
||||||
|
src_bind_mask = buffer_vk->bind_mask & ~WINED3D_READ_ONLY_BIND_MASK;
|
||||||
|
buffer_vk->bind_mask |= bind_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_bind_mask)
|
||||||
{
|
{
|
||||||
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
|
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
|
||||||
VkBufferMemoryBarrier vk_barrier;
|
VkBufferMemoryBarrier vk_barrier;
|
||||||
|
|
||||||
TRACE(" %s -> %s.\n",
|
TRACE(" %s -> %s.\n",
|
||||||
wined3d_debug_bind_flags(buffer_vk->bind_mask), wined3d_debug_bind_flags(bind_mask));
|
wined3d_debug_bind_flags(src_bind_mask), wined3d_debug_bind_flags(bind_mask));
|
||||||
|
|
||||||
wined3d_context_vk_end_current_render_pass(context_vk);
|
wined3d_context_vk_end_current_render_pass(context_vk);
|
||||||
|
|
||||||
vk_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
vk_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||||
vk_barrier.pNext = NULL;
|
vk_barrier.pNext = NULL;
|
||||||
vk_barrier.srcAccessMask = vk_access_mask_from_bind_flags(buffer_vk->bind_mask);
|
vk_barrier.srcAccessMask = vk_access_mask_from_bind_flags(src_bind_mask);
|
||||||
vk_barrier.dstAccessMask = vk_access_mask_from_bind_flags(bind_mask);
|
vk_barrier.dstAccessMask = vk_access_mask_from_bind_flags(bind_mask);
|
||||||
vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
@ -1605,11 +1621,10 @@ void wined3d_buffer_vk_barrier(struct wined3d_buffer_vk *buffer_vk,
|
||||||
vk_barrier.offset = buffer_vk->bo.buffer_offset;
|
vk_barrier.offset = buffer_vk->bo.buffer_offset;
|
||||||
vk_barrier.size = buffer_vk->b.resource.size;
|
vk_barrier.size = buffer_vk->b.resource.size;
|
||||||
VK_CALL(vkCmdPipelineBarrier(wined3d_context_vk_get_command_buffer(context_vk),
|
VK_CALL(vkCmdPipelineBarrier(wined3d_context_vk_get_command_buffer(context_vk),
|
||||||
vk_pipeline_stage_mask_from_bind_flags(buffer_vk->bind_mask),
|
vk_pipeline_stage_mask_from_bind_flags(src_bind_mask),
|
||||||
vk_pipeline_stage_mask_from_bind_flags(bind_mask),
|
vk_pipeline_stage_mask_from_bind_flags(bind_mask),
|
||||||
0, 0, NULL, 1, &vk_barrier, 0, NULL));
|
0, 0, NULL, 1, &vk_barrier, 0, NULL));
|
||||||
}
|
}
|
||||||
buffer_vk->bind_mask = bind_mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
|
HRESULT CDECL wined3d_buffer_create(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
|
||||||
|
|
|
@ -5244,15 +5244,31 @@ HRESULT wined3d_texture_vk_init(struct wined3d_texture_vk *texture_vk, struct wi
|
||||||
void wined3d_texture_vk_barrier(struct wined3d_texture_vk *texture_vk,
|
void wined3d_texture_vk_barrier(struct wined3d_texture_vk *texture_vk,
|
||||||
struct wined3d_context_vk *context_vk, uint32_t bind_mask)
|
struct wined3d_context_vk *context_vk, uint32_t bind_mask)
|
||||||
{
|
{
|
||||||
VkImageSubresourceRange vk_range;
|
uint32_t src_bind_mask = 0;
|
||||||
|
|
||||||
TRACE("texture_vk %p, context_vk %p, bind_mask %s.\n",
|
TRACE("texture_vk %p, context_vk %p, bind_mask %s.\n",
|
||||||
texture_vk, context_vk, wined3d_debug_bind_flags(bind_mask));
|
texture_vk, context_vk, wined3d_debug_bind_flags(bind_mask));
|
||||||
|
|
||||||
if (texture_vk->bind_mask && texture_vk->bind_mask != bind_mask)
|
if (bind_mask & ~WINED3D_READ_ONLY_BIND_MASK)
|
||||||
{
|
{
|
||||||
|
src_bind_mask = texture_vk->bind_mask & WINED3D_READ_ONLY_BIND_MASK;
|
||||||
|
if (!src_bind_mask)
|
||||||
|
src_bind_mask = texture_vk->bind_mask;
|
||||||
|
|
||||||
|
texture_vk->bind_mask = bind_mask;
|
||||||
|
}
|
||||||
|
else if ((texture_vk->bind_mask & bind_mask) != bind_mask)
|
||||||
|
{
|
||||||
|
src_bind_mask = texture_vk->bind_mask & ~WINED3D_READ_ONLY_BIND_MASK;
|
||||||
|
texture_vk->bind_mask |= bind_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_bind_mask)
|
||||||
|
{
|
||||||
|
VkImageSubresourceRange vk_range;
|
||||||
|
|
||||||
TRACE(" %s -> %s.\n",
|
TRACE(" %s -> %s.\n",
|
||||||
wined3d_debug_bind_flags(texture_vk->bind_mask), wined3d_debug_bind_flags(bind_mask));
|
wined3d_debug_bind_flags(src_bind_mask), wined3d_debug_bind_flags(bind_mask));
|
||||||
|
|
||||||
vk_range.aspectMask = vk_aspect_mask_from_format(texture_vk->t.resource.format);
|
vk_range.aspectMask = vk_aspect_mask_from_format(texture_vk->t.resource.format);
|
||||||
vk_range.baseMipLevel = 0;
|
vk_range.baseMipLevel = 0;
|
||||||
|
@ -5261,12 +5277,11 @@ void wined3d_texture_vk_barrier(struct wined3d_texture_vk *texture_vk,
|
||||||
vk_range.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
vk_range.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||||
|
|
||||||
wined3d_context_vk_image_barrier(context_vk, wined3d_context_vk_get_command_buffer(context_vk),
|
wined3d_context_vk_image_barrier(context_vk, wined3d_context_vk_get_command_buffer(context_vk),
|
||||||
vk_pipeline_stage_mask_from_bind_flags(texture_vk->bind_mask),
|
vk_pipeline_stage_mask_from_bind_flags(src_bind_mask),
|
||||||
vk_pipeline_stage_mask_from_bind_flags(bind_mask),
|
vk_pipeline_stage_mask_from_bind_flags(bind_mask),
|
||||||
vk_access_mask_from_bind_flags(texture_vk->bind_mask), vk_access_mask_from_bind_flags(bind_mask),
|
vk_access_mask_from_bind_flags(src_bind_mask), vk_access_mask_from_bind_flags(bind_mask),
|
||||||
texture_vk->layout, texture_vk->layout, texture_vk->image.vk_image, &vk_range);
|
texture_vk->layout, texture_vk->layout, texture_vk->image.vk_image, &vk_range);
|
||||||
}
|
}
|
||||||
texture_vk->bind_mask = bind_mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ffp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
|
static void ffp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
|
||||||
|
|
|
@ -310,6 +310,9 @@ struct min_lookup
|
||||||
extern const struct min_lookup minMipLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
|
extern const struct min_lookup minMipLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
|
||||||
extern const GLenum magLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
|
extern const GLenum magLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
static const uint32_t WINED3D_READ_ONLY_BIND_MASK = WINED3D_BIND_VERTEX_BUFFER | WINED3D_BIND_INDEX_BUFFER
|
||||||
|
| WINED3D_BIND_CONSTANT_BUFFER | WINED3D_BIND_SHADER_RESOURCE | WINED3D_BIND_INDIRECT_BUFFER;
|
||||||
|
|
||||||
GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f) DECLSPEC_HIDDEN;
|
GLenum wined3d_gl_compare_func(enum wined3d_cmp_func f) DECLSPEC_HIDDEN;
|
||||||
VkAccessFlags vk_access_mask_from_bind_flags(uint32_t bind_flags) DECLSPEC_HIDDEN;
|
VkAccessFlags vk_access_mask_from_bind_flags(uint32_t bind_flags) DECLSPEC_HIDDEN;
|
||||||
VkCompareOp vk_compare_op_from_wined3d(enum wined3d_cmp_func op) DECLSPEC_HIDDEN;
|
VkCompareOp vk_compare_op_from_wined3d(enum wined3d_cmp_func op) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue