Check shm extension is supported before using it

If shm extension is not supported (for example by connecting to a remote X11 server), the xcb_shm_query_version call set an error in connection (error 2, XCB_CONN_CLOSED_EXT_NOTSUPPORTED), making it unusable for other calls.

Bug: swiftshader:169
Change-Id: Iaeac93208913b8f1407664fa4c913add4a943683
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/61928
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Peng Huang <penghuang@chromium.org>
Tested-by: Thomas Laroche <tho.laroche@gmail.com>
Commit-Queue: Thomas Laroche <tho.laroche@gmail.com>
diff --git a/src/WSI/XcbSurfaceKHR.cpp b/src/WSI/XcbSurfaceKHR.cpp
index ab55f66..1a4102a 100644
--- a/src/WSI/XcbSurfaceKHR.cpp
+++ b/src/WSI/XcbSurfaceKHR.cpp
@@ -54,16 +54,19 @@
 	uint32_t values[2] = { 0, 0xffffffff };
 	libXCB->xcb_create_gc(connection, gc, window, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND, values);
 
-	auto shmCookie = libXCB->xcb_shm_query_version(connection);
-	auto geomCookie = libXCB->xcb_get_geometry(connection, window);
-
-	if (auto *reply = libXCB->xcb_shm_query_version_reply(connection, shmCookie, nullptr))
+	auto shmQuery = libXCB->xcb_get_extension_data(connection, libXCB->xcb_shm_id);
+	if(shmQuery->present)
 	{
-		mitSHM = reply && reply->shared_pixmaps;
-		free(reply);
+		auto shmCookie = libXCB->xcb_shm_query_version(connection);
+		if(auto *reply = libXCB->xcb_shm_query_version_reply(connection, shmCookie, nullptr))
+		{
+			mitSHM = reply && reply->shared_pixmaps;
+			free(reply);
+		}
 	}
 
-	if (auto *reply = libXCB->xcb_get_geometry_reply(connection, geomCookie, nullptr))
+	auto geomCookie = libXCB->xcb_get_geometry(connection, window);
+	if(auto *reply = libXCB->xcb_get_geometry_reply(connection, geomCookie, nullptr))
 	{
 		windowDepth = reply->depth;
 		free(reply);
diff --git a/src/WSI/libXCB.cpp b/src/WSI/libXCB.cpp
index e94da9e..60be41e 100644
--- a/src/WSI/libXCB.cpp
+++ b/src/WSI/libXCB.cpp
@@ -29,12 +29,14 @@
 	getFuncAddress(libxcb, "xcb_put_image", &xcb_put_image);
 	getFuncAddress(libxcb, "xcb_copy_area", &xcb_copy_area);
 	getFuncAddress(libxcb, "xcb_free_pixmap", &xcb_free_pixmap);
+	getFuncAddress(libxcb, "xcb_get_extension_data", &xcb_get_extension_data);
 
 	getFuncAddress(libshm, "xcb_shm_query_version", &xcb_shm_query_version);
 	getFuncAddress(libshm, "xcb_shm_query_version_reply", &xcb_shm_query_version_reply);
 	getFuncAddress(libshm, "xcb_shm_attach", &xcb_shm_attach);
 	getFuncAddress(libshm, "xcb_shm_detach", &xcb_shm_detach);
 	getFuncAddress(libshm, "xcb_shm_create_pixmap", &xcb_shm_create_pixmap);
+	xcb_shm_id = (xcb_extension_t *)getProcAddress(libshm, "xcb_shm_id");
 }
 
 LibXcbExports *LibXCB::operator->()
diff --git a/src/WSI/libXCB.hpp b/src/WSI/libXCB.hpp
index 3369299..50a943c 100644
--- a/src/WSI/libXCB.hpp
+++ b/src/WSI/libXCB.hpp
@@ -32,12 +32,14 @@
 	xcb_void_cookie_t (*xcb_put_image)(xcb_connection_t *c, uint8_t format, xcb_drawable_t drawable, xcb_gcontext_t gc, uint16_t width, uint16_t height, int16_t dst_x, int16_t dst_y, uint8_t left_pad, uint8_t depth, uint32_t data_len, const uint8_t *data) = nullptr;
 	xcb_void_cookie_t (*xcb_copy_area)(xcb_connection_t *conn, xcb_drawable_t src_drawable, xcb_drawable_t dst_drawable, xcb_gcontext_t gc, int16_t src_x, int16_t src_y, int16_t dst_x, int16_t dst_y, uint16_t width, uint16_t height);
 	xcb_void_cookie_t (*xcb_free_pixmap)(xcb_connection_t *conn, xcb_pixmap_t pixmap);
+	xcb_query_extension_reply_t *(*xcb_get_extension_data)(xcb_connection_t *c, xcb_extension_t *extension) = nullptr;
 
 	xcb_shm_query_version_cookie_t 	(*xcb_shm_query_version)(xcb_connection_t *c);
 	xcb_shm_query_version_reply_t *(*xcb_shm_query_version_reply)(xcb_connection_t *c, xcb_shm_query_version_cookie_t cookie, xcb_generic_error_t **e);
 	xcb_void_cookie_t (*xcb_shm_attach)(xcb_connection_t *c, xcb_shm_seg_t shmseg, uint32_t shmid, uint8_t read_only);
 	xcb_void_cookie_t (*xcb_shm_detach)(xcb_connection_t * 	c, xcb_shm_seg_t shmseg);
 	xcb_void_cookie_t (*xcb_shm_create_pixmap)(xcb_connection_t *c, xcb_pixmap_t pid, xcb_drawable_t drawable, uint16_t width, uint16_t height, uint8_t depth, xcb_shm_seg_t shmseg, uint32_t offset);
+	xcb_extension_t *xcb_shm_id;
 };
 
 class LibXCB