{"id":1006,"date":"2018-05-07T10:39:54","date_gmt":"2018-05-07T08:39:54","guid":{"rendered":"https:\/\/blogs.igalia.com\/itoral\/?p=1006"},"modified":"2018-05-07T10:39:54","modified_gmt":"2018-05-07T08:39:54","slug":"intel-mesa-vulkan-driver-now-supports-shaderint16","status":"publish","type":"post","link":"https:\/\/blogs.igalia.com\/itoral\/2018\/05\/07\/intel-mesa-vulkan-driver-now-supports-shaderint16\/","title":{"rendered":"Intel Mesa Vulkan driver now supports shaderInt16"},"content":{"rendered":"<p>The Vulkan specification includes a number of <em>optional<\/em> features that drivers may or may not support, as described in <a href=\"https:\/\/www.khronos.org\/registry\/vulkan\/specs\/1.1\/html\/vkspec.html#features-features\">chapter 30.1 Features<\/a>. Application developers can query the driver for supported features via <em>vkGetPhysicalDeviceFeatures()<\/em> and then activate the subset they need in the <em>pEnabledFeatures<\/em> field of the <em>VkDeviceCreateInfo<\/em> structure passed at device creation time.<\/p>\n<p>In the last few weeks I have been spending some time, together with my colleague Chema, adding support for one of these features in <em>Anvil<\/em>, the Intel Vulkan driver in Mesa, called <strong>shaderInt16<\/strong>, which we landed in Mesa master last week. This is an <strong>optional feature available since Vulkan 1.0<\/strong>. From the spec:<\/p>\n<blockquote><p>\n  <em>shaderInt16<\/em> specifies whether 16-bit integers (signed and unsigned) are supported in shader code. If this feature is not enabled, 16-bit integer types must not be used in shader code. This also specifies whether shader modules can declare the Int16 capability.\n<\/p><\/blockquote>\n<p>It is probably relevant to highlight that this Vulkan capability also requires the <strong>SPIR-V Int16 capability<\/strong>, which basically means that the driver&#8217;s SPIR-V compiler backend can actually digest SPIR-V shaders that declare and use 16-bit integers, and which is really the core of the functionality exposed by the Vulkan feature.<\/p>\n<p>Ideally,  <em>shaderInt16<\/em> would <strong>increase the overall throughput of integer operations<\/strong> in shaders, leading to better performance when you don&#8217;t need a full 32-bit range. It may also provide <strong>better overall register usage<\/strong> since you need less register space to store your integer data during shader execution. It is important to remark, however, that not all hardware platforms (Intel or otherwise) may have native support for all possible types of 16-bit operations, and thus, some of them might still need to run in 32-bit (which requires injecting type conversion instructions in the shader code). For Intel platforms, this is the case for operations associated with integer division.<\/p>\n<p>From the point of view of the driver, this is the first time that we generally exercise lower bit-size data types in the driver compiler backend, so if you find any bugs in the implementation, please file bug reports in <a href=\"https:\/\/bugs.freedesktop.org\/\">bugzilla<\/a>!<\/p>\n<p>Speaking of <em>shaderInt16<\/em>, I think it is worth mentioning its interactions with other Vulkan functionality that we implemented in the past: the Vulkan 1.0 <strong>VK_KHR_16bit_storage<\/strong> extension (which has been promoted to core in Vulkan 1.1). From the spec:<\/p>\n<blockquote><p>\n  The <em>VK_KHR_16bit_storage<\/em> extension allows use of 16-bit types in shader input and output interfaces, and push constant blocks. This extension introduces several new optional features which map to SPIR-V capabilities and allow access to 16-bit data in Block-decorated objects in the Uniform and the StorageBuffer storage classes, and objects in the PushConstant storage class. This extension allows 16-bit variables to be declared and used as user-defined shader inputs and outputs but does not change location assignment and component assignment rules.\n<\/p><\/blockquote>\n<p>While the <em>shaderInt16<\/em> capability provides the means to operate with 16-bit integers inside a shader, the <em>VK_KHR_16bit_storage<\/em> extension provides developers with the means to also feed shaders with 16-bit integer (and also floating point) input data, such as Uniform\/Storage Buffer Objects or Push Constants, from the applications side, plus, it also gives the opportunity for linked shader stages in a graphics pipeline to consume 16-bit shader inputs and produce 16-bit shader outputs.<\/p>\n<p><em>VK_KHR_16bit_storage<\/em> and <em>shaderInt16<\/em> should be seen as two parts of a whole, each one addressing one part of a larger problem: <em>VK_KHR_16bit_storage<\/em> can help reduce memory bandwith for Uniform and Storage  Buffer data accessed from the shaders and \/ or optimize Push Constant space, of which there are only a few bytes available, making it a precious shader resource, but without <em>shaderInt16<\/em>, shaders that are fed 16-bit input data are still required to convert this data to 32-bit internally for operation (and then back again to 16-bit for output if needed). Likewise, shaders that use <em>shaderInt16<\/em> without <em>VK_KHR_16bit_storage<\/em> can only operate with 16-bit data that is generated inside the shader, which largely limits its usage. Both together, however, give you the complete functionality.<\/p>\n<h1>Conclusions<\/h1>\n<p>We are very happy to continue expanding the feature set supported in Anvil and we look forward to seeing application developers making good use of <strong>shaderInt16<\/strong> in Vulkan to improve shader performance. As noted above, this is the first time that we fully enable the shader compiler backend to do general purpose operations on lower bit-size data types and there might be things that we can still improve or optimize. If you hit any issues with the implementation, please contact us and \/ or file bug reports so we can continue to improve the implementation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Vulkan specification includes a number of optional features that drivers may or may not support, as described in chapter 30.1 Features. Application developers can query the driver for supported features via vkGetPhysicalDeviceFeatures() and then activate the subset they need in the pEnabledFeatures field of the VkDeviceCreateInfo structure passed at device creation time. In the &hellip; <a href=\"https:\/\/blogs.igalia.com\/itoral\/2018\/05\/07\/intel-mesa-vulkan-driver-now-supports-shaderint16\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Intel Mesa Vulkan driver now supports shaderInt16&#8221;<\/span><\/a><\/p>\n","protected":false},"author":16,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-1006","post","type-post","status-publish","format-standard","hentry","category-graphics"],"_links":{"self":[{"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/posts\/1006","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/comments?post=1006"}],"version-history":[{"count":2,"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/posts\/1006\/revisions"}],"predecessor-version":[{"id":1008,"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/posts\/1006\/revisions\/1008"}],"wp:attachment":[{"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/media?parent=1006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/categories?post=1006"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.igalia.com\/itoral\/wp-json\/wp\/v2\/tags?post=1006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}