[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

mesa: Changes to 'upstream-unstable'



 VERSION                                           |    2 
 bin/.cherry-ignore                                |    3 
 docs/relnotes/13.0.1.html                         |    3 
 docs/relnotes/13.0.2.html                         |  188 ++++++++++++++
 include/pci_ids/i965_pci_ids.h                    |   24 -
 src/amd/common/ac_nir_to_llvm.c                   |   28 +-
 src/amd/vulkan/radv_cmd_buffer.c                  |    1 
 src/amd/vulkan/radv_device.c                      |   18 -
 src/amd/vulkan/radv_formats.c                     |    1 
 src/amd/vulkan/radv_image.c                       |   35 +-
 src/amd/vulkan/radv_meta_clear.c                  |    2 
 src/amd/vulkan/radv_wsi.c                         |    3 
 src/compiler/glsl/cache.c                         |   11 
 src/compiler/glsl/glcpp/glcpp-parse.y             |   25 +
 src/compiler/glsl/glcpp/glcpp.h                   |    9 
 src/compiler/glsl/glsl_lexer.ll                   |    4 
 src/compiler/glsl/lower_output_reads.cpp          |    1 
 src/compiler/spirv/vtn_variables.c                |    8 
 src/gallium/drivers/radeonsi/si_compute.c         |   13 
 src/gallium/drivers/vc4/vc4_context.h             |    8 
 src/gallium/drivers/vc4/vc4_draw.c                |    5 
 src/gallium/drivers/vc4/vc4_program.c             |   27 +-
 src/gallium/drivers/vc4/vc4_qir.h                 |    1 
 src/gallium/drivers/vc4/vc4_qpu_emit.c            |    5 
 src/gallium/drivers/vc4/vc4_register_allocate.c   |    5 
 src/gbm/backends/dri/gbm_dri.c                    |    2 
 src/intel/common/gen_device_info.c                |   48 +++
 src/intel/isl/isl.c                               |    2 
 src/intel/vulkan/anv_blorp.c                      |   24 -
 src/intel/vulkan/anv_cmd_buffer.c                 |    6 
 src/intel/vulkan/anv_descriptor_set.c             |   12 
 src/intel/vulkan/anv_device.c                     |  192 ++++++++++++--
 src/intel/vulkan/anv_formats.c                    |    3 
 src/intel/vulkan/anv_genX.h                       |    2 
 src/intel/vulkan/anv_image.c                      |   12 
 src/intel/vulkan/anv_intel.c                      |    2 
 src/intel/vulkan/anv_pass.c                       |    3 
 src/intel/vulkan/anv_pipeline.c                   |    6 
 src/intel/vulkan/anv_pipeline_cache.c             |    3 
 src/intel/vulkan/anv_private.h                    |   15 +
 src/intel/vulkan/anv_query.c                      |    3 
 src/intel/vulkan/anv_wsi.c                        |   19 +
 src/intel/vulkan/gen8_cmd_buffer.c                |   29 ++
 src/intel/vulkan/genX_blorp_exec.c                |    2 
 src/intel/vulkan/genX_cmd_buffer.c                |   65 ++++
 src/mesa/drivers/dri/i965/brw_cs.c                |    2 
 src/mesa/drivers/dri/i965/brw_fs_nir.cpp          |    2 
 src/mesa/drivers/dri/i965/brw_sampler_state.c     |   18 -
 src/mesa/drivers/dri/i965/brw_state.h             |    9 
 src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp |    3 
 src/mesa/main/arbprogram.c                        |   12 
 src/mesa/main/hash.c                              |   18 -
 src/mesa/main/pipelineobj.c                       |    3 
 src/mesa/main/shaderapi.c                         |   43 +--
 src/vulkan/wsi/Makefile.sources                   |    3 
 src/vulkan/wsi/wsi_common.h                       |    1 
 src/vulkan/wsi/wsi_common_queue.h                 |  154 +++++++++++
 src/vulkan/wsi/wsi_common_wayland.c               |   56 ++--
 src/vulkan/wsi/wsi_common_x11.c                   |  290 +++++++++++++++++++---
 59 files changed, 1227 insertions(+), 267 deletions(-)

New commits:
commit c9e993ba1301ac0380b86a3934f5c97ff0827594
Author: Emil Velikov <emil.velikov@collabora.com>
Date:   Mon Nov 28 15:06:08 2016 +0000

    docs: add release notes for 13.0.2
    
    Signed-off-by: Emil Velikov <emil.velikov@collabora.com>

diff --git a/docs/relnotes/13.0.2.html b/docs/relnotes/13.0.2.html
new file mode 100644
index 0000000..5125b61
--- /dev/null
+++ b/docs/relnotes/13.0.2.html
@@ -0,0 +1,188 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html lang="en">
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8">
+  <title>Mesa Release Notes</title>
+  <link rel="stylesheet" type="text/css" href="../mesa.css">
+</head>
+<body>
+
+<div class="header">
+  <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="../contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 13.0.2 Release Notes / November 28, 2016</h1>
+
+<p>
+Mesa 13.0.2 is a bug fix release which fixes bugs found since the 13.0.1 release.
+</p>
+<p>
+Mesa 13.0.2 implements the OpenGL 4.4 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 4.4.  OpenGL
+4.4 is <strong>only</strong> available if requested at context creation
+because compatibility contexts are not supported.
+</p>
+
+
+<h2>SHA256 checksums</h2>
+<pre>
+TBD
+</pre>
+
+
+<h2>New features</h2>
+<p>None</p>
+
+
+<h2>Bug fixes</h2>
+
+<ul>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=97321";>Bug 97321</a> - Query INFO_LOG_LENGTH for empty info log should return 0</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=97420";>Bug 97420</a> - &quot;#version 0&quot; crashes glsl_compiler</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=98632";>Bug 98632</a> - Fix build on Hurd without PATH_MAX</li>
+
+</ul>
+
+
+<h2>Changes</h2>
+
+<p>Ben Widawsky (3):</p>
+<ul>
+  <li>i965: Add some APL and KBL SKU strings</li>
+  <li>i965: Reorder PCI ID list to match release order</li>
+  <li>i965/glk: Add basic Geminilake support</li>
+</ul>
+
+<p>Dave Airlie (14):</p>
+<ul>
+  <li>radv: fix texturesamples to handle single sample case</li>
+  <li>wsi: fix VK_INCOMPLETE for vkGetSwapchainImagesKHR</li>
+  <li>radv: don't crash on null swapchain destroy.</li>
+  <li>ac/nir/llvm: fix channel in texture gather lowering code.</li>
+  <li>radv: make sure to flush input attachments correctly.</li>
+  <li>radv: fix image view creation for depth and stencil only</li>
+  <li>radv: spir-v allows texture size query with and without lod.</li>
+  <li>vulkan/wsi/x11: handle timeouts properly in next image acquire (v1.1)</li>
+  <li>vulkan/wsi: store present mode in swapchain base class</li>
+  <li>vulkan/wsi/x11: add support for IMMEDIATE present mode</li>
+  <li>radv: fix texel fetch offset with 2d arrays.</li>
+  <li>radv/si: fix optimal micro tile selection</li>
+  <li>radv/ac/llvm: shadow samplers only return one value.</li>
+  <li>radv: fix 3D clears with baseMiplevel</li>
+</ul>
+
+<p>Eduardo Lima Mitev (2):</p>
+<ul>
+  <li>vulkan/wsi/x11: Fix behavior of vkGetPhysicalDeviceSurfaceFormatsKHR</li>
+  <li>vulkan/wsi/x11: Fix behavior of vkGetPhysicalDeviceSurfacePresentModesKHR</li>
+</ul>
+
+<p>Emil Velikov (5):</p>
+<ul>
+  <li>docs: add sha256 checksums for 13.0.1</li>
+  <li>cherry-ignore: add reverted LLVM_LIBDIR patch</li>
+  <li>anv: fix enumeration of properties</li>
+  <li>radv: honour the number of properties available</li>
+  <li>Update version to 13.0.2</li>
+</ul>
+
+<p>Eric Anholt (3):</p>
+<ul>
+  <li>vc4: Don't abort when a shader compile fails.</li>
+  <li>vc4: Clamp the shadow comparison value.</li>
+  <li>vc4: Fix register class handling of DDX/DDY arguments.</li>
+</ul>
+
+<p>Gwan-gyeong Mun (2):</p>
+<ul>
+  <li>util/disk_cache: close a previously opened handle in disk_cache_put (v2)</li>
+  <li>anv: Fix unintentional integer overflow in anv_CreateDmaBufImageINTEL</li>
+</ul>
+
+<p>Iago Toral Quiroga (1):</p>
+<ul>
+  <li>anv/format: handle unsupported formats properly</li>
+</ul>
+
+<p>Ian Romanick (2):</p>
+<ul>
+  <li>glcpp: Handle '#version 0' and other invalid values</li>
+  <li>glsl: Parse 0 as a preprocessor INTCONSTANT</li>
+</ul>
+
+<p>Jason Ekstrand (15):</p>
+<ul>
+  <li>anv/gen8: Stall when needed in Cmd(Set|Reset)Event</li>
+  <li>anv/wsi: Set the fence to signaled in AcquireNextImageKHR</li>
+  <li>anv: Rework fences</li>
+  <li>vulkan/wsi/wayland: Include pthread.h</li>
+  <li>vulkan/wsi/wayland: Clean up some error handling paths</li>
+  <li>vulkan/wsi: Report the correct min/maxImageCount</li>
+  <li>i965/gs: Allow primitive id to be a system value</li>
+  <li>anv: Handle null in all destructors</li>
+  <li>anv/fence: Handle ANV_FENCE_CREATE_SIGNALED_BIT</li>
+  <li>nir/spirv: Fix handling of gl_PrimitiveId</li>
+  <li>anv/blorp: Ignore clears for attachments first used as resolve destinations</li>
+  <li>anv: Implement a depth stall restriction on gen7</li>
+  <li>anv/cmd_buffer: Handle running out of binding tables in compute shaders</li>
+  <li>anv/cmd_buffer: Emit a CS stall before setting a CS pipeline</li>
+  <li>vulkan/wsi/x11: Implement FIFO mode.</li>
+</ul>
+
+<p>Jordan Justen (2):</p>
+<ul>
+  <li>isl: Fix height calculation in isl_msaa_interleaved_scale_px_to_sa</li>
+  <li>i965/hsw: Set integer mode in sampling state for stencil texturing</li>
+</ul>
+
+<p>Kenneth Graunke (4):</p>
+<ul>
+  <li>intel: Set min_ds_entries on Broxton.</li>
+  <li>i965: Fix compute shader crash.</li>
+  <li>mesa: Drop PATH_MAX usage.</li>
+  <li>i965: Fix GS push inputs with enhanced layouts.</li>
+</ul>
+
+<p>Kevin Strasser (1):</p>
+<ul>
+  <li>vulkan/wsi: Add a thread-safe queue implementation</li>
+</ul>
+
+<p>Lionel Landwerlin (1):</p>
+<ul>
+  <li>anv: fix multi level clears with VK_REMAINING_MIP_LEVELS</li>
+</ul>
+
+<p>Lucas Stach (1):</p>
+<ul>
+  <li>gbm: request correct version of the DRI2_FENCE extension</li>
+</ul>
+
+<p>Nicolai Hähnle (2):</p>
+<ul>
+  <li>radeonsi: store group_size_variable in struct si_compute</li>
+  <li>glsl/lower_output_reads: fix geometry shader output handling with conditional emit</li>
+</ul>
+
+<p>Steinar H. Gunderson (1):</p>
+<ul>
+  <li>Fix races during _mesa_HashWalk().</li>
+</ul>
+
+<p>Tapani Pälli (1):</p>
+<ul>
+  <li>mesa: fix empty program log length</li>
+</ul>
+
+
+</div>
+</body>
+</html>

commit f92c2e3d2bc0bc44e53f42706ebce041a313246c
Author: Emil Velikov <emil.velikov@collabora.com>
Date:   Mon Nov 28 15:02:48 2016 +0000

    Update version to 13.0.2
    
    Signed-off-by: Emil Velikov <emil.velikov@collabora.com>

diff --git a/VERSION b/VERSION
index 5cb7d85..347caf3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-13.0.1
+13.0.2

commit 02fd5a19b7be6fe849b39e36d3b6e5f609927d2f
Author: Dave Airlie <airlied@redhat.com>
Date:   Mon Nov 28 07:03:11 2016 +0000

    radv: fix 3D clears with baseMiplevel
    
    This fixes:
    dEQP-VK.api.image_clearing.clear_color_image.3d*
    
    These were hitting an assert as the code wasn't taking the
    baseMipLevel into account when minify the image depth.
    
    Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    Cc: "13.0" <mesa-stable@lists.freedesktop.org>
    (cherry picked from commit 09c0c17bc3609a5f5d3ba1df26820406ff5449bf)

diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c
index 7e3e5f4..a347703 100644
--- a/src/amd/vulkan/radv_meta_clear.c
+++ b/src/amd/vulkan/radv_meta_clear.c
@@ -998,7 +998,7 @@ radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer,
 		const VkImageSubresourceRange *range = &ranges[r];
 		for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) {
 			const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ?
-				radv_minify(image->extent.depth, l) :
+				radv_minify(image->extent.depth, range->baseMipLevel + l) :
 				radv_get_layerCount(image, range);
 			for (uint32_t s = 0; s < layer_count; ++s) {
 				struct radv_image_view iview;

commit 87b76f0e058658ffe122b97e8dc7e7dc19d49265
Author: Dave Airlie <airlied@redhat.com>
Date:   Tue Oct 25 07:47:13 2016 +1000

    radv/ac/llvm: shadow samplers only return one value.
    
    The intrinsic engine asserts in llvm due to this.
    
    Reported-by: Christoph Haag <haagch+mesadev@frickel.club>
    Cc: "13.0" <mesa-stable@lists.freedesktop.org>
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    (cherry picked from commit b56b54cbf1d8e70c87a434da5350d11533e5fed8)
    
    Squashed with commit:
    
    radv/ac/llvm: fix regression with shadow samplers fix
    
    This fixes b56b54cbf1d8e70c87a434da5350d11533e5fed8:
    radv/ac/llvm: shadow samplers only return one value
    
    It makes sure we only do that for shadow sampling, as
    opposed to sizing requests.
    
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    Cc: "13.0" <mesa-stable@lists.freedesktop.org>
    (cherry picked from commit b2e217369e1ca4bf9d7741721559a4506b1f0ce8)
    
    Squashed with commit:
    
    radv: brown-paper bag for a forgotten else.
    
    This fixes the fix:
    radv/ac/llvm: fix regression with shadow samplers fix
    
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    Cc: "13.0" <mesa-stable@lists.freedesktop.org>
    (cherry picked from commit 020978af12ef6d598bc5efeae3704c0eb8cdafd2)

diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 799eb34..0daef08 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -3545,6 +3545,8 @@ static void visit_tex(struct nir_to_llvm_context *ctx, nir_tex_instr *instr)
 
 	if (instr->op == nir_texop_query_levels)
 		result = LLVMBuildExtractElement(ctx->builder, result, LLVMConstInt(ctx->i32, 3, false), "");
+	else if (instr->is_shadow && instr->op != nir_texop_txs && instr->op != nir_texop_lod)
+		result = LLVMBuildExtractElement(ctx->builder, result, ctx->i32zero, "");
 	else if (instr->op == nir_texop_txs &&
 		 instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE &&
 		 instr->is_array) {

commit 17dee709a9b8ac358374d26c1f4efe5c7b09f5bd
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Nov 24 10:04:35 2016 +1000

    radv/si: fix optimal micro tile selection
    
    The same fix was posted for radeonsi, so port it here.
    
    Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net>
    Cc: "13.0" <mesa-stable@lists.freedesktop.org>
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    (cherry picked from commit 9838db8f643354e485f74664b92b902fe0b95c4f)

diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c
index 3099d83..9649158 100644
--- a/src/amd/vulkan/radv_image.c
+++ b/src/amd/vulkan/radv_image.c
@@ -831,29 +831,29 @@ void radv_image_set_optimal_micro_tile_mode(struct radv_device *device,
 		switch (micro_tile_mode) {
 		case 0: /* displayable */
 			switch (image->surface.bpe) {
-			case 8:
+			case 1:
                             image->surface.tiling_index[0] = 10;
                             break;
-			case 16:
+			case 2:
                             image->surface.tiling_index[0] = 11;
                             break;
-			default: /* 32, 64 */
+			default: /* 4, 8 */
                             image->surface.tiling_index[0] = 12;
                             break;
 			}
 			break;
 		case 1: /* thin */
 			switch (image->surface.bpe) {
-			case 8:
+			case 1:
                                 image->surface.tiling_index[0] = 14;
                                 break;
-			case 16:
+			case 2:
                                 image->surface.tiling_index[0] = 15;
                                 break;
-			case 32:
+			case 4:
                                 image->surface.tiling_index[0] = 16;
                                 break;
-			default: /* 64, 128 */
+			default: /* 8, 16 */
                                 image->surface.tiling_index[0] = 17;
                                 break;
 			}

commit d653c84a688d65b8b421c08fdbea6b22878a364d
Author: Emil Velikov <emil.velikov@collabora.com>
Date:   Thu Nov 24 18:14:58 2016 +0000

    radv: honour the number of properties available
    
    Cap up-to the number of properties available while copying the data.
    Otherwise we might crash and/or leak data.
    
    Cc: Dave Airlie <airlied@redhat.com>
    Cc: "13.0" <mesa-stable@lists.freedesktop.org>
    Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
    Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    (cherry picked from commit a025c5b2c7c9c6862006b13c9b8ab46c3acf8e53)

diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 4a924ea..94a2ef0 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -659,17 +659,15 @@ VkResult radv_EnumerateInstanceExtensionProperties(
 	uint32_t*                                   pPropertyCount,
 	VkExtensionProperties*                      pProperties)
 {
-	unsigned i;
 	if (pProperties == NULL) {
 		*pPropertyCount = ARRAY_SIZE(global_extensions);
 		return VK_SUCCESS;
 	}
 
-	for (i = 0; i < *pPropertyCount; i++)
-		memcpy(&pProperties[i], &global_extensions[i], sizeof(VkExtensionProperties));
+	*pPropertyCount = MIN2(*pPropertyCount, ARRAY_SIZE(global_extensions));
+	typed_memcpy(pProperties, global_extensions, *pPropertyCount);
 
-	*pPropertyCount = i;
-	if (i < ARRAY_SIZE(global_extensions))
+	if (*pPropertyCount < ARRAY_SIZE(global_extensions))
 		return VK_INCOMPLETE;
 
 	return VK_SUCCESS;
@@ -681,19 +679,17 @@ VkResult radv_EnumerateDeviceExtensionProperties(
 	uint32_t*                                   pPropertyCount,
 	VkExtensionProperties*                      pProperties)
 {
-	unsigned i;
-
 	if (pProperties == NULL) {
 		*pPropertyCount = ARRAY_SIZE(device_extensions);
 		return VK_SUCCESS;
 	}
 
-	for (i = 0; i < *pPropertyCount; i++)
-		memcpy(&pProperties[i], &device_extensions[i], sizeof(VkExtensionProperties));
+	*pPropertyCount = MIN2(*pPropertyCount, ARRAY_SIZE(device_extensions));
+	typed_memcpy(pProperties, device_extensions, *pPropertyCount);
 
-	*pPropertyCount = i;
-	if (i < ARRAY_SIZE(device_extensions))
+	if (*pPropertyCount < ARRAY_SIZE(device_extensions))
 		return VK_INCOMPLETE;
+
 	return VK_SUCCESS;
 }
 

commit 960a87fb174290f36ce0434a631b879d01397589
Author: Dave Airlie <airlied@redhat.com>
Date:   Thu Nov 24 03:10:52 2016 +0000

    radv: fix texel fetch offset with 2d arrays.
    
    The code didn't limit the offsets to the number supplied, so
    if we expected 3 but only got 2 we were accessing undefined memory.
    
    This fixes random failures in:
    dEQP-VK.glsl.texture_functions.texelfetchoffset.sampler2darray_*
    
    Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
    Cc: "13.0" <mesa-stable@lists.freedesktop.org>
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    (cherry picked from commit bb8ac183404541ca8dee31563709d5aca8de0e73)

diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 31d7b6e..799eb34 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -3517,12 +3517,13 @@ static void visit_tex(struct nir_to_llvm_context *ctx, nir_tex_instr *instr)
 	if (offsets && instr->op == nir_texop_txf) {
 		nir_const_value *const_offset =
 			nir_src_as_const_value(instr->src[const_src].src);
-
+		int num_offsets = instr->src[const_src].src.ssa->num_components;
 		assert(const_offset);
-		if (instr->coord_components > 2)
+		num_offsets = MIN2(num_offsets, instr->coord_components);
+		if (num_offsets > 2)
 			address[2] = LLVMBuildAdd(ctx->builder,
 						  address[2], LLVMConstInt(ctx->i32, const_offset->i32[2], false), "");
-		if (instr->coord_components > 1)
+		if (num_offsets > 1)
 			address[1] = LLVMBuildAdd(ctx->builder,
 						  address[1], LLVMConstInt(ctx->i32, const_offset->i32[1], false), "");
 		address[0] = LLVMBuildAdd(ctx->builder,

commit aa939d7d2a16ea3ea2da785859b96bfacf9d62d9
Author: Jason Ekstrand <jason.ekstrand@intel.com>
Date:   Thu Nov 3 16:59:08 2016 -0700

    vulkan/wsi/x11: Implement FIFO mode.
    
    This implements VK_PRESENT_MODE_FIFO_KHR for X11.  Unfortunately, due to
    the way the present extension works, we have to manage the queue of
    presented images in a separate thread.
    
    Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
    Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
    Reviewed-by: Dave Airlie <airlied@redhat.com>
    Cc: "13.0" <mesa-stable@lists.freedesktop.org>
    (cherry picked from commit e73d136a02308088cacab842790c7670e5d07b23)

diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 75eab6c..8e0043f 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -39,6 +39,7 @@
 
 #include "wsi_common.h"
 #include "wsi_common_x11.h"
+#include "wsi_common_queue.h"
 
 #define typed_memcpy(dest, src, count) ({ \
    static_assert(sizeof(*src) == sizeof(*dest), ""); \
@@ -145,6 +146,7 @@ static const VkSurfaceFormatKHR formats[] = {
 static const VkPresentModeKHR present_modes[] = {
    VK_PRESENT_MODE_IMMEDIATE_KHR,
    VK_PRESENT_MODE_MAILBOX_KHR,
+   VK_PRESENT_MODE_FIFO_KHR,
 };
 
 static xcb_screen_t *
@@ -490,8 +492,15 @@ struct x11_swapchain {
    xcb_present_event_t                          event_id;
    xcb_special_event_t *                        special_event;
    uint64_t                                     send_sbc;
+   uint64_t                                     last_present_msc;
    uint32_t                                     stamp;
 
+   bool                                         threaded;
+   VkResult                                     status;
+   struct wsi_queue                             present_queue;
+   struct wsi_queue                             acquire_queue;
+   pthread_t                                    queue_manager;
+
    struct x11_image                             images[0];
 };
 
@@ -542,6 +551,8 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain,
       for (unsigned i = 0; i < chain->image_count; i++) {
          if (chain->images[i].pixmap == idle->pixmap) {
             chain->images[i].busy = false;
+            if (chain->threaded)
+               wsi_queue_push(&chain->acquire_queue, i);
             break;
          }
       }
@@ -549,7 +560,13 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain,
       break;
    }
 
-   case XCB_PRESENT_COMPLETE_NOTIFY:
+   case XCB_PRESENT_EVENT_COMPLETE_NOTIFY: {
+      xcb_present_complete_notify_event_t *complete = (void *) event;
+      if (complete->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP)
+         chain->last_present_msc = complete->msc;
+      break;
+   }
+
    default:
       break;
    }
@@ -578,12 +595,9 @@ static uint64_t wsi_get_absolute_timeout(uint64_t timeout)
 }
 
 static VkResult
-x11_acquire_next_image(struct wsi_swapchain *anv_chain,
-                       uint64_t timeout,
-                       VkSemaphore semaphore,
-                       uint32_t *image_index)
+x11_acquire_next_image_poll_x11(struct x11_swapchain *chain,
+                                uint32_t *image_index, uint64_t timeout)
 {
-   struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
    xcb_generic_event_t *event;
    struct pollfd pfds;
    uint64_t atimeout;
@@ -641,17 +655,38 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain,
 }
 
 static VkResult
-x11_queue_present(struct wsi_swapchain *anv_chain,
-                  uint32_t image_index)
+x11_acquire_next_image_from_queue(struct x11_swapchain *chain,
+                                  uint32_t *image_index_out, uint64_t timeout)
+{
+   assert(chain->threaded);
+
+   uint32_t image_index;
+   VkResult result = wsi_queue_pull(&chain->acquire_queue,
+                                    &image_index, timeout);
+   if (result != VK_SUCCESS) {
+      return result;
+   } else if (chain->status != VK_SUCCESS) {
+      return chain->status;
+   }
+
+   assert(image_index < chain->image_count);
+   xshmfence_await(chain->images[image_index].shm_fence);
+
+   *image_index_out = image_index;
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+x11_present_to_x11(struct x11_swapchain *chain, uint32_t image_index,
+                   uint32_t target_msc)
 {
-   struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
    struct x11_image *image = &chain->images[image_index];
 
    assert(image_index < chain->image_count);
 
    uint32_t options = XCB_PRESENT_OPTION_NONE;
 
-   int64_t target_msc = 0;
    int64_t divisor = 0;
    int64_t remainder = 0;
 
@@ -686,6 +721,82 @@ x11_queue_present(struct wsi_swapchain *anv_chain,
 }
 
 static VkResult
+x11_acquire_next_image(struct wsi_swapchain *anv_chain,
+                       uint64_t timeout,
+                       VkSemaphore semaphore,
+                       uint32_t *image_index)
+{
+   struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
+
+   if (chain->threaded) {
+      return x11_acquire_next_image_from_queue(chain, image_index, timeout);
+   } else {
+      return x11_acquire_next_image_poll_x11(chain, image_index, timeout);
+   }
+}
+
+static VkResult
+x11_queue_present(struct wsi_swapchain *anv_chain,
+                  uint32_t image_index)
+{
+   struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
+
+   if (chain->threaded) {
+      wsi_queue_push(&chain->present_queue, image_index);
+      return chain->status;
+   } else {
+      return x11_present_to_x11(chain, image_index, 0);
+   }
+}
+
+static void *
+x11_manage_fifo_queues(void *state)
+{
+   struct x11_swapchain *chain = state;
+   VkResult result;
+
+   assert(chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR);
+
+   while (chain->status == VK_SUCCESS) {
+      /* It should be safe to unconditionally block here.  Later in the loop
+       * we blocks until the previous present has landed on-screen.  At that
+       * point, we should have received IDLE_NOTIFY on all images presented
+       * before that point so the client should be able to acquire any image
+       * other than the currently presented one.
+       */
+      uint32_t image_index;
+      result = wsi_queue_pull(&chain->present_queue, &image_index, INT64_MAX);
+      if (result != VK_SUCCESS) {
+         goto fail;
+      } else if (chain->status != VK_SUCCESS) {
+         return NULL;
+      }
+
+      uint64_t target_msc = chain->last_present_msc + 1;
+      result = x11_present_to_x11(chain, image_index, target_msc);
+      if (result != VK_SUCCESS)
+         goto fail;
+
+      while (chain->last_present_msc < target_msc) {
+         xcb_generic_event_t *event =
+            xcb_wait_for_special_event(chain->conn, chain->special_event);
+         if (!event)
+            goto fail;
+
+         result = x11_handle_dri3_present_event(chain, (void *)event);
+         if (result != VK_SUCCESS)
+            goto fail;
+      }
+   }
+
+fail:
+   chain->status = result;
+   wsi_queue_push(&chain->acquire_queue, UINT32_MAX);
+
+   return NULL;
+}
+
+static VkResult
 x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
                const VkSwapchainCreateInfoKHR *pCreateInfo,
                const VkAllocationCallbacks* pAllocator,
@@ -783,6 +894,15 @@ x11_swapchain_destroy(struct wsi_swapchain *anv_chain,
    for (uint32_t i = 0; i < chain->image_count; i++)
       x11_image_finish(chain, pAllocator, &chain->images[i]);
 
+   if (chain->threaded) {
+      chain->status = VK_ERROR_OUT_OF_DATE_KHR;
+      /* Push a UINT32_MAX to wake up the manager */
+      wsi_queue_push(&chain->present_queue, UINT32_MAX);
+      pthread_join(chain->queue_manager, NULL);
+      wsi_queue_destroy(&chain->acquire_queue);
+      wsi_queue_destroy(&chain->present_queue);
+   }
+
    xcb_unregister_for_special_event(chain->conn, chain->special_event);
 
    vk_free(pAllocator, chain);
@@ -834,6 +954,9 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
    chain->extent = pCreateInfo->imageExtent;
    chain->image_count = num_images;
    chain->send_sbc = 0;
+   chain->last_present_msc = 0;
+   chain->threaded = false;
+   chain->status = VK_SUCCESS;
 
    free(geometry);
 
@@ -872,6 +995,37 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
          goto fail_init_images;
    }
 
+   if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) {
+      chain->threaded = true;
+
+      /* Initialize our queues.  We make them image_count + 1 because we will
+       * occasionally use UINT32_MAX to signal the other thread that an error
+       * has occurred and we don't want an overflow.
+       */
+      int ret;
+      ret = wsi_queue_init(&chain->acquire_queue, chain->image_count + 1);
+      if (ret) {
+         goto fail_init_images;
+      }
+
+      ret = wsi_queue_init(&chain->present_queue, chain->image_count + 1);
+      if (ret) {
+         wsi_queue_destroy(&chain->acquire_queue);
+         goto fail_init_images;
+      }
+
+      for (unsigned i = 0; i < chain->image_count; i++)
+         wsi_queue_push(&chain->acquire_queue, i);
+
+      ret = pthread_create(&chain->queue_manager, NULL,
+                           x11_manage_fifo_queues, chain);
+      if (ret) {
+         wsi_queue_destroy(&chain->present_queue);
+         wsi_queue_destroy(&chain->acquire_queue);
+         goto fail_init_images;
+      }
+   }
+
    *swapchain_out = &chain->base;
 
    return VK_SUCCESS;

commit 0aa527526c18ec630f532003eb01ae0bcf86aea3
Author: Kevin Strasser <kevin.strasser@intel.com>
Date:   Wed Nov 2 18:18:44 2016 -0700

    vulkan/wsi: Add a thread-safe queue implementation
    
    In order to support FIFO mode without blocking the application on calls
    to vkQueuePresentKHR it is necessary to enqueue the request and defer
    calling the server until the next vblank period. The xcb present api
    doesn't offer a way to register a callback, so we will have to spawn a
    worker thread that will wait for a request to be added to the queue, call
    to the server, and then make the image available for reuse.  This commit
    introduces the queue data structure needed to implement this.
    
    Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
    Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
    Reviewed-by: Dave Airlie <airlied@redhat.com>
    Cc: "13.0" <mesa-stable@lists.freedesktop.org>
    (cherry picked from commit 932bb3f0ddf22a9cbdf6d45089547765027b4397)

diff --git a/src/vulkan/wsi/Makefile.sources b/src/vulkan/wsi/Makefile.sources
index 3139e6d..50660f9 100644
--- a/src/vulkan/wsi/Makefile.sources
+++ b/src/vulkan/wsi/Makefile.sources
@@ -1,6 +1,7 @@
 
 VULKAN_WSI_FILES := \
-	wsi_common.h
+	wsi_common.h \
+	wsi_common_queue.h
 
 VULKAN_WSI_WAYLAND_FILES := \
 	wsi_common_wayland.c \
diff --git a/src/vulkan/wsi/wsi_common_queue.h b/src/vulkan/wsi/wsi_common_queue.h
new file mode 100644
index 0000000..0e72c8d
--- /dev/null
+++ b/src/vulkan/wsi/wsi_common_queue.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef VULKAN_WSI_COMMON_QUEUE_H
+#define VULKAN_WSI_COMMON_QUEUE_H
+
+#include <time.h>
+#include <pthread.h>
+#include "util/u_vector.h"
+
+struct wsi_queue {
+   struct u_vector vector;
+   pthread_mutex_t mutex;
+   pthread_cond_t cond;
+};
+
+static inline int
+wsi_queue_init(struct wsi_queue *queue, int length)
+{
+   int ret;
+
+   uint32_t length_pow2 = 4;
+   while (length_pow2 < length)
+      length_pow2 *= 2;
+
+   ret = u_vector_init(&queue->vector, sizeof(uint32_t),
+                       sizeof(uint32_t) * length_pow2);
+   if (!ret)
+      return ENOMEM;
+
+   pthread_condattr_t condattr;
+   ret = pthread_condattr_init(&condattr);
+   if (ret)
+      goto fail_vector;
+
+   ret = pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
+   if (ret)
+      goto fail_condattr;
+
+   ret = pthread_cond_init(&queue->cond, &condattr);
+   if (ret)
+      goto fail_condattr;
+
+   ret = pthread_mutex_init(&queue->mutex, NULL);
+   if (ret)
+      goto fail_cond;
+
+   return 0;
+
+fail_cond:
+   pthread_cond_destroy(&queue->cond);
+fail_condattr:
+   pthread_condattr_destroy(&condattr);
+fail_vector:
+   u_vector_finish(&queue->vector);
+
+   return ret;
+}
+
+static inline void
+wsi_queue_destroy(struct wsi_queue *queue)
+{
+   u_vector_finish(&queue->vector);
+   pthread_mutex_destroy(&queue->mutex);
+   pthread_cond_destroy(&queue->cond);
+}
+
+static inline void
+wsi_queue_push(struct wsi_queue *queue, uint32_t index)
+{
+   uint32_t *elem;
+
+   pthread_mutex_lock(&queue->mutex);
+
+   if (u_vector_length(&queue->vector) == 0)
+      pthread_cond_signal(&queue->cond);
+
+   elem = u_vector_add(&queue->vector);
+   *elem = index;
+
+   pthread_mutex_unlock(&queue->mutex);
+}
+
+#define NSEC_PER_SEC 1000000000
+#define INT_TYPE_MAX(type) ((1ull << (sizeof(type) * 8 - 1)) - 1)
+
+static inline VkResult
+wsi_queue_pull(struct wsi_queue *queue, uint32_t *index, uint64_t timeout)
+{
+   VkResult result;
+   int32_t ret;
+
+   pthread_mutex_lock(&queue->mutex);
+
+   struct timespec now;
+   clock_gettime(CLOCK_MONOTONIC, &now);
+
+   uint32_t abs_nsec = now.tv_nsec + timeout % NSEC_PER_SEC;
+   uint64_t abs_sec = now.tv_sec + (abs_nsec / NSEC_PER_SEC) +
+                      (timeout / NSEC_PER_SEC);
+   abs_nsec %= NSEC_PER_SEC;
+
+   /* Avoid roll-over in tv_sec on 32-bit systems if the user provided timeout
+    * is UINT64_MAX
+    */
+   struct timespec abstime;
+   abstime.tv_nsec = abs_nsec;
+   abstime.tv_sec = MIN2(abs_sec, INT_TYPE_MAX(abstime.tv_sec));
+
+   while (u_vector_length(&queue->vector) == 0) {
+      ret = pthread_cond_timedwait(&queue->cond, &queue->mutex, &abstime);
+      if (ret == 0) {
+         continue;
+      } else if (ret == ETIMEDOUT) {
+         result = VK_TIMEOUT;
+         goto end;
+      } else {
+         /* Something went badly wrong */
+         result = VK_ERROR_OUT_OF_DATE_KHR;
+         goto end;
+      }
+   }
+
+   uint32_t *elem = u_vector_remove(&queue->vector);
+   *index = *elem;
+   result = VK_SUCCESS;
+
+end:
+   pthread_mutex_unlock(&queue->mutex);
+
+   return result;
+}
+
+#endif /* VULKAN_WSI_COMMON_QUEUE_H */


Reply to: