xref: /aosp_15_r20/external/mesa3d/src/imagination/vulkan/pvr_device.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2022 Imagination Technologies Ltd.
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * based in part on anv driver which is:
5*61046927SAndroid Build Coastguard Worker  * Copyright © 2015 Intel Corporation
6*61046927SAndroid Build Coastguard Worker  *
7*61046927SAndroid Build Coastguard Worker  * based in part on v3dv driver which is:
8*61046927SAndroid Build Coastguard Worker  * Copyright © 2019 Raspberry Pi
9*61046927SAndroid Build Coastguard Worker  *
10*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
11*61046927SAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to deal
12*61046927SAndroid Build Coastguard Worker  * in the Software without restriction, including without limitation the rights
13*61046927SAndroid Build Coastguard Worker  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14*61046927SAndroid Build Coastguard Worker  * copies of the Software, and to permit persons to whom the Software is
15*61046927SAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
16*61046927SAndroid Build Coastguard Worker  *
17*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
18*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
19*61046927SAndroid Build Coastguard Worker  * Software.
20*61046927SAndroid Build Coastguard Worker  *
21*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24*61046927SAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26*61046927SAndroid Build Coastguard Worker  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27*61046927SAndroid Build Coastguard Worker  * SOFTWARE.
28*61046927SAndroid Build Coastguard Worker  */
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker #include <assert.h>
31*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
32*61046927SAndroid Build Coastguard Worker #include <inttypes.h>
33*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
34*61046927SAndroid Build Coastguard Worker #include <stddef.h>
35*61046927SAndroid Build Coastguard Worker #include <stdint.h>
36*61046927SAndroid Build Coastguard Worker #include <stdio.h>
37*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
38*61046927SAndroid Build Coastguard Worker #include <string.h>
39*61046927SAndroid Build Coastguard Worker #include <vulkan/vulkan.h>
40*61046927SAndroid Build Coastguard Worker #include <xf86drm.h>
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker #include "git_sha1.h"
43*61046927SAndroid Build Coastguard Worker #include "hwdef/rogue_hw_utils.h"
44*61046927SAndroid Build Coastguard Worker #include "pvr_bo.h"
45*61046927SAndroid Build Coastguard Worker #include "pvr_border.h"
46*61046927SAndroid Build Coastguard Worker #include "pvr_clear.h"
47*61046927SAndroid Build Coastguard Worker #include "pvr_csb.h"
48*61046927SAndroid Build Coastguard Worker #include "pvr_csb_enum_helpers.h"
49*61046927SAndroid Build Coastguard Worker #include "pvr_debug.h"
50*61046927SAndroid Build Coastguard Worker #include "pvr_device_info.h"
51*61046927SAndroid Build Coastguard Worker #include "pvr_dump_info.h"
52*61046927SAndroid Build Coastguard Worker #include "pvr_hardcode.h"
53*61046927SAndroid Build Coastguard Worker #include "pvr_job_render.h"
54*61046927SAndroid Build Coastguard Worker #include "pvr_limits.h"
55*61046927SAndroid Build Coastguard Worker #include "pvr_pds.h"
56*61046927SAndroid Build Coastguard Worker #include "pvr_private.h"
57*61046927SAndroid Build Coastguard Worker #include "pvr_robustness.h"
58*61046927SAndroid Build Coastguard Worker #include "pvr_tex_state.h"
59*61046927SAndroid Build Coastguard Worker #include "pvr_types.h"
60*61046927SAndroid Build Coastguard Worker #include "pvr_uscgen.h"
61*61046927SAndroid Build Coastguard Worker #include "pvr_util.h"
62*61046927SAndroid Build Coastguard Worker #include "pvr_winsys.h"
63*61046927SAndroid Build Coastguard Worker #include "rogue/rogue.h"
64*61046927SAndroid Build Coastguard Worker #include "util/build_id.h"
65*61046927SAndroid Build Coastguard Worker #include "util/log.h"
66*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
67*61046927SAndroid Build Coastguard Worker #include "util/mesa-sha1.h"
68*61046927SAndroid Build Coastguard Worker #include "util/os_misc.h"
69*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
70*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
71*61046927SAndroid Build Coastguard Worker #include "vk_alloc.h"
72*61046927SAndroid Build Coastguard Worker #include "vk_extensions.h"
73*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
74*61046927SAndroid Build Coastguard Worker #include "vk_object.h"
75*61046927SAndroid Build Coastguard Worker #include "vk_physical_device_features.h"
76*61046927SAndroid Build Coastguard Worker #include "vk_physical_device_properties.h"
77*61046927SAndroid Build Coastguard Worker #include "vk_sampler.h"
78*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker #define PVR_GLOBAL_FREE_LIST_INITIAL_SIZE (2U * 1024U * 1024U)
81*61046927SAndroid Build Coastguard Worker #define PVR_GLOBAL_FREE_LIST_MAX_SIZE (256U * 1024U * 1024U)
82*61046927SAndroid Build Coastguard Worker #define PVR_GLOBAL_FREE_LIST_GROW_SIZE (1U * 1024U * 1024U)
83*61046927SAndroid Build Coastguard Worker 
84*61046927SAndroid Build Coastguard Worker /* After PVR_SECONDARY_DEVICE_THRESHOLD devices per instance are created,
85*61046927SAndroid Build Coastguard Worker  * devices will have a smaller global free list size, as usually this use-case
86*61046927SAndroid Build Coastguard Worker  * implies smaller amounts of work spread out. The free list can still grow as
87*61046927SAndroid Build Coastguard Worker  * required.
88*61046927SAndroid Build Coastguard Worker  */
89*61046927SAndroid Build Coastguard Worker #define PVR_SECONDARY_DEVICE_THRESHOLD (4U)
90*61046927SAndroid Build Coastguard Worker #define PVR_SECONDARY_DEVICE_FREE_LIST_INITAL_SIZE (512U * 1024U)
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker /* The grow threshold is a percentage. This is intended to be 12.5%, but has
93*61046927SAndroid Build Coastguard Worker  * been rounded up since the percentage is treated as an integer.
94*61046927SAndroid Build Coastguard Worker  */
95*61046927SAndroid Build Coastguard Worker #define PVR_GLOBAL_FREE_LIST_GROW_THRESHOLD 13U
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker #if defined(VK_USE_PLATFORM_DISPLAY_KHR)
98*61046927SAndroid Build Coastguard Worker #   define PVR_USE_WSI_PLATFORM_DISPLAY true
99*61046927SAndroid Build Coastguard Worker #else
100*61046927SAndroid Build Coastguard Worker #   define PVR_USE_WSI_PLATFORM_DISPLAY false
101*61046927SAndroid Build Coastguard Worker #endif
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker #if PVR_USE_WSI_PLATFORM_DISPLAY
104*61046927SAndroid Build Coastguard Worker #   define PVR_USE_WSI_PLATFORM true
105*61046927SAndroid Build Coastguard Worker #else
106*61046927SAndroid Build Coastguard Worker #   define PVR_USE_WSI_PLATFORM false
107*61046927SAndroid Build Coastguard Worker #endif
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker #define PVR_API_VERSION VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION)
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker /* Amount of padding required for VkBuffers to ensure we don't read beyond
112*61046927SAndroid Build Coastguard Worker  * a page boundary.
113*61046927SAndroid Build Coastguard Worker  */
114*61046927SAndroid Build Coastguard Worker #define PVR_BUFFER_MEMORY_PADDING_SIZE 4
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker /* Default size in bytes used by pvr_CreateDevice() for setting up the
117*61046927SAndroid Build Coastguard Worker  * suballoc_general, suballoc_pds and suballoc_usc suballocators.
118*61046927SAndroid Build Coastguard Worker  *
119*61046927SAndroid Build Coastguard Worker  * TODO: Investigate if a different default size can improve the overall
120*61046927SAndroid Build Coastguard Worker  * performance of internal driver allocations.
121*61046927SAndroid Build Coastguard Worker  */
122*61046927SAndroid Build Coastguard Worker #define PVR_SUBALLOCATOR_GENERAL_SIZE (128 * 1024)
123*61046927SAndroid Build Coastguard Worker #define PVR_SUBALLOCATOR_PDS_SIZE (128 * 1024)
124*61046927SAndroid Build Coastguard Worker #define PVR_SUBALLOCATOR_TRANSFER_SIZE (128 * 1024)
125*61046927SAndroid Build Coastguard Worker #define PVR_SUBALLOCATOR_USC_SIZE (128 * 1024)
126*61046927SAndroid Build Coastguard Worker #define PVR_SUBALLOCATOR_VIS_TEST_SIZE (128 * 1024)
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker struct pvr_drm_device_config {
129*61046927SAndroid Build Coastguard Worker    struct pvr_drm_device_info {
130*61046927SAndroid Build Coastguard Worker       const char *name;
131*61046927SAndroid Build Coastguard Worker       size_t len;
132*61046927SAndroid Build Coastguard Worker    } render, display;
133*61046927SAndroid Build Coastguard Worker };
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker #define DEF_CONFIG(render_, display_)                               \
136*61046927SAndroid Build Coastguard Worker    {                                                                \
137*61046927SAndroid Build Coastguard Worker       .render = { .name = render_, .len = sizeof(render_) - 1 },    \
138*61046927SAndroid Build Coastguard Worker       .display = { .name = display_, .len = sizeof(display_) - 1 }, \
139*61046927SAndroid Build Coastguard Worker    }
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker /* This is the list of supported DRM render/display driver configs. */
142*61046927SAndroid Build Coastguard Worker static const struct pvr_drm_device_config pvr_drm_configs[] = {
143*61046927SAndroid Build Coastguard Worker    DEF_CONFIG("mediatek,mt8173-gpu", "mediatek-drm"),
144*61046927SAndroid Build Coastguard Worker    DEF_CONFIG("ti,am62-gpu", "ti,am625-dss"),
145*61046927SAndroid Build Coastguard Worker };
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker #undef DEF_CONFIG
148*61046927SAndroid Build Coastguard Worker 
149*61046927SAndroid Build Coastguard Worker static const struct vk_instance_extension_table pvr_instance_extensions = {
150*61046927SAndroid Build Coastguard Worker    .KHR_display = PVR_USE_WSI_PLATFORM_DISPLAY,
151*61046927SAndroid Build Coastguard Worker    .KHR_external_fence_capabilities = true,
152*61046927SAndroid Build Coastguard Worker    .KHR_external_memory_capabilities = true,
153*61046927SAndroid Build Coastguard Worker    .KHR_external_semaphore_capabilities = true,
154*61046927SAndroid Build Coastguard Worker    .KHR_get_display_properties2 = PVR_USE_WSI_PLATFORM_DISPLAY,
155*61046927SAndroid Build Coastguard Worker    .KHR_get_physical_device_properties2 = true,
156*61046927SAndroid Build Coastguard Worker    .KHR_get_surface_capabilities2 = PVR_USE_WSI_PLATFORM,
157*61046927SAndroid Build Coastguard Worker    .KHR_surface = PVR_USE_WSI_PLATFORM,
158*61046927SAndroid Build Coastguard Worker #ifndef VK_USE_PLATFORM_WIN32_KHR
159*61046927SAndroid Build Coastguard Worker    .EXT_headless_surface = PVR_USE_WSI_PLATFORM,
160*61046927SAndroid Build Coastguard Worker #endif
161*61046927SAndroid Build Coastguard Worker    .EXT_debug_report = true,
162*61046927SAndroid Build Coastguard Worker    .EXT_debug_utils = true,
163*61046927SAndroid Build Coastguard Worker };
164*61046927SAndroid Build Coastguard Worker 
pvr_physical_device_get_supported_extensions(struct vk_device_extension_table * extensions)165*61046927SAndroid Build Coastguard Worker static void pvr_physical_device_get_supported_extensions(
166*61046927SAndroid Build Coastguard Worker    struct vk_device_extension_table *extensions)
167*61046927SAndroid Build Coastguard Worker {
168*61046927SAndroid Build Coastguard Worker    *extensions = (struct vk_device_extension_table){
169*61046927SAndroid Build Coastguard Worker       .KHR_bind_memory2 = true,
170*61046927SAndroid Build Coastguard Worker       .KHR_copy_commands2 = true,
171*61046927SAndroid Build Coastguard Worker       /* TODO: enable this extension when the conformance tests get
172*61046927SAndroid Build Coastguard Worker        * updated to version 1.3.6.0, the current version does not
173*61046927SAndroid Build Coastguard Worker        * include the imagination driver ID, which will make a dEQP
174*61046927SAndroid Build Coastguard Worker        * test fail
175*61046927SAndroid Build Coastguard Worker        */
176*61046927SAndroid Build Coastguard Worker       .KHR_driver_properties = false,
177*61046927SAndroid Build Coastguard Worker       .KHR_external_fence = true,
178*61046927SAndroid Build Coastguard Worker       .KHR_external_fence_fd = true,
179*61046927SAndroid Build Coastguard Worker       .KHR_external_memory = true,
180*61046927SAndroid Build Coastguard Worker       .KHR_external_memory_fd = true,
181*61046927SAndroid Build Coastguard Worker       .KHR_format_feature_flags2 = true,
182*61046927SAndroid Build Coastguard Worker       .KHR_external_semaphore = PVR_USE_WSI_PLATFORM,
183*61046927SAndroid Build Coastguard Worker       .KHR_external_semaphore_fd = PVR_USE_WSI_PLATFORM,
184*61046927SAndroid Build Coastguard Worker       .KHR_get_memory_requirements2 = true,
185*61046927SAndroid Build Coastguard Worker       .KHR_image_format_list = true,
186*61046927SAndroid Build Coastguard Worker       .KHR_index_type_uint8 = true,
187*61046927SAndroid Build Coastguard Worker       .KHR_shader_expect_assume = true,
188*61046927SAndroid Build Coastguard Worker       .KHR_swapchain = PVR_USE_WSI_PLATFORM,
189*61046927SAndroid Build Coastguard Worker       .KHR_timeline_semaphore = true,
190*61046927SAndroid Build Coastguard Worker       .KHR_uniform_buffer_standard_layout = true,
191*61046927SAndroid Build Coastguard Worker       .EXT_external_memory_dma_buf = true,
192*61046927SAndroid Build Coastguard Worker       .EXT_host_query_reset = true,
193*61046927SAndroid Build Coastguard Worker       .EXT_index_type_uint8 = true,
194*61046927SAndroid Build Coastguard Worker       .EXT_memory_budget = true,
195*61046927SAndroid Build Coastguard Worker       .EXT_private_data = true,
196*61046927SAndroid Build Coastguard Worker       .EXT_scalar_block_layout = true,
197*61046927SAndroid Build Coastguard Worker       .EXT_texel_buffer_alignment = true,
198*61046927SAndroid Build Coastguard Worker       .EXT_tooling_info = true,
199*61046927SAndroid Build Coastguard Worker    };
200*61046927SAndroid Build Coastguard Worker }
201*61046927SAndroid Build Coastguard Worker 
pvr_physical_device_get_supported_features(const struct pvr_device_info * const dev_info,struct vk_features * const features)202*61046927SAndroid Build Coastguard Worker static void pvr_physical_device_get_supported_features(
203*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *const dev_info,
204*61046927SAndroid Build Coastguard Worker    struct vk_features *const features)
205*61046927SAndroid Build Coastguard Worker {
206*61046927SAndroid Build Coastguard Worker    *features = (struct vk_features){
207*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.0 */
208*61046927SAndroid Build Coastguard Worker       .robustBufferAccess = true,
209*61046927SAndroid Build Coastguard Worker       .fullDrawIndexUint32 = true,
210*61046927SAndroid Build Coastguard Worker       .imageCubeArray = true,
211*61046927SAndroid Build Coastguard Worker       .independentBlend = false,
212*61046927SAndroid Build Coastguard Worker       .geometryShader = false,
213*61046927SAndroid Build Coastguard Worker       .tessellationShader = false,
214*61046927SAndroid Build Coastguard Worker       .sampleRateShading = true,
215*61046927SAndroid Build Coastguard Worker       .dualSrcBlend = false,
216*61046927SAndroid Build Coastguard Worker       .logicOp = false,
217*61046927SAndroid Build Coastguard Worker       .multiDrawIndirect = true,
218*61046927SAndroid Build Coastguard Worker       .drawIndirectFirstInstance = true,
219*61046927SAndroid Build Coastguard Worker       .depthClamp = true,
220*61046927SAndroid Build Coastguard Worker       .depthBiasClamp = true,
221*61046927SAndroid Build Coastguard Worker       .fillModeNonSolid = false,
222*61046927SAndroid Build Coastguard Worker       .depthBounds = false,
223*61046927SAndroid Build Coastguard Worker       .wideLines = true,
224*61046927SAndroid Build Coastguard Worker       .largePoints = true,
225*61046927SAndroid Build Coastguard Worker       .alphaToOne = false,
226*61046927SAndroid Build Coastguard Worker       .multiViewport = false,
227*61046927SAndroid Build Coastguard Worker       .samplerAnisotropy = false,
228*61046927SAndroid Build Coastguard Worker       .textureCompressionETC2 = true,
229*61046927SAndroid Build Coastguard Worker       .textureCompressionASTC_LDR = false,
230*61046927SAndroid Build Coastguard Worker       .textureCompressionBC = false,
231*61046927SAndroid Build Coastguard Worker       .occlusionQueryPrecise = false,
232*61046927SAndroid Build Coastguard Worker       .pipelineStatisticsQuery = false,
233*61046927SAndroid Build Coastguard Worker       .vertexPipelineStoresAndAtomics = true,
234*61046927SAndroid Build Coastguard Worker       .fragmentStoresAndAtomics = true,
235*61046927SAndroid Build Coastguard Worker       .shaderTessellationAndGeometryPointSize = false,
236*61046927SAndroid Build Coastguard Worker       .shaderImageGatherExtended = false,
237*61046927SAndroid Build Coastguard Worker       .shaderStorageImageExtendedFormats = true,
238*61046927SAndroid Build Coastguard Worker       .shaderStorageImageMultisample = false,
239*61046927SAndroid Build Coastguard Worker       .shaderStorageImageReadWithoutFormat = true,
240*61046927SAndroid Build Coastguard Worker       .shaderStorageImageWriteWithoutFormat = false,
241*61046927SAndroid Build Coastguard Worker       .shaderUniformBufferArrayDynamicIndexing = true,
242*61046927SAndroid Build Coastguard Worker       .shaderSampledImageArrayDynamicIndexing = true,
243*61046927SAndroid Build Coastguard Worker       .shaderStorageBufferArrayDynamicIndexing = true,
244*61046927SAndroid Build Coastguard Worker       .shaderStorageImageArrayDynamicIndexing = true,
245*61046927SAndroid Build Coastguard Worker       .shaderClipDistance = false,
246*61046927SAndroid Build Coastguard Worker       .shaderCullDistance = false,
247*61046927SAndroid Build Coastguard Worker       .shaderFloat64 = false,
248*61046927SAndroid Build Coastguard Worker       .shaderInt64 = true,
249*61046927SAndroid Build Coastguard Worker       .shaderInt16 = true,
250*61046927SAndroid Build Coastguard Worker       .shaderResourceResidency = false,
251*61046927SAndroid Build Coastguard Worker       .shaderResourceMinLod = false,
252*61046927SAndroid Build Coastguard Worker       .sparseBinding = false,
253*61046927SAndroid Build Coastguard Worker       .sparseResidencyBuffer = false,
254*61046927SAndroid Build Coastguard Worker       .sparseResidencyImage2D = false,
255*61046927SAndroid Build Coastguard Worker       .sparseResidencyImage3D = false,
256*61046927SAndroid Build Coastguard Worker       .sparseResidency2Samples = false,
257*61046927SAndroid Build Coastguard Worker       .sparseResidency4Samples = false,
258*61046927SAndroid Build Coastguard Worker       .sparseResidency8Samples = false,
259*61046927SAndroid Build Coastguard Worker       .sparseResidency16Samples = false,
260*61046927SAndroid Build Coastguard Worker       .sparseResidencyAliased = false,
261*61046927SAndroid Build Coastguard Worker       .variableMultisampleRate = false,
262*61046927SAndroid Build Coastguard Worker       .inheritedQueries = false,
263*61046927SAndroid Build Coastguard Worker 
264*61046927SAndroid Build Coastguard Worker       /* VK_KHR_index_type_uint8 */
265*61046927SAndroid Build Coastguard Worker       .indexTypeUint8 = true,
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.2 / VK_KHR_timeline_semaphore */
268*61046927SAndroid Build Coastguard Worker       .timelineSemaphore = true,
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.2 / VK_KHR_uniform_buffer_standard_layout */
271*61046927SAndroid Build Coastguard Worker       .uniformBufferStandardLayout = true,
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.2 / VK_EXT_host_query_reset */
274*61046927SAndroid Build Coastguard Worker       .hostQueryReset = true,
275*61046927SAndroid Build Coastguard Worker 
276*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.3 / VK_EXT_private_data */
277*61046927SAndroid Build Coastguard Worker       .privateData = true,
278*61046927SAndroid Build Coastguard Worker 
279*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.2 / VK_EXT_scalar_block_layout */
280*61046927SAndroid Build Coastguard Worker       .scalarBlockLayout = true,
281*61046927SAndroid Build Coastguard Worker 
282*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.3 / VK_EXT_texel_buffer_alignment */
283*61046927SAndroid Build Coastguard Worker       .texelBufferAlignment = true,
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker       /* VK_KHR_shader_expect_assume */
286*61046927SAndroid Build Coastguard Worker       .shaderExpectAssume = true,
287*61046927SAndroid Build Coastguard Worker    };
288*61046927SAndroid Build Coastguard Worker }
289*61046927SAndroid Build Coastguard Worker 
pvr_physical_device_init_pipeline_cache_uuid(const struct pvr_device_info * const dev_info,uint8_t pipeline_cache_uuid_out[const static VK_UUID_SIZE])290*61046927SAndroid Build Coastguard Worker static bool pvr_physical_device_init_pipeline_cache_uuid(
291*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *const dev_info,
292*61046927SAndroid Build Coastguard Worker    uint8_t pipeline_cache_uuid_out[const static VK_UUID_SIZE])
293*61046927SAndroid Build Coastguard Worker {
294*61046927SAndroid Build Coastguard Worker    struct mesa_sha1 sha1_ctx;
295*61046927SAndroid Build Coastguard Worker    unsigned build_id_len;
296*61046927SAndroid Build Coastguard Worker    uint8_t sha1[20];
297*61046927SAndroid Build Coastguard Worker    uint64_t bvnc;
298*61046927SAndroid Build Coastguard Worker 
299*61046927SAndroid Build Coastguard Worker    const struct build_id_note *note =
300*61046927SAndroid Build Coastguard Worker       build_id_find_nhdr_for_addr(pvr_physical_device_init_pipeline_cache_uuid);
301*61046927SAndroid Build Coastguard Worker    if (!note) {
302*61046927SAndroid Build Coastguard Worker       mesa_loge("Failed to find build-id");
303*61046927SAndroid Build Coastguard Worker       return false;
304*61046927SAndroid Build Coastguard Worker    }
305*61046927SAndroid Build Coastguard Worker 
306*61046927SAndroid Build Coastguard Worker    build_id_len = build_id_length(note);
307*61046927SAndroid Build Coastguard Worker    if (build_id_len < 20) {
308*61046927SAndroid Build Coastguard Worker       mesa_loge("Build-id too short. It needs to be a SHA");
309*61046927SAndroid Build Coastguard Worker       return false;
310*61046927SAndroid Build Coastguard Worker    }
311*61046927SAndroid Build Coastguard Worker 
312*61046927SAndroid Build Coastguard Worker    bvnc = pvr_get_packed_bvnc(dev_info);
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker    _mesa_sha1_init(&sha1_ctx);
315*61046927SAndroid Build Coastguard Worker    _mesa_sha1_update(&sha1_ctx, build_id_data(note), build_id_len);
316*61046927SAndroid Build Coastguard Worker    _mesa_sha1_update(&sha1_ctx, &bvnc, sizeof(bvnc));
317*61046927SAndroid Build Coastguard Worker    _mesa_sha1_final(&sha1_ctx, sha1);
318*61046927SAndroid Build Coastguard Worker    memcpy(pipeline_cache_uuid_out, sha1, VK_UUID_SIZE);
319*61046927SAndroid Build Coastguard Worker 
320*61046927SAndroid Build Coastguard Worker    return true;
321*61046927SAndroid Build Coastguard Worker }
322*61046927SAndroid Build Coastguard Worker 
323*61046927SAndroid Build Coastguard Worker struct pvr_descriptor_limits {
324*61046927SAndroid Build Coastguard Worker    uint32_t max_per_stage_resources;
325*61046927SAndroid Build Coastguard Worker    uint32_t max_per_stage_samplers;
326*61046927SAndroid Build Coastguard Worker    uint32_t max_per_stage_uniform_buffers;
327*61046927SAndroid Build Coastguard Worker    uint32_t max_per_stage_storage_buffers;
328*61046927SAndroid Build Coastguard Worker    uint32_t max_per_stage_sampled_images;
329*61046927SAndroid Build Coastguard Worker    uint32_t max_per_stage_storage_images;
330*61046927SAndroid Build Coastguard Worker    uint32_t max_per_stage_input_attachments;
331*61046927SAndroid Build Coastguard Worker };
332*61046927SAndroid Build Coastguard Worker 
333*61046927SAndroid Build Coastguard Worker static const struct pvr_descriptor_limits *
pvr_get_physical_device_descriptor_limits(const struct pvr_device_info * dev_info,const struct pvr_device_runtime_info * dev_runtime_info)334*61046927SAndroid Build Coastguard Worker pvr_get_physical_device_descriptor_limits(
335*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *dev_info,
336*61046927SAndroid Build Coastguard Worker    const struct pvr_device_runtime_info *dev_runtime_info)
337*61046927SAndroid Build Coastguard Worker {
338*61046927SAndroid Build Coastguard Worker    enum pvr_descriptor_cs_level {
339*61046927SAndroid Build Coastguard Worker       /* clang-format off */
340*61046927SAndroid Build Coastguard Worker       CS4096, /* 6XT and some XE cores with large CS. */
341*61046927SAndroid Build Coastguard Worker       CS2560, /* Mid range Rogue XE cores. */
342*61046927SAndroid Build Coastguard Worker       CS2048, /* Low end Rogue XE cores. */
343*61046927SAndroid Build Coastguard Worker       CS1536, /* Ultra-low-end 9XEP. */
344*61046927SAndroid Build Coastguard Worker       CS680,  /* lower limits for older devices. */
345*61046927SAndroid Build Coastguard Worker       CS408,  /* 7XE. */
346*61046927SAndroid Build Coastguard Worker       /* clang-format on */
347*61046927SAndroid Build Coastguard Worker    };
348*61046927SAndroid Build Coastguard Worker 
349*61046927SAndroid Build Coastguard Worker    static const struct pvr_descriptor_limits descriptor_limits[] = {
350*61046927SAndroid Build Coastguard Worker       [CS4096] = { 1160U, 256U, 192U, 144U, 256U, 256U, 8U, },
351*61046927SAndroid Build Coastguard Worker       [CS2560] = {  648U, 128U, 128U, 128U, 128U, 128U, 8U, },
352*61046927SAndroid Build Coastguard Worker       [CS2048] = {  584U, 128U,  96U,  64U, 128U, 128U, 8U, },
353*61046927SAndroid Build Coastguard Worker       [CS1536] = {  456U,  64U,  96U,  64U, 128U,  64U, 8U, },
354*61046927SAndroid Build Coastguard Worker       [CS680]  = {  224U,  32U,  64U,  36U,  48U,   8U, 8U, },
355*61046927SAndroid Build Coastguard Worker       [CS408]  = {  128U,  16U,  40U,  28U,  16U,   8U, 8U, },
356*61046927SAndroid Build Coastguard Worker    };
357*61046927SAndroid Build Coastguard Worker 
358*61046927SAndroid Build Coastguard Worker    const uint32_t common_size =
359*61046927SAndroid Build Coastguard Worker       pvr_calc_fscommon_size_and_tiles_in_flight(dev_info,
360*61046927SAndroid Build Coastguard Worker                                                  dev_runtime_info,
361*61046927SAndroid Build Coastguard Worker                                                  UINT32_MAX,
362*61046927SAndroid Build Coastguard Worker                                                  1);
363*61046927SAndroid Build Coastguard Worker    enum pvr_descriptor_cs_level cs_level;
364*61046927SAndroid Build Coastguard Worker 
365*61046927SAndroid Build Coastguard Worker    if (common_size >= 2048) {
366*61046927SAndroid Build Coastguard Worker       cs_level = CS2048;
367*61046927SAndroid Build Coastguard Worker    } else if (common_size >= 1526) {
368*61046927SAndroid Build Coastguard Worker       cs_level = CS1536;
369*61046927SAndroid Build Coastguard Worker    } else if (common_size >= 680) {
370*61046927SAndroid Build Coastguard Worker       cs_level = CS680;
371*61046927SAndroid Build Coastguard Worker    } else if (common_size >= 408) {
372*61046927SAndroid Build Coastguard Worker       cs_level = CS408;
373*61046927SAndroid Build Coastguard Worker    } else {
374*61046927SAndroid Build Coastguard Worker       mesa_loge("This core appears to have a very limited amount of shared "
375*61046927SAndroid Build Coastguard Worker                 "register space and may not meet the Vulkan spec limits.");
376*61046927SAndroid Build Coastguard Worker       abort();
377*61046927SAndroid Build Coastguard Worker    }
378*61046927SAndroid Build Coastguard Worker 
379*61046927SAndroid Build Coastguard Worker    return &descriptor_limits[cs_level];
380*61046927SAndroid Build Coastguard Worker }
381*61046927SAndroid Build Coastguard Worker 
pvr_physical_device_get_properties(const struct pvr_physical_device * const pdevice,struct vk_properties * const properties)382*61046927SAndroid Build Coastguard Worker static bool pvr_physical_device_get_properties(
383*61046927SAndroid Build Coastguard Worker    const struct pvr_physical_device *const pdevice,
384*61046927SAndroid Build Coastguard Worker    struct vk_properties *const properties)
385*61046927SAndroid Build Coastguard Worker {
386*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *const dev_info = &pdevice->dev_info;
387*61046927SAndroid Build Coastguard Worker    const struct pvr_device_runtime_info *const dev_runtime_info =
388*61046927SAndroid Build Coastguard Worker       &pdevice->dev_runtime_info;
389*61046927SAndroid Build Coastguard Worker    const struct pvr_descriptor_limits *descriptor_limits =
390*61046927SAndroid Build Coastguard Worker       pvr_get_physical_device_descriptor_limits(dev_info, dev_runtime_info);
391*61046927SAndroid Build Coastguard Worker 
392*61046927SAndroid Build Coastguard Worker    /* Default value based on the minimum value found in all existing cores. */
393*61046927SAndroid Build Coastguard Worker    const uint32_t max_multisample =
394*61046927SAndroid Build Coastguard Worker       PVR_GET_FEATURE_VALUE(dev_info, max_multisample, 4);
395*61046927SAndroid Build Coastguard Worker 
396*61046927SAndroid Build Coastguard Worker    /* Default value based on the minimum value found in all existing cores. */
397*61046927SAndroid Build Coastguard Worker    const uint32_t uvs_banks = PVR_GET_FEATURE_VALUE(dev_info, uvs_banks, 2);
398*61046927SAndroid Build Coastguard Worker 
399*61046927SAndroid Build Coastguard Worker    /* Default value based on the minimum value found in all existing cores. */
400*61046927SAndroid Build Coastguard Worker    const uint32_t uvs_pba_entries =
401*61046927SAndroid Build Coastguard Worker       PVR_GET_FEATURE_VALUE(dev_info, uvs_pba_entries, 160);
402*61046927SAndroid Build Coastguard Worker 
403*61046927SAndroid Build Coastguard Worker    /* Default value based on the minimum value found in all existing cores. */
404*61046927SAndroid Build Coastguard Worker    const uint32_t num_user_clip_planes =
405*61046927SAndroid Build Coastguard Worker       PVR_GET_FEATURE_VALUE(dev_info, num_user_clip_planes, 8);
406*61046927SAndroid Build Coastguard Worker 
407*61046927SAndroid Build Coastguard Worker    const uint32_t sub_pixel_precision =
408*61046927SAndroid Build Coastguard Worker       PVR_HAS_FEATURE(dev_info, simple_internal_parameter_format) ? 4U : 8U;
409*61046927SAndroid Build Coastguard Worker 
410*61046927SAndroid Build Coastguard Worker    const uint32_t max_render_size = rogue_get_render_size_max(dev_info);
411*61046927SAndroid Build Coastguard Worker 
412*61046927SAndroid Build Coastguard Worker    const uint32_t max_sample_bits = ((max_multisample << 1) - 1);
413*61046927SAndroid Build Coastguard Worker 
414*61046927SAndroid Build Coastguard Worker    const uint32_t max_user_vertex_components =
415*61046927SAndroid Build Coastguard Worker       ((uvs_banks <= 8U) && (uvs_pba_entries == 160U)) ? 64U : 128U;
416*61046927SAndroid Build Coastguard Worker 
417*61046927SAndroid Build Coastguard Worker    /* The workgroup invocations are limited by the case where we have a compute
418*61046927SAndroid Build Coastguard Worker     * barrier - each slot has a fixed number of invocations, the whole workgroup
419*61046927SAndroid Build Coastguard Worker     * may need to span multiple slots. As each slot will WAIT at the barrier
420*61046927SAndroid Build Coastguard Worker     * until the last invocation completes, all have to be schedulable at the
421*61046927SAndroid Build Coastguard Worker     * same time.
422*61046927SAndroid Build Coastguard Worker     *
423*61046927SAndroid Build Coastguard Worker     * Typically all Rogue cores have 16 slots. Some of the smallest cores are
424*61046927SAndroid Build Coastguard Worker     * reduced to 14.
425*61046927SAndroid Build Coastguard Worker     *
426*61046927SAndroid Build Coastguard Worker     * The compute barrier slot exhaustion scenario can be tested with:
427*61046927SAndroid Build Coastguard Worker     * dEQP-VK.memory_model.message_passing*u32.coherent.fence_fence
428*61046927SAndroid Build Coastguard Worker     *    .atomicwrite*guard*comp
429*61046927SAndroid Build Coastguard Worker     */
430*61046927SAndroid Build Coastguard Worker 
431*61046927SAndroid Build Coastguard Worker    /* Default value based on the minimum value found in all existing cores. */
432*61046927SAndroid Build Coastguard Worker    const uint32_t usc_slots = PVR_GET_FEATURE_VALUE(dev_info, usc_slots, 14);
433*61046927SAndroid Build Coastguard Worker 
434*61046927SAndroid Build Coastguard Worker    /* Default value based on the minimum value found in all existing cores. */
435*61046927SAndroid Build Coastguard Worker    const uint32_t max_instances_per_pds_task =
436*61046927SAndroid Build Coastguard Worker       PVR_GET_FEATURE_VALUE(dev_info, max_instances_per_pds_task, 32U);
437*61046927SAndroid Build Coastguard Worker 
438*61046927SAndroid Build Coastguard Worker    const uint32_t max_compute_work_group_invocations =
439*61046927SAndroid Build Coastguard Worker       (usc_slots * max_instances_per_pds_task >= 512U) ? 512U : 384U;
440*61046927SAndroid Build Coastguard Worker 
441*61046927SAndroid Build Coastguard Worker    bool ret;
442*61046927SAndroid Build Coastguard Worker 
443*61046927SAndroid Build Coastguard Worker    *properties = (struct vk_properties){
444*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.0 */
445*61046927SAndroid Build Coastguard Worker       .apiVersion = PVR_API_VERSION,
446*61046927SAndroid Build Coastguard Worker       .driverVersion = vk_get_driver_version(),
447*61046927SAndroid Build Coastguard Worker       .vendorID = VK_VENDOR_ID_IMAGINATION,
448*61046927SAndroid Build Coastguard Worker       .deviceID = dev_info->ident.device_id,
449*61046927SAndroid Build Coastguard Worker       .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
450*61046927SAndroid Build Coastguard Worker       /* deviceName and pipelineCacheUUID are filled below .*/
451*61046927SAndroid Build Coastguard Worker 
452*61046927SAndroid Build Coastguard Worker       .maxImageDimension1D = max_render_size,
453*61046927SAndroid Build Coastguard Worker       .maxImageDimension2D = max_render_size,
454*61046927SAndroid Build Coastguard Worker       .maxImageDimension3D = PVR_MAX_TEXTURE_EXTENT_Z,
455*61046927SAndroid Build Coastguard Worker       .maxImageDimensionCube = max_render_size,
456*61046927SAndroid Build Coastguard Worker       .maxImageArrayLayers = PVR_MAX_ARRAY_LAYERS,
457*61046927SAndroid Build Coastguard Worker       .maxTexelBufferElements = 64U * 1024U,
458*61046927SAndroid Build Coastguard Worker       .maxUniformBufferRange = 128U * 1024U * 1024U,
459*61046927SAndroid Build Coastguard Worker       .maxStorageBufferRange = 128U * 1024U * 1024U,
460*61046927SAndroid Build Coastguard Worker       .maxPushConstantsSize = PVR_MAX_PUSH_CONSTANTS_SIZE,
461*61046927SAndroid Build Coastguard Worker       .maxMemoryAllocationCount = UINT32_MAX,
462*61046927SAndroid Build Coastguard Worker       .maxSamplerAllocationCount = UINT32_MAX,
463*61046927SAndroid Build Coastguard Worker       .bufferImageGranularity = 1U,
464*61046927SAndroid Build Coastguard Worker       .sparseAddressSpaceSize = 256ULL * 1024ULL * 1024ULL * 1024ULL,
465*61046927SAndroid Build Coastguard Worker       /* Maximum number of descriptor sets that can be bound simultaneously. */
466*61046927SAndroid Build Coastguard Worker       .maxBoundDescriptorSets = PVR_MAX_DESCRIPTOR_SETS,
467*61046927SAndroid Build Coastguard Worker       .maxPerStageResources = descriptor_limits->max_per_stage_resources,
468*61046927SAndroid Build Coastguard Worker       .maxPerStageDescriptorSamplers =
469*61046927SAndroid Build Coastguard Worker          descriptor_limits->max_per_stage_samplers,
470*61046927SAndroid Build Coastguard Worker       .maxPerStageDescriptorUniformBuffers =
471*61046927SAndroid Build Coastguard Worker          descriptor_limits->max_per_stage_uniform_buffers,
472*61046927SAndroid Build Coastguard Worker       .maxPerStageDescriptorStorageBuffers =
473*61046927SAndroid Build Coastguard Worker          descriptor_limits->max_per_stage_storage_buffers,
474*61046927SAndroid Build Coastguard Worker       .maxPerStageDescriptorSampledImages =
475*61046927SAndroid Build Coastguard Worker          descriptor_limits->max_per_stage_sampled_images,
476*61046927SAndroid Build Coastguard Worker       .maxPerStageDescriptorStorageImages =
477*61046927SAndroid Build Coastguard Worker          descriptor_limits->max_per_stage_storage_images,
478*61046927SAndroid Build Coastguard Worker       .maxPerStageDescriptorInputAttachments =
479*61046927SAndroid Build Coastguard Worker          descriptor_limits->max_per_stage_input_attachments,
480*61046927SAndroid Build Coastguard Worker       .maxDescriptorSetSamplers = 256U,
481*61046927SAndroid Build Coastguard Worker       .maxDescriptorSetUniformBuffers = 256U,
482*61046927SAndroid Build Coastguard Worker       .maxDescriptorSetUniformBuffersDynamic =
483*61046927SAndroid Build Coastguard Worker          PVR_MAX_DESCRIPTOR_SET_UNIFORM_DYNAMIC_BUFFERS,
484*61046927SAndroid Build Coastguard Worker       .maxDescriptorSetStorageBuffers = 256U,
485*61046927SAndroid Build Coastguard Worker       .maxDescriptorSetStorageBuffersDynamic =
486*61046927SAndroid Build Coastguard Worker          PVR_MAX_DESCRIPTOR_SET_STORAGE_DYNAMIC_BUFFERS,
487*61046927SAndroid Build Coastguard Worker       .maxDescriptorSetSampledImages = 256U,
488*61046927SAndroid Build Coastguard Worker       .maxDescriptorSetStorageImages = 256U,
489*61046927SAndroid Build Coastguard Worker       .maxDescriptorSetInputAttachments = 256U,
490*61046927SAndroid Build Coastguard Worker 
491*61046927SAndroid Build Coastguard Worker       /* Vertex Shader Limits */
492*61046927SAndroid Build Coastguard Worker       .maxVertexInputAttributes = PVR_MAX_VERTEX_INPUT_BINDINGS,
493*61046927SAndroid Build Coastguard Worker       .maxVertexInputBindings = PVR_MAX_VERTEX_INPUT_BINDINGS,
494*61046927SAndroid Build Coastguard Worker       .maxVertexInputAttributeOffset = 0xFFFF,
495*61046927SAndroid Build Coastguard Worker       .maxVertexInputBindingStride = 1024U * 1024U * 1024U * 2U,
496*61046927SAndroid Build Coastguard Worker       .maxVertexOutputComponents = max_user_vertex_components,
497*61046927SAndroid Build Coastguard Worker 
498*61046927SAndroid Build Coastguard Worker       /* Tessellation Limits */
499*61046927SAndroid Build Coastguard Worker       .maxTessellationGenerationLevel = 0,
500*61046927SAndroid Build Coastguard Worker       .maxTessellationPatchSize = 0,
501*61046927SAndroid Build Coastguard Worker       .maxTessellationControlPerVertexInputComponents = 0,
502*61046927SAndroid Build Coastguard Worker       .maxTessellationControlPerVertexOutputComponents = 0,
503*61046927SAndroid Build Coastguard Worker       .maxTessellationControlPerPatchOutputComponents = 0,
504*61046927SAndroid Build Coastguard Worker       .maxTessellationControlTotalOutputComponents = 0,
505*61046927SAndroid Build Coastguard Worker       .maxTessellationEvaluationInputComponents = 0,
506*61046927SAndroid Build Coastguard Worker       .maxTessellationEvaluationOutputComponents = 0,
507*61046927SAndroid Build Coastguard Worker 
508*61046927SAndroid Build Coastguard Worker       /* Geometry Shader Limits */
509*61046927SAndroid Build Coastguard Worker       .maxGeometryShaderInvocations = 0,
510*61046927SAndroid Build Coastguard Worker       .maxGeometryInputComponents = 0,
511*61046927SAndroid Build Coastguard Worker       .maxGeometryOutputComponents = 0,
512*61046927SAndroid Build Coastguard Worker       .maxGeometryOutputVertices = 0,
513*61046927SAndroid Build Coastguard Worker       .maxGeometryTotalOutputComponents = 0,
514*61046927SAndroid Build Coastguard Worker 
515*61046927SAndroid Build Coastguard Worker       /* Fragment Shader Limits */
516*61046927SAndroid Build Coastguard Worker       .maxFragmentInputComponents = max_user_vertex_components,
517*61046927SAndroid Build Coastguard Worker       .maxFragmentOutputAttachments = PVR_MAX_COLOR_ATTACHMENTS,
518*61046927SAndroid Build Coastguard Worker       .maxFragmentDualSrcAttachments = 0,
519*61046927SAndroid Build Coastguard Worker       .maxFragmentCombinedOutputResources =
520*61046927SAndroid Build Coastguard Worker          descriptor_limits->max_per_stage_storage_buffers +
521*61046927SAndroid Build Coastguard Worker          descriptor_limits->max_per_stage_storage_images +
522*61046927SAndroid Build Coastguard Worker          PVR_MAX_COLOR_ATTACHMENTS,
523*61046927SAndroid Build Coastguard Worker 
524*61046927SAndroid Build Coastguard Worker       /* Compute Shader Limits */
525*61046927SAndroid Build Coastguard Worker       .maxComputeSharedMemorySize = 16U * 1024U,
526*61046927SAndroid Build Coastguard Worker       .maxComputeWorkGroupCount = { 64U * 1024U, 64U * 1024U, 64U * 1024U },
527*61046927SAndroid Build Coastguard Worker       .maxComputeWorkGroupInvocations = max_compute_work_group_invocations,
528*61046927SAndroid Build Coastguard Worker       .maxComputeWorkGroupSize = { max_compute_work_group_invocations,
529*61046927SAndroid Build Coastguard Worker                                    max_compute_work_group_invocations,
530*61046927SAndroid Build Coastguard Worker                                    64U },
531*61046927SAndroid Build Coastguard Worker 
532*61046927SAndroid Build Coastguard Worker       /* Rasterization Limits */
533*61046927SAndroid Build Coastguard Worker       .subPixelPrecisionBits = sub_pixel_precision,
534*61046927SAndroid Build Coastguard Worker       .subTexelPrecisionBits = 8U,
535*61046927SAndroid Build Coastguard Worker       .mipmapPrecisionBits = 8U,
536*61046927SAndroid Build Coastguard Worker 
537*61046927SAndroid Build Coastguard Worker       .maxDrawIndexedIndexValue = UINT32_MAX,
538*61046927SAndroid Build Coastguard Worker       .maxDrawIndirectCount = 2U * 1024U * 1024U * 1024U,
539*61046927SAndroid Build Coastguard Worker       .maxSamplerLodBias = 16.0f,
540*61046927SAndroid Build Coastguard Worker       .maxSamplerAnisotropy = 1.0f,
541*61046927SAndroid Build Coastguard Worker       .maxViewports = PVR_MAX_VIEWPORTS,
542*61046927SAndroid Build Coastguard Worker 
543*61046927SAndroid Build Coastguard Worker       .maxViewportDimensions[0] = max_render_size,
544*61046927SAndroid Build Coastguard Worker       .maxViewportDimensions[1] = max_render_size,
545*61046927SAndroid Build Coastguard Worker       .viewportBoundsRange[0] = -(int32_t)(2U * max_render_size),
546*61046927SAndroid Build Coastguard Worker       .viewportBoundsRange[1] = 2U * max_render_size,
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker       .viewportSubPixelBits = 0,
549*61046927SAndroid Build Coastguard Worker       .minMemoryMapAlignment = pdevice->ws->page_size,
550*61046927SAndroid Build Coastguard Worker       .minTexelBufferOffsetAlignment = 16U,
551*61046927SAndroid Build Coastguard Worker       .minUniformBufferOffsetAlignment = 4U,
552*61046927SAndroid Build Coastguard Worker       .minStorageBufferOffsetAlignment = 4U,
553*61046927SAndroid Build Coastguard Worker 
554*61046927SAndroid Build Coastguard Worker       .minTexelOffset = -8,
555*61046927SAndroid Build Coastguard Worker       .maxTexelOffset = 7U,
556*61046927SAndroid Build Coastguard Worker       .minTexelGatherOffset = -8,
557*61046927SAndroid Build Coastguard Worker       .maxTexelGatherOffset = 7,
558*61046927SAndroid Build Coastguard Worker       .minInterpolationOffset = -0.5,
559*61046927SAndroid Build Coastguard Worker       .maxInterpolationOffset = 0.5,
560*61046927SAndroid Build Coastguard Worker       .subPixelInterpolationOffsetBits = 4U,
561*61046927SAndroid Build Coastguard Worker 
562*61046927SAndroid Build Coastguard Worker       .maxFramebufferWidth = max_render_size,
563*61046927SAndroid Build Coastguard Worker       .maxFramebufferHeight = max_render_size,
564*61046927SAndroid Build Coastguard Worker       .maxFramebufferLayers = PVR_MAX_FRAMEBUFFER_LAYERS,
565*61046927SAndroid Build Coastguard Worker 
566*61046927SAndroid Build Coastguard Worker       .framebufferColorSampleCounts = max_sample_bits,
567*61046927SAndroid Build Coastguard Worker       .framebufferDepthSampleCounts = max_sample_bits,
568*61046927SAndroid Build Coastguard Worker       .framebufferStencilSampleCounts = max_sample_bits,
569*61046927SAndroid Build Coastguard Worker       .framebufferNoAttachmentsSampleCounts = max_sample_bits,
570*61046927SAndroid Build Coastguard Worker       .maxColorAttachments = PVR_MAX_COLOR_ATTACHMENTS,
571*61046927SAndroid Build Coastguard Worker       .sampledImageColorSampleCounts = max_sample_bits,
572*61046927SAndroid Build Coastguard Worker       .sampledImageIntegerSampleCounts = max_sample_bits,
573*61046927SAndroid Build Coastguard Worker       .sampledImageDepthSampleCounts = max_sample_bits,
574*61046927SAndroid Build Coastguard Worker       .sampledImageStencilSampleCounts = max_sample_bits,
575*61046927SAndroid Build Coastguard Worker       .storageImageSampleCounts = max_sample_bits,
576*61046927SAndroid Build Coastguard Worker       .maxSampleMaskWords = 1U,
577*61046927SAndroid Build Coastguard Worker       .timestampComputeAndGraphics = false,
578*61046927SAndroid Build Coastguard Worker       .timestampPeriod = 0.0f,
579*61046927SAndroid Build Coastguard Worker       .maxClipDistances = num_user_clip_planes,
580*61046927SAndroid Build Coastguard Worker       .maxCullDistances = num_user_clip_planes,
581*61046927SAndroid Build Coastguard Worker       .maxCombinedClipAndCullDistances = num_user_clip_planes,
582*61046927SAndroid Build Coastguard Worker       .discreteQueuePriorities = 2U,
583*61046927SAndroid Build Coastguard Worker       .pointSizeRange[0] = 1.0f,
584*61046927SAndroid Build Coastguard Worker       .pointSizeRange[1] = 511.0f,
585*61046927SAndroid Build Coastguard Worker       .pointSizeGranularity = 0.0625f,
586*61046927SAndroid Build Coastguard Worker       .lineWidthRange[0] = 1.0f / 16.0f,
587*61046927SAndroid Build Coastguard Worker       .lineWidthRange[1] = 16.0f,
588*61046927SAndroid Build Coastguard Worker       .lineWidthGranularity = 1.0f / 16.0f,
589*61046927SAndroid Build Coastguard Worker       .strictLines = false,
590*61046927SAndroid Build Coastguard Worker       .standardSampleLocations = true,
591*61046927SAndroid Build Coastguard Worker       .optimalBufferCopyOffsetAlignment = 4U,
592*61046927SAndroid Build Coastguard Worker       .optimalBufferCopyRowPitchAlignment = 4U,
593*61046927SAndroid Build Coastguard Worker       .nonCoherentAtomSize = 1U,
594*61046927SAndroid Build Coastguard Worker 
595*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.2 / VK_KHR_driver_properties */
596*61046927SAndroid Build Coastguard Worker       .driverID = VK_DRIVER_ID_IMAGINATION_OPEN_SOURCE_MESA,
597*61046927SAndroid Build Coastguard Worker       .driverName = "Imagination open-source Mesa driver",
598*61046927SAndroid Build Coastguard Worker       .driverInfo = "Mesa " PACKAGE_VERSION MESA_GIT_SHA1,
599*61046927SAndroid Build Coastguard Worker       .conformanceVersion = {
600*61046927SAndroid Build Coastguard Worker          .major = 1,
601*61046927SAndroid Build Coastguard Worker          .minor = 3,
602*61046927SAndroid Build Coastguard Worker          .subminor = 4,
603*61046927SAndroid Build Coastguard Worker          .patch = 1,
604*61046927SAndroid Build Coastguard Worker       },
605*61046927SAndroid Build Coastguard Worker 
606*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.2 / VK_KHR_timeline_semaphore */
607*61046927SAndroid Build Coastguard Worker       .maxTimelineSemaphoreValueDifference = UINT64_MAX,
608*61046927SAndroid Build Coastguard Worker 
609*61046927SAndroid Build Coastguard Worker       /* Vulkan 1.3 / VK_EXT_texel_buffer_alignment */
610*61046927SAndroid Build Coastguard Worker       .storageTexelBufferOffsetAlignmentBytes = 16,
611*61046927SAndroid Build Coastguard Worker       .storageTexelBufferOffsetSingleTexelAlignment = true,
612*61046927SAndroid Build Coastguard Worker       .uniformTexelBufferOffsetAlignmentBytes = 16,
613*61046927SAndroid Build Coastguard Worker       .uniformTexelBufferOffsetSingleTexelAlignment = false,
614*61046927SAndroid Build Coastguard Worker    };
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker    snprintf(properties->deviceName,
617*61046927SAndroid Build Coastguard Worker             sizeof(properties->deviceName),
618*61046927SAndroid Build Coastguard Worker             "Imagination PowerVR %s %s",
619*61046927SAndroid Build Coastguard Worker             dev_info->ident.series_name,
620*61046927SAndroid Build Coastguard Worker             dev_info->ident.public_name);
621*61046927SAndroid Build Coastguard Worker 
622*61046927SAndroid Build Coastguard Worker    ret = pvr_physical_device_init_pipeline_cache_uuid(
623*61046927SAndroid Build Coastguard Worker       dev_info,
624*61046927SAndroid Build Coastguard Worker       properties->pipelineCacheUUID);
625*61046927SAndroid Build Coastguard Worker    if (!ret)
626*61046927SAndroid Build Coastguard Worker       return false;
627*61046927SAndroid Build Coastguard Worker 
628*61046927SAndroid Build Coastguard Worker    return true;
629*61046927SAndroid Build Coastguard Worker }
630*61046927SAndroid Build Coastguard Worker 
pvr_EnumerateInstanceVersion(uint32_t * pApiVersion)631*61046927SAndroid Build Coastguard Worker VkResult pvr_EnumerateInstanceVersion(uint32_t *pApiVersion)
632*61046927SAndroid Build Coastguard Worker {
633*61046927SAndroid Build Coastguard Worker    *pApiVersion = PVR_API_VERSION;
634*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
635*61046927SAndroid Build Coastguard Worker }
636*61046927SAndroid Build Coastguard Worker 
637*61046927SAndroid Build Coastguard Worker VkResult
pvr_EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)638*61046927SAndroid Build Coastguard Worker pvr_EnumerateInstanceExtensionProperties(const char *pLayerName,
639*61046927SAndroid Build Coastguard Worker                                          uint32_t *pPropertyCount,
640*61046927SAndroid Build Coastguard Worker                                          VkExtensionProperties *pProperties)
641*61046927SAndroid Build Coastguard Worker {
642*61046927SAndroid Build Coastguard Worker    if (pLayerName)
643*61046927SAndroid Build Coastguard Worker       return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
644*61046927SAndroid Build Coastguard Worker 
645*61046927SAndroid Build Coastguard Worker    return vk_enumerate_instance_extension_properties(&pvr_instance_extensions,
646*61046927SAndroid Build Coastguard Worker                                                      pPropertyCount,
647*61046927SAndroid Build Coastguard Worker                                                      pProperties);
648*61046927SAndroid Build Coastguard Worker }
649*61046927SAndroid Build Coastguard Worker 
pvr_physical_device_destroy(struct vk_physical_device * vk_pdevice)650*61046927SAndroid Build Coastguard Worker static void pvr_physical_device_destroy(struct vk_physical_device *vk_pdevice)
651*61046927SAndroid Build Coastguard Worker {
652*61046927SAndroid Build Coastguard Worker    struct pvr_physical_device *pdevice =
653*61046927SAndroid Build Coastguard Worker       container_of(vk_pdevice, struct pvr_physical_device, vk);
654*61046927SAndroid Build Coastguard Worker 
655*61046927SAndroid Build Coastguard Worker    /* Be careful here. The device might not have been initialized. This can
656*61046927SAndroid Build Coastguard Worker     * happen since initialization is done in vkEnumeratePhysicalDevices() but
657*61046927SAndroid Build Coastguard Worker     * finish is done in vkDestroyInstance(). Make sure that you check for NULL
658*61046927SAndroid Build Coastguard Worker     * before freeing or that the freeing functions accept NULL pointers.
659*61046927SAndroid Build Coastguard Worker     */
660*61046927SAndroid Build Coastguard Worker 
661*61046927SAndroid Build Coastguard Worker    if (pdevice->compiler)
662*61046927SAndroid Build Coastguard Worker       ralloc_free(pdevice->compiler);
663*61046927SAndroid Build Coastguard Worker 
664*61046927SAndroid Build Coastguard Worker    pvr_wsi_finish(pdevice);
665*61046927SAndroid Build Coastguard Worker 
666*61046927SAndroid Build Coastguard Worker    if (pdevice->ws)
667*61046927SAndroid Build Coastguard Worker       pvr_winsys_destroy(pdevice->ws);
668*61046927SAndroid Build Coastguard Worker 
669*61046927SAndroid Build Coastguard Worker    vk_free(&pdevice->vk.instance->alloc, pdevice->render_path);
670*61046927SAndroid Build Coastguard Worker    vk_free(&pdevice->vk.instance->alloc, pdevice->display_path);
671*61046927SAndroid Build Coastguard Worker 
672*61046927SAndroid Build Coastguard Worker    vk_physical_device_finish(&pdevice->vk);
673*61046927SAndroid Build Coastguard Worker 
674*61046927SAndroid Build Coastguard Worker    vk_free(&pdevice->vk.instance->alloc, pdevice);
675*61046927SAndroid Build Coastguard Worker }
676*61046927SAndroid Build Coastguard Worker 
pvr_DestroyInstance(VkInstance _instance,const VkAllocationCallbacks * pAllocator)677*61046927SAndroid Build Coastguard Worker void pvr_DestroyInstance(VkInstance _instance,
678*61046927SAndroid Build Coastguard Worker                          const VkAllocationCallbacks *pAllocator)
679*61046927SAndroid Build Coastguard Worker {
680*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_instance, instance, _instance);
681*61046927SAndroid Build Coastguard Worker 
682*61046927SAndroid Build Coastguard Worker    if (!instance)
683*61046927SAndroid Build Coastguard Worker       return;
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker    VG(VALGRIND_DESTROY_MEMPOOL(instance));
686*61046927SAndroid Build Coastguard Worker 
687*61046927SAndroid Build Coastguard Worker    vk_instance_finish(&instance->vk);
688*61046927SAndroid Build Coastguard Worker    vk_free(&instance->vk.alloc, instance);
689*61046927SAndroid Build Coastguard Worker }
690*61046927SAndroid Build Coastguard Worker 
pvr_compute_heap_size(void)691*61046927SAndroid Build Coastguard Worker static uint64_t pvr_compute_heap_size(void)
692*61046927SAndroid Build Coastguard Worker {
693*61046927SAndroid Build Coastguard Worker    /* Query the total ram from the system */
694*61046927SAndroid Build Coastguard Worker    uint64_t total_ram;
695*61046927SAndroid Build Coastguard Worker    if (!os_get_total_physical_memory(&total_ram))
696*61046927SAndroid Build Coastguard Worker       return 0;
697*61046927SAndroid Build Coastguard Worker 
698*61046927SAndroid Build Coastguard Worker    /* We don't want to burn too much ram with the GPU. If the user has 4GiB
699*61046927SAndroid Build Coastguard Worker     * or less, we use at most half. If they have more than 4GiB, we use 3/4.
700*61046927SAndroid Build Coastguard Worker     */
701*61046927SAndroid Build Coastguard Worker    uint64_t available_ram;
702*61046927SAndroid Build Coastguard Worker    if (total_ram <= 4ULL * 1024ULL * 1024ULL * 1024ULL)
703*61046927SAndroid Build Coastguard Worker       available_ram = total_ram / 2U;
704*61046927SAndroid Build Coastguard Worker    else
705*61046927SAndroid Build Coastguard Worker       available_ram = total_ram * 3U / 4U;
706*61046927SAndroid Build Coastguard Worker 
707*61046927SAndroid Build Coastguard Worker    return available_ram;
708*61046927SAndroid Build Coastguard Worker }
709*61046927SAndroid Build Coastguard Worker 
pvr_physical_device_init(struct pvr_physical_device * pdevice,struct pvr_instance * instance,drmDevicePtr drm_render_device,drmDevicePtr drm_display_device)710*61046927SAndroid Build Coastguard Worker static VkResult pvr_physical_device_init(struct pvr_physical_device *pdevice,
711*61046927SAndroid Build Coastguard Worker                                          struct pvr_instance *instance,
712*61046927SAndroid Build Coastguard Worker                                          drmDevicePtr drm_render_device,
713*61046927SAndroid Build Coastguard Worker                                          drmDevicePtr drm_display_device)
714*61046927SAndroid Build Coastguard Worker {
715*61046927SAndroid Build Coastguard Worker    struct vk_physical_device_dispatch_table dispatch_table;
716*61046927SAndroid Build Coastguard Worker    struct vk_device_extension_table supported_extensions;
717*61046927SAndroid Build Coastguard Worker    struct vk_properties supported_properties;
718*61046927SAndroid Build Coastguard Worker    struct vk_features supported_features;
719*61046927SAndroid Build Coastguard Worker    struct pvr_winsys *ws;
720*61046927SAndroid Build Coastguard Worker    char *display_path;
721*61046927SAndroid Build Coastguard Worker    char *render_path;
722*61046927SAndroid Build Coastguard Worker    VkResult result;
723*61046927SAndroid Build Coastguard Worker 
724*61046927SAndroid Build Coastguard Worker    if (!getenv("PVR_I_WANT_A_BROKEN_VULKAN_DRIVER")) {
725*61046927SAndroid Build Coastguard Worker       return vk_errorf(instance,
726*61046927SAndroid Build Coastguard Worker                        VK_ERROR_INCOMPATIBLE_DRIVER,
727*61046927SAndroid Build Coastguard Worker                        "WARNING: powervr is not a conformant Vulkan "
728*61046927SAndroid Build Coastguard Worker                        "implementation. Pass "
729*61046927SAndroid Build Coastguard Worker                        "PVR_I_WANT_A_BROKEN_VULKAN_DRIVER=1 if you know "
730*61046927SAndroid Build Coastguard Worker                        "what you're doing.");
731*61046927SAndroid Build Coastguard Worker    }
732*61046927SAndroid Build Coastguard Worker 
733*61046927SAndroid Build Coastguard Worker    render_path = vk_strdup(&instance->vk.alloc,
734*61046927SAndroid Build Coastguard Worker                            drm_render_device->nodes[DRM_NODE_RENDER],
735*61046927SAndroid Build Coastguard Worker                            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
736*61046927SAndroid Build Coastguard Worker    if (!render_path) {
737*61046927SAndroid Build Coastguard Worker       result = VK_ERROR_OUT_OF_HOST_MEMORY;
738*61046927SAndroid Build Coastguard Worker       goto err_out;
739*61046927SAndroid Build Coastguard Worker    }
740*61046927SAndroid Build Coastguard Worker 
741*61046927SAndroid Build Coastguard Worker    if (instance->vk.enabled_extensions.KHR_display) {
742*61046927SAndroid Build Coastguard Worker       display_path = vk_strdup(&instance->vk.alloc,
743*61046927SAndroid Build Coastguard Worker                                drm_display_device->nodes[DRM_NODE_PRIMARY],
744*61046927SAndroid Build Coastguard Worker                                VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
745*61046927SAndroid Build Coastguard Worker       if (!display_path) {
746*61046927SAndroid Build Coastguard Worker          result = VK_ERROR_OUT_OF_HOST_MEMORY;
747*61046927SAndroid Build Coastguard Worker          goto err_vk_free_render_path;
748*61046927SAndroid Build Coastguard Worker       }
749*61046927SAndroid Build Coastguard Worker    } else {
750*61046927SAndroid Build Coastguard Worker       display_path = NULL;
751*61046927SAndroid Build Coastguard Worker    }
752*61046927SAndroid Build Coastguard Worker 
753*61046927SAndroid Build Coastguard Worker    result =
754*61046927SAndroid Build Coastguard Worker       pvr_winsys_create(render_path, display_path, &instance->vk.alloc, &ws);
755*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
756*61046927SAndroid Build Coastguard Worker       goto err_vk_free_display_path;
757*61046927SAndroid Build Coastguard Worker 
758*61046927SAndroid Build Coastguard Worker    pdevice->instance = instance;
759*61046927SAndroid Build Coastguard Worker    pdevice->render_path = render_path;
760*61046927SAndroid Build Coastguard Worker    pdevice->display_path = display_path;
761*61046927SAndroid Build Coastguard Worker    pdevice->ws = ws;
762*61046927SAndroid Build Coastguard Worker 
763*61046927SAndroid Build Coastguard Worker    result = ws->ops->device_info_init(ws,
764*61046927SAndroid Build Coastguard Worker                                       &pdevice->dev_info,
765*61046927SAndroid Build Coastguard Worker                                       &pdevice->dev_runtime_info);
766*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
767*61046927SAndroid Build Coastguard Worker       goto err_pvr_winsys_destroy;
768*61046927SAndroid Build Coastguard Worker 
769*61046927SAndroid Build Coastguard Worker    pvr_physical_device_get_supported_extensions(&supported_extensions);
770*61046927SAndroid Build Coastguard Worker    pvr_physical_device_get_supported_features(&pdevice->dev_info,
771*61046927SAndroid Build Coastguard Worker                                               &supported_features);
772*61046927SAndroid Build Coastguard Worker    if (!pvr_physical_device_get_properties(pdevice, &supported_properties)) {
773*61046927SAndroid Build Coastguard Worker       result = vk_errorf(instance,
774*61046927SAndroid Build Coastguard Worker                          VK_ERROR_INITIALIZATION_FAILED,
775*61046927SAndroid Build Coastguard Worker                          "Failed to collect physical device properties");
776*61046927SAndroid Build Coastguard Worker       goto err_pvr_winsys_destroy;
777*61046927SAndroid Build Coastguard Worker    }
778*61046927SAndroid Build Coastguard Worker 
779*61046927SAndroid Build Coastguard Worker    vk_physical_device_dispatch_table_from_entrypoints(
780*61046927SAndroid Build Coastguard Worker       &dispatch_table,
781*61046927SAndroid Build Coastguard Worker       &pvr_physical_device_entrypoints,
782*61046927SAndroid Build Coastguard Worker       true);
783*61046927SAndroid Build Coastguard Worker 
784*61046927SAndroid Build Coastguard Worker    vk_physical_device_dispatch_table_from_entrypoints(
785*61046927SAndroid Build Coastguard Worker       &dispatch_table,
786*61046927SAndroid Build Coastguard Worker       &wsi_physical_device_entrypoints,
787*61046927SAndroid Build Coastguard Worker       false);
788*61046927SAndroid Build Coastguard Worker 
789*61046927SAndroid Build Coastguard Worker    result = vk_physical_device_init(&pdevice->vk,
790*61046927SAndroid Build Coastguard Worker                                     &instance->vk,
791*61046927SAndroid Build Coastguard Worker                                     &supported_extensions,
792*61046927SAndroid Build Coastguard Worker                                     &supported_features,
793*61046927SAndroid Build Coastguard Worker                                     &supported_properties,
794*61046927SAndroid Build Coastguard Worker                                     &dispatch_table);
795*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
796*61046927SAndroid Build Coastguard Worker       goto err_pvr_winsys_destroy;
797*61046927SAndroid Build Coastguard Worker 
798*61046927SAndroid Build Coastguard Worker    pdevice->vk.supported_sync_types = ws->sync_types;
799*61046927SAndroid Build Coastguard Worker 
800*61046927SAndroid Build Coastguard Worker    /* Setup available memory heaps and types */
801*61046927SAndroid Build Coastguard Worker    pdevice->memory.memoryHeapCount = 1;
802*61046927SAndroid Build Coastguard Worker    pdevice->memory.memoryHeaps[0].size = pvr_compute_heap_size();
803*61046927SAndroid Build Coastguard Worker    pdevice->memory.memoryHeaps[0].flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
804*61046927SAndroid Build Coastguard Worker 
805*61046927SAndroid Build Coastguard Worker    pdevice->memory.memoryTypeCount = 1;
806*61046927SAndroid Build Coastguard Worker    pdevice->memory.memoryTypes[0].propertyFlags =
807*61046927SAndroid Build Coastguard Worker       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
808*61046927SAndroid Build Coastguard Worker       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
809*61046927SAndroid Build Coastguard Worker       VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
810*61046927SAndroid Build Coastguard Worker    pdevice->memory.memoryTypes[0].heapIndex = 0;
811*61046927SAndroid Build Coastguard Worker 
812*61046927SAndroid Build Coastguard Worker    result = pvr_wsi_init(pdevice);
813*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
814*61046927SAndroid Build Coastguard Worker       vk_error(instance, result);
815*61046927SAndroid Build Coastguard Worker       goto err_vk_physical_device_finish;
816*61046927SAndroid Build Coastguard Worker    }
817*61046927SAndroid Build Coastguard Worker 
818*61046927SAndroid Build Coastguard Worker    pdevice->compiler = rogue_compiler_create(&pdevice->dev_info);
819*61046927SAndroid Build Coastguard Worker    if (!pdevice->compiler) {
820*61046927SAndroid Build Coastguard Worker       result = vk_errorf(instance,
821*61046927SAndroid Build Coastguard Worker                          VK_ERROR_INITIALIZATION_FAILED,
822*61046927SAndroid Build Coastguard Worker                          "Failed to initialize Rogue compiler");
823*61046927SAndroid Build Coastguard Worker       goto err_wsi_finish;
824*61046927SAndroid Build Coastguard Worker    }
825*61046927SAndroid Build Coastguard Worker 
826*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
827*61046927SAndroid Build Coastguard Worker 
828*61046927SAndroid Build Coastguard Worker err_wsi_finish:
829*61046927SAndroid Build Coastguard Worker    pvr_wsi_finish(pdevice);
830*61046927SAndroid Build Coastguard Worker 
831*61046927SAndroid Build Coastguard Worker err_vk_physical_device_finish:
832*61046927SAndroid Build Coastguard Worker    vk_physical_device_finish(&pdevice->vk);
833*61046927SAndroid Build Coastguard Worker 
834*61046927SAndroid Build Coastguard Worker err_pvr_winsys_destroy:
835*61046927SAndroid Build Coastguard Worker    pvr_winsys_destroy(ws);
836*61046927SAndroid Build Coastguard Worker 
837*61046927SAndroid Build Coastguard Worker err_vk_free_display_path:
838*61046927SAndroid Build Coastguard Worker    vk_free(&instance->vk.alloc, display_path);
839*61046927SAndroid Build Coastguard Worker 
840*61046927SAndroid Build Coastguard Worker err_vk_free_render_path:
841*61046927SAndroid Build Coastguard Worker    vk_free(&instance->vk.alloc, render_path);
842*61046927SAndroid Build Coastguard Worker 
843*61046927SAndroid Build Coastguard Worker err_out:
844*61046927SAndroid Build Coastguard Worker    return result;
845*61046927SAndroid Build Coastguard Worker }
846*61046927SAndroid Build Coastguard Worker 
pvr_get_drm_devices(void * const obj,drmDevicePtr * const devices,const int max_devices,int * const num_devices_out)847*61046927SAndroid Build Coastguard Worker static VkResult pvr_get_drm_devices(void *const obj,
848*61046927SAndroid Build Coastguard Worker                                     drmDevicePtr *const devices,
849*61046927SAndroid Build Coastguard Worker                                     const int max_devices,
850*61046927SAndroid Build Coastguard Worker                                     int *const num_devices_out)
851*61046927SAndroid Build Coastguard Worker {
852*61046927SAndroid Build Coastguard Worker    int ret = drmGetDevices2(0, devices, max_devices);
853*61046927SAndroid Build Coastguard Worker    if (ret < 0) {
854*61046927SAndroid Build Coastguard Worker       return vk_errorf(obj,
855*61046927SAndroid Build Coastguard Worker                        VK_ERROR_INITIALIZATION_FAILED,
856*61046927SAndroid Build Coastguard Worker                        "Failed to enumerate drm devices (errno %d: %s)",
857*61046927SAndroid Build Coastguard Worker                        -ret,
858*61046927SAndroid Build Coastguard Worker                        strerror(-ret));
859*61046927SAndroid Build Coastguard Worker    }
860*61046927SAndroid Build Coastguard Worker 
861*61046927SAndroid Build Coastguard Worker    if (num_devices_out)
862*61046927SAndroid Build Coastguard Worker       *num_devices_out = ret;
863*61046927SAndroid Build Coastguard Worker 
864*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
865*61046927SAndroid Build Coastguard Worker }
866*61046927SAndroid Build Coastguard Worker 
867*61046927SAndroid Build Coastguard Worker static bool
pvr_drm_device_compatible(const struct pvr_drm_device_info * const info,drmDevice * const drm_dev)868*61046927SAndroid Build Coastguard Worker pvr_drm_device_compatible(const struct pvr_drm_device_info *const info,
869*61046927SAndroid Build Coastguard Worker                           drmDevice *const drm_dev)
870*61046927SAndroid Build Coastguard Worker {
871*61046927SAndroid Build Coastguard Worker    char **const compatible = drm_dev->deviceinfo.platform->compatible;
872*61046927SAndroid Build Coastguard Worker 
873*61046927SAndroid Build Coastguard Worker    for (char **compat = compatible; *compat; compat++) {
874*61046927SAndroid Build Coastguard Worker       if (strncmp(*compat, info->name, info->len) == 0)
875*61046927SAndroid Build Coastguard Worker          return true;
876*61046927SAndroid Build Coastguard Worker    }
877*61046927SAndroid Build Coastguard Worker 
878*61046927SAndroid Build Coastguard Worker    return false;
879*61046927SAndroid Build Coastguard Worker }
880*61046927SAndroid Build Coastguard Worker 
881*61046927SAndroid Build Coastguard Worker static const struct pvr_drm_device_config *
pvr_drm_device_get_config(drmDevice * const drm_dev)882*61046927SAndroid Build Coastguard Worker pvr_drm_device_get_config(drmDevice *const drm_dev)
883*61046927SAndroid Build Coastguard Worker {
884*61046927SAndroid Build Coastguard Worker    for (size_t i = 0U; i < ARRAY_SIZE(pvr_drm_configs); i++) {
885*61046927SAndroid Build Coastguard Worker       if (pvr_drm_device_compatible(&pvr_drm_configs[i].render, drm_dev))
886*61046927SAndroid Build Coastguard Worker          return &pvr_drm_configs[i];
887*61046927SAndroid Build Coastguard Worker    }
888*61046927SAndroid Build Coastguard Worker 
889*61046927SAndroid Build Coastguard Worker    return NULL;
890*61046927SAndroid Build Coastguard Worker }
891*61046927SAndroid Build Coastguard Worker 
892*61046927SAndroid Build Coastguard Worker static void
pvr_physical_device_dump_info(const struct pvr_physical_device * pdevice,char * const * comp_display,char * const * comp_render)893*61046927SAndroid Build Coastguard Worker pvr_physical_device_dump_info(const struct pvr_physical_device *pdevice,
894*61046927SAndroid Build Coastguard Worker                               char *const *comp_display,
895*61046927SAndroid Build Coastguard Worker                               char *const *comp_render)
896*61046927SAndroid Build Coastguard Worker {
897*61046927SAndroid Build Coastguard Worker    drmVersionPtr version_display, version_render;
898*61046927SAndroid Build Coastguard Worker    struct pvr_device_dump_info info;
899*61046927SAndroid Build Coastguard Worker 
900*61046927SAndroid Build Coastguard Worker    version_display = drmGetVersion(pdevice->ws->display_fd);
901*61046927SAndroid Build Coastguard Worker    if (!version_display)
902*61046927SAndroid Build Coastguard Worker       return;
903*61046927SAndroid Build Coastguard Worker 
904*61046927SAndroid Build Coastguard Worker    version_render = drmGetVersion(pdevice->ws->render_fd);
905*61046927SAndroid Build Coastguard Worker    if (!version_render) {
906*61046927SAndroid Build Coastguard Worker       drmFreeVersion(version_display);
907*61046927SAndroid Build Coastguard Worker       return;
908*61046927SAndroid Build Coastguard Worker    }
909*61046927SAndroid Build Coastguard Worker 
910*61046927SAndroid Build Coastguard Worker    info.device_info = &pdevice->dev_info;
911*61046927SAndroid Build Coastguard Worker    info.device_runtime_info = &pdevice->dev_runtime_info;
912*61046927SAndroid Build Coastguard Worker    info.drm_display.patchlevel = version_display->version_patchlevel;
913*61046927SAndroid Build Coastguard Worker    info.drm_display.major = version_display->version_major;
914*61046927SAndroid Build Coastguard Worker    info.drm_display.minor = version_display->version_minor;
915*61046927SAndroid Build Coastguard Worker    info.drm_display.name = version_display->name;
916*61046927SAndroid Build Coastguard Worker    info.drm_display.date = version_display->date;
917*61046927SAndroid Build Coastguard Worker    info.drm_display.comp = comp_display;
918*61046927SAndroid Build Coastguard Worker    info.drm_render.patchlevel = version_render->version_patchlevel;
919*61046927SAndroid Build Coastguard Worker    info.drm_render.major = version_render->version_major;
920*61046927SAndroid Build Coastguard Worker    info.drm_render.minor = version_render->version_minor;
921*61046927SAndroid Build Coastguard Worker    info.drm_render.name = version_render->name;
922*61046927SAndroid Build Coastguard Worker    info.drm_render.date = version_render->date;
923*61046927SAndroid Build Coastguard Worker    info.drm_render.comp = comp_render;
924*61046927SAndroid Build Coastguard Worker 
925*61046927SAndroid Build Coastguard Worker    pvr_dump_physical_device_info(&info);
926*61046927SAndroid Build Coastguard Worker 
927*61046927SAndroid Build Coastguard Worker    drmFreeVersion(version_display);
928*61046927SAndroid Build Coastguard Worker    drmFreeVersion(version_render);
929*61046927SAndroid Build Coastguard Worker }
930*61046927SAndroid Build Coastguard Worker 
931*61046927SAndroid Build Coastguard Worker static VkResult
pvr_physical_device_enumerate(struct vk_instance * const vk_instance)932*61046927SAndroid Build Coastguard Worker pvr_physical_device_enumerate(struct vk_instance *const vk_instance)
933*61046927SAndroid Build Coastguard Worker {
934*61046927SAndroid Build Coastguard Worker    struct pvr_instance *const instance =
935*61046927SAndroid Build Coastguard Worker       container_of(vk_instance, struct pvr_instance, vk);
936*61046927SAndroid Build Coastguard Worker 
937*61046927SAndroid Build Coastguard Worker    const struct pvr_drm_device_config *config = NULL;
938*61046927SAndroid Build Coastguard Worker 
939*61046927SAndroid Build Coastguard Worker    drmDevicePtr drm_display_device = NULL;
940*61046927SAndroid Build Coastguard Worker    drmDevicePtr drm_render_device = NULL;
941*61046927SAndroid Build Coastguard Worker    struct pvr_physical_device *pdevice;
942*61046927SAndroid Build Coastguard Worker    drmDevicePtr *drm_devices;
943*61046927SAndroid Build Coastguard Worker    int num_drm_devices = 0;
944*61046927SAndroid Build Coastguard Worker    VkResult result;
945*61046927SAndroid Build Coastguard Worker 
946*61046927SAndroid Build Coastguard Worker    result = pvr_get_drm_devices(instance, NULL, 0, &num_drm_devices);
947*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
948*61046927SAndroid Build Coastguard Worker       goto out;
949*61046927SAndroid Build Coastguard Worker 
950*61046927SAndroid Build Coastguard Worker    if (num_drm_devices == 0) {
951*61046927SAndroid Build Coastguard Worker       result = VK_SUCCESS;
952*61046927SAndroid Build Coastguard Worker       goto out;
953*61046927SAndroid Build Coastguard Worker    }
954*61046927SAndroid Build Coastguard Worker 
955*61046927SAndroid Build Coastguard Worker    drm_devices = vk_alloc(&vk_instance->alloc,
956*61046927SAndroid Build Coastguard Worker                           sizeof(*drm_devices) * num_drm_devices,
957*61046927SAndroid Build Coastguard Worker                           8,
958*61046927SAndroid Build Coastguard Worker                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
959*61046927SAndroid Build Coastguard Worker    if (!drm_devices) {
960*61046927SAndroid Build Coastguard Worker       result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
961*61046927SAndroid Build Coastguard Worker       goto out;
962*61046927SAndroid Build Coastguard Worker    }
963*61046927SAndroid Build Coastguard Worker 
964*61046927SAndroid Build Coastguard Worker    result = pvr_get_drm_devices(instance, drm_devices, num_drm_devices, NULL);
965*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
966*61046927SAndroid Build Coastguard Worker       goto out_free_drm_device_ptrs;
967*61046927SAndroid Build Coastguard Worker 
968*61046927SAndroid Build Coastguard Worker    /* First search for our render node... */
969*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < num_drm_devices; i++) {
970*61046927SAndroid Build Coastguard Worker       drmDevice *const drm_dev = drm_devices[i];
971*61046927SAndroid Build Coastguard Worker 
972*61046927SAndroid Build Coastguard Worker       if (drm_dev->bustype != DRM_BUS_PLATFORM)
973*61046927SAndroid Build Coastguard Worker          continue;
974*61046927SAndroid Build Coastguard Worker 
975*61046927SAndroid Build Coastguard Worker       if (!(drm_dev->available_nodes & BITFIELD_BIT(DRM_NODE_RENDER)))
976*61046927SAndroid Build Coastguard Worker          continue;
977*61046927SAndroid Build Coastguard Worker 
978*61046927SAndroid Build Coastguard Worker       config = pvr_drm_device_get_config(drm_dev);
979*61046927SAndroid Build Coastguard Worker       if (config) {
980*61046927SAndroid Build Coastguard Worker          drm_render_device = drm_dev;
981*61046927SAndroid Build Coastguard Worker          break;
982*61046927SAndroid Build Coastguard Worker       }
983*61046927SAndroid Build Coastguard Worker    }
984*61046927SAndroid Build Coastguard Worker 
985*61046927SAndroid Build Coastguard Worker    if (!config) {
986*61046927SAndroid Build Coastguard Worker       result = VK_SUCCESS;
987*61046927SAndroid Build Coastguard Worker       goto out_free_drm_devices;
988*61046927SAndroid Build Coastguard Worker    }
989*61046927SAndroid Build Coastguard Worker 
990*61046927SAndroid Build Coastguard Worker    mesa_logd("Found compatible render device '%s'.",
991*61046927SAndroid Build Coastguard Worker              drm_render_device->nodes[DRM_NODE_RENDER]);
992*61046927SAndroid Build Coastguard Worker 
993*61046927SAndroid Build Coastguard Worker    /* ...then find the compatible display node. */
994*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < num_drm_devices; i++) {
995*61046927SAndroid Build Coastguard Worker       drmDevice *const drm_dev = drm_devices[i];
996*61046927SAndroid Build Coastguard Worker 
997*61046927SAndroid Build Coastguard Worker       if (!(drm_dev->available_nodes & BITFIELD_BIT(DRM_NODE_PRIMARY)))
998*61046927SAndroid Build Coastguard Worker          continue;
999*61046927SAndroid Build Coastguard Worker 
1000*61046927SAndroid Build Coastguard Worker       if (pvr_drm_device_compatible(&config->display, drm_dev)) {
1001*61046927SAndroid Build Coastguard Worker          drm_display_device = drm_dev;
1002*61046927SAndroid Build Coastguard Worker          break;
1003*61046927SAndroid Build Coastguard Worker       }
1004*61046927SAndroid Build Coastguard Worker    }
1005*61046927SAndroid Build Coastguard Worker 
1006*61046927SAndroid Build Coastguard Worker    if (!drm_display_device) {
1007*61046927SAndroid Build Coastguard Worker       mesa_loge("Render device '%s' has no compatible display device.",
1008*61046927SAndroid Build Coastguard Worker                 drm_render_device->nodes[DRM_NODE_RENDER]);
1009*61046927SAndroid Build Coastguard Worker       result = VK_SUCCESS;
1010*61046927SAndroid Build Coastguard Worker       goto out_free_drm_devices;
1011*61046927SAndroid Build Coastguard Worker    }
1012*61046927SAndroid Build Coastguard Worker 
1013*61046927SAndroid Build Coastguard Worker    mesa_logd("Found compatible display device '%s'.",
1014*61046927SAndroid Build Coastguard Worker              drm_display_device->nodes[DRM_NODE_PRIMARY]);
1015*61046927SAndroid Build Coastguard Worker 
1016*61046927SAndroid Build Coastguard Worker    pdevice = vk_zalloc(&vk_instance->alloc,
1017*61046927SAndroid Build Coastguard Worker                        sizeof(*pdevice),
1018*61046927SAndroid Build Coastguard Worker                        8,
1019*61046927SAndroid Build Coastguard Worker                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1020*61046927SAndroid Build Coastguard Worker    if (!pdevice) {
1021*61046927SAndroid Build Coastguard Worker       result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1022*61046927SAndroid Build Coastguard Worker       goto out_free_drm_devices;
1023*61046927SAndroid Build Coastguard Worker    }
1024*61046927SAndroid Build Coastguard Worker 
1025*61046927SAndroid Build Coastguard Worker    result = pvr_physical_device_init(pdevice,
1026*61046927SAndroid Build Coastguard Worker                                      instance,
1027*61046927SAndroid Build Coastguard Worker                                      drm_render_device,
1028*61046927SAndroid Build Coastguard Worker                                      drm_display_device);
1029*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
1030*61046927SAndroid Build Coastguard Worker       if (result == VK_ERROR_INCOMPATIBLE_DRIVER)
1031*61046927SAndroid Build Coastguard Worker          result = VK_SUCCESS;
1032*61046927SAndroid Build Coastguard Worker 
1033*61046927SAndroid Build Coastguard Worker       goto err_free_pdevice;
1034*61046927SAndroid Build Coastguard Worker    }
1035*61046927SAndroid Build Coastguard Worker 
1036*61046927SAndroid Build Coastguard Worker    if (PVR_IS_DEBUG_SET(INFO)) {
1037*61046927SAndroid Build Coastguard Worker       pvr_physical_device_dump_info(
1038*61046927SAndroid Build Coastguard Worker          pdevice,
1039*61046927SAndroid Build Coastguard Worker          drm_display_device->deviceinfo.platform->compatible,
1040*61046927SAndroid Build Coastguard Worker          drm_render_device->deviceinfo.platform->compatible);
1041*61046927SAndroid Build Coastguard Worker    }
1042*61046927SAndroid Build Coastguard Worker 
1043*61046927SAndroid Build Coastguard Worker    list_add(&pdevice->vk.link, &vk_instance->physical_devices.list);
1044*61046927SAndroid Build Coastguard Worker 
1045*61046927SAndroid Build Coastguard Worker    result = VK_SUCCESS;
1046*61046927SAndroid Build Coastguard Worker    goto out_free_drm_devices;
1047*61046927SAndroid Build Coastguard Worker 
1048*61046927SAndroid Build Coastguard Worker err_free_pdevice:
1049*61046927SAndroid Build Coastguard Worker    vk_free(&vk_instance->alloc, pdevice);
1050*61046927SAndroid Build Coastguard Worker 
1051*61046927SAndroid Build Coastguard Worker out_free_drm_devices:
1052*61046927SAndroid Build Coastguard Worker    drmFreeDevices(drm_devices, num_drm_devices);
1053*61046927SAndroid Build Coastguard Worker 
1054*61046927SAndroid Build Coastguard Worker out_free_drm_device_ptrs:
1055*61046927SAndroid Build Coastguard Worker    vk_free(&vk_instance->alloc, drm_devices);
1056*61046927SAndroid Build Coastguard Worker 
1057*61046927SAndroid Build Coastguard Worker out:
1058*61046927SAndroid Build Coastguard Worker    return result;
1059*61046927SAndroid Build Coastguard Worker }
1060*61046927SAndroid Build Coastguard Worker 
pvr_CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)1061*61046927SAndroid Build Coastguard Worker VkResult pvr_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
1062*61046927SAndroid Build Coastguard Worker                             const VkAllocationCallbacks *pAllocator,
1063*61046927SAndroid Build Coastguard Worker                             VkInstance *pInstance)
1064*61046927SAndroid Build Coastguard Worker {
1065*61046927SAndroid Build Coastguard Worker    struct vk_instance_dispatch_table dispatch_table;
1066*61046927SAndroid Build Coastguard Worker    struct pvr_instance *instance;
1067*61046927SAndroid Build Coastguard Worker    VkResult result;
1068*61046927SAndroid Build Coastguard Worker 
1069*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
1070*61046927SAndroid Build Coastguard Worker 
1071*61046927SAndroid Build Coastguard Worker    if (!pAllocator)
1072*61046927SAndroid Build Coastguard Worker       pAllocator = vk_default_allocator();
1073*61046927SAndroid Build Coastguard Worker 
1074*61046927SAndroid Build Coastguard Worker    instance = vk_alloc(pAllocator,
1075*61046927SAndroid Build Coastguard Worker                        sizeof(*instance),
1076*61046927SAndroid Build Coastguard Worker                        8,
1077*61046927SAndroid Build Coastguard Worker                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
1078*61046927SAndroid Build Coastguard Worker    if (!instance)
1079*61046927SAndroid Build Coastguard Worker       return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
1080*61046927SAndroid Build Coastguard Worker 
1081*61046927SAndroid Build Coastguard Worker    vk_instance_dispatch_table_from_entrypoints(&dispatch_table,
1082*61046927SAndroid Build Coastguard Worker                                                &pvr_instance_entrypoints,
1083*61046927SAndroid Build Coastguard Worker                                                true);
1084*61046927SAndroid Build Coastguard Worker 
1085*61046927SAndroid Build Coastguard Worker    vk_instance_dispatch_table_from_entrypoints(&dispatch_table,
1086*61046927SAndroid Build Coastguard Worker                                                &wsi_instance_entrypoints,
1087*61046927SAndroid Build Coastguard Worker                                                false);
1088*61046927SAndroid Build Coastguard Worker 
1089*61046927SAndroid Build Coastguard Worker    result = vk_instance_init(&instance->vk,
1090*61046927SAndroid Build Coastguard Worker                              &pvr_instance_extensions,
1091*61046927SAndroid Build Coastguard Worker                              &dispatch_table,
1092*61046927SAndroid Build Coastguard Worker                              pCreateInfo,
1093*61046927SAndroid Build Coastguard Worker                              pAllocator);
1094*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
1095*61046927SAndroid Build Coastguard Worker       vk_free(pAllocator, instance);
1096*61046927SAndroid Build Coastguard Worker       return result;
1097*61046927SAndroid Build Coastguard Worker    }
1098*61046927SAndroid Build Coastguard Worker 
1099*61046927SAndroid Build Coastguard Worker    pvr_process_debug_variable();
1100*61046927SAndroid Build Coastguard Worker 
1101*61046927SAndroid Build Coastguard Worker    instance->active_device_count = 0;
1102*61046927SAndroid Build Coastguard Worker 
1103*61046927SAndroid Build Coastguard Worker    instance->vk.physical_devices.enumerate = pvr_physical_device_enumerate;
1104*61046927SAndroid Build Coastguard Worker    instance->vk.physical_devices.destroy = pvr_physical_device_destroy;
1105*61046927SAndroid Build Coastguard Worker 
1106*61046927SAndroid Build Coastguard Worker    VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
1107*61046927SAndroid Build Coastguard Worker 
1108*61046927SAndroid Build Coastguard Worker    *pInstance = pvr_instance_to_handle(instance);
1109*61046927SAndroid Build Coastguard Worker 
1110*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1111*61046927SAndroid Build Coastguard Worker }
1112*61046927SAndroid Build Coastguard Worker 
pvr_get_simultaneous_num_allocs(const struct pvr_device_info * dev_info,ASSERTED const struct pvr_device_runtime_info * dev_runtime_info)1113*61046927SAndroid Build Coastguard Worker static uint32_t pvr_get_simultaneous_num_allocs(
1114*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *dev_info,
1115*61046927SAndroid Build Coastguard Worker    ASSERTED const struct pvr_device_runtime_info *dev_runtime_info)
1116*61046927SAndroid Build Coastguard Worker {
1117*61046927SAndroid Build Coastguard Worker    uint32_t min_cluster_per_phantom;
1118*61046927SAndroid Build Coastguard Worker 
1119*61046927SAndroid Build Coastguard Worker    if (PVR_HAS_FEATURE(dev_info, s8xe))
1120*61046927SAndroid Build Coastguard Worker       return PVR_GET_FEATURE_VALUE(dev_info, num_raster_pipes, 0U);
1121*61046927SAndroid Build Coastguard Worker 
1122*61046927SAndroid Build Coastguard Worker    assert(dev_runtime_info->num_phantoms == 1);
1123*61046927SAndroid Build Coastguard Worker    min_cluster_per_phantom = PVR_GET_FEATURE_VALUE(dev_info, num_clusters, 1U);
1124*61046927SAndroid Build Coastguard Worker 
1125*61046927SAndroid Build Coastguard Worker    if (min_cluster_per_phantom >= 4)
1126*61046927SAndroid Build Coastguard Worker       return 1;
1127*61046927SAndroid Build Coastguard Worker    else if (min_cluster_per_phantom == 2)
1128*61046927SAndroid Build Coastguard Worker       return 2;
1129*61046927SAndroid Build Coastguard Worker    else
1130*61046927SAndroid Build Coastguard Worker       return 4;
1131*61046927SAndroid Build Coastguard Worker }
1132*61046927SAndroid Build Coastguard Worker 
pvr_calc_fscommon_size_and_tiles_in_flight(const struct pvr_device_info * dev_info,const struct pvr_device_runtime_info * dev_runtime_info,uint32_t fs_common_size,uint32_t min_tiles_in_flight)1133*61046927SAndroid Build Coastguard Worker uint32_t pvr_calc_fscommon_size_and_tiles_in_flight(
1134*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *dev_info,
1135*61046927SAndroid Build Coastguard Worker    const struct pvr_device_runtime_info *dev_runtime_info,
1136*61046927SAndroid Build Coastguard Worker    uint32_t fs_common_size,
1137*61046927SAndroid Build Coastguard Worker    uint32_t min_tiles_in_flight)
1138*61046927SAndroid Build Coastguard Worker {
1139*61046927SAndroid Build Coastguard Worker    const uint32_t available_shareds =
1140*61046927SAndroid Build Coastguard Worker       dev_runtime_info->reserved_shared_size - dev_runtime_info->max_coeffs;
1141*61046927SAndroid Build Coastguard Worker    const uint32_t max_tiles_in_flight =
1142*61046927SAndroid Build Coastguard Worker       PVR_GET_FEATURE_VALUE(dev_info, isp_max_tiles_in_flight, 1U);
1143*61046927SAndroid Build Coastguard Worker    uint32_t num_tile_in_flight;
1144*61046927SAndroid Build Coastguard Worker    uint32_t num_allocs;
1145*61046927SAndroid Build Coastguard Worker 
1146*61046927SAndroid Build Coastguard Worker    if (fs_common_size == 0)
1147*61046927SAndroid Build Coastguard Worker       return max_tiles_in_flight;
1148*61046927SAndroid Build Coastguard Worker 
1149*61046927SAndroid Build Coastguard Worker    num_allocs = pvr_get_simultaneous_num_allocs(dev_info, dev_runtime_info);
1150*61046927SAndroid Build Coastguard Worker 
1151*61046927SAndroid Build Coastguard Worker    if (fs_common_size == UINT32_MAX) {
1152*61046927SAndroid Build Coastguard Worker       uint32_t max_common_size = available_shareds;
1153*61046927SAndroid Build Coastguard Worker 
1154*61046927SAndroid Build Coastguard Worker       num_allocs *= MIN2(min_tiles_in_flight, max_tiles_in_flight);
1155*61046927SAndroid Build Coastguard Worker 
1156*61046927SAndroid Build Coastguard Worker       if (!PVR_HAS_ERN(dev_info, 38748)) {
1157*61046927SAndroid Build Coastguard Worker          /* Hardware needs space for one extra shared allocation. */
1158*61046927SAndroid Build Coastguard Worker          num_allocs += 1;
1159*61046927SAndroid Build Coastguard Worker       }
1160*61046927SAndroid Build Coastguard Worker 
1161*61046927SAndroid Build Coastguard Worker       /* Double resource requirements to deal with fragmentation. */
1162*61046927SAndroid Build Coastguard Worker       max_common_size /= num_allocs * 2;
1163*61046927SAndroid Build Coastguard Worker       max_common_size = MIN2(max_common_size, ROGUE_MAX_PIXEL_SHARED_REGISTERS);
1164*61046927SAndroid Build Coastguard Worker       max_common_size =
1165*61046927SAndroid Build Coastguard Worker          ROUND_DOWN_TO(max_common_size,
1166*61046927SAndroid Build Coastguard Worker                        PVRX(TA_STATE_PDS_SIZEINFO2_USC_SHAREDSIZE_UNIT_SIZE));
1167*61046927SAndroid Build Coastguard Worker 
1168*61046927SAndroid Build Coastguard Worker       return max_common_size;
1169*61046927SAndroid Build Coastguard Worker    }
1170*61046927SAndroid Build Coastguard Worker 
1171*61046927SAndroid Build Coastguard Worker    num_tile_in_flight = available_shareds / (fs_common_size * 2);
1172*61046927SAndroid Build Coastguard Worker 
1173*61046927SAndroid Build Coastguard Worker    if (!PVR_HAS_ERN(dev_info, 38748))
1174*61046927SAndroid Build Coastguard Worker       num_tile_in_flight -= 1;
1175*61046927SAndroid Build Coastguard Worker 
1176*61046927SAndroid Build Coastguard Worker    num_tile_in_flight /= num_allocs;
1177*61046927SAndroid Build Coastguard Worker 
1178*61046927SAndroid Build Coastguard Worker #if MESA_DEBUG
1179*61046927SAndroid Build Coastguard Worker    /* Validate the above result. */
1180*61046927SAndroid Build Coastguard Worker 
1181*61046927SAndroid Build Coastguard Worker    assert(num_tile_in_flight >= MIN2(num_tile_in_flight, max_tiles_in_flight));
1182*61046927SAndroid Build Coastguard Worker    num_allocs *= num_tile_in_flight;
1183*61046927SAndroid Build Coastguard Worker 
1184*61046927SAndroid Build Coastguard Worker    if (!PVR_HAS_ERN(dev_info, 38748)) {
1185*61046927SAndroid Build Coastguard Worker       /* Hardware needs space for one extra shared allocation. */
1186*61046927SAndroid Build Coastguard Worker       num_allocs += 1;
1187*61046927SAndroid Build Coastguard Worker    }
1188*61046927SAndroid Build Coastguard Worker 
1189*61046927SAndroid Build Coastguard Worker    assert(fs_common_size <= available_shareds / (num_allocs * 2));
1190*61046927SAndroid Build Coastguard Worker #endif
1191*61046927SAndroid Build Coastguard Worker 
1192*61046927SAndroid Build Coastguard Worker    return MIN2(num_tile_in_flight, max_tiles_in_flight);
1193*61046927SAndroid Build Coastguard Worker }
1194*61046927SAndroid Build Coastguard Worker 
1195*61046927SAndroid Build Coastguard Worker const static VkQueueFamilyProperties pvr_queue_family_properties = {
1196*61046927SAndroid Build Coastguard Worker    .queueFlags = VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT |
1197*61046927SAndroid Build Coastguard Worker                  VK_QUEUE_TRANSFER_BIT,
1198*61046927SAndroid Build Coastguard Worker    .queueCount = PVR_MAX_QUEUES,
1199*61046927SAndroid Build Coastguard Worker    .timestampValidBits = 0,
1200*61046927SAndroid Build Coastguard Worker    .minImageTransferGranularity = { 1, 1, 1 },
1201*61046927SAndroid Build Coastguard Worker };
1202*61046927SAndroid Build Coastguard Worker 
pvr_compute_heap_budget(struct pvr_physical_device * pdevice)1203*61046927SAndroid Build Coastguard Worker static uint64_t pvr_compute_heap_budget(struct pvr_physical_device *pdevice)
1204*61046927SAndroid Build Coastguard Worker {
1205*61046927SAndroid Build Coastguard Worker    const uint64_t heap_size = pdevice->memory.memoryHeaps[0].size;
1206*61046927SAndroid Build Coastguard Worker    const uint64_t heap_used = pdevice->heap_used;
1207*61046927SAndroid Build Coastguard Worker    uint64_t sys_available = 0, heap_available;
1208*61046927SAndroid Build Coastguard Worker    ASSERTED bool has_available_memory =
1209*61046927SAndroid Build Coastguard Worker       os_get_available_system_memory(&sys_available);
1210*61046927SAndroid Build Coastguard Worker    assert(has_available_memory);
1211*61046927SAndroid Build Coastguard Worker 
1212*61046927SAndroid Build Coastguard Worker    /* Let's not incite the app to starve the system: report at most 90% of
1213*61046927SAndroid Build Coastguard Worker     * available system memory.
1214*61046927SAndroid Build Coastguard Worker     */
1215*61046927SAndroid Build Coastguard Worker    heap_available = sys_available * 9 / 10;
1216*61046927SAndroid Build Coastguard Worker    return MIN2(heap_size, heap_used + heap_available);
1217*61046927SAndroid Build Coastguard Worker }
1218*61046927SAndroid Build Coastguard Worker 
pvr_GetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice,uint32_t * pQueueFamilyPropertyCount,VkQueueFamilyProperties2 * pQueueFamilyProperties)1219*61046927SAndroid Build Coastguard Worker void pvr_GetPhysicalDeviceQueueFamilyProperties2(
1220*61046927SAndroid Build Coastguard Worker    VkPhysicalDevice physicalDevice,
1221*61046927SAndroid Build Coastguard Worker    uint32_t *pQueueFamilyPropertyCount,
1222*61046927SAndroid Build Coastguard Worker    VkQueueFamilyProperties2 *pQueueFamilyProperties)
1223*61046927SAndroid Build Coastguard Worker {
1224*61046927SAndroid Build Coastguard Worker    VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2,
1225*61046927SAndroid Build Coastguard Worker                           out,
1226*61046927SAndroid Build Coastguard Worker                           pQueueFamilyProperties,
1227*61046927SAndroid Build Coastguard Worker                           pQueueFamilyPropertyCount);
1228*61046927SAndroid Build Coastguard Worker 
1229*61046927SAndroid Build Coastguard Worker    vk_outarray_append_typed (VkQueueFamilyProperties2, &out, p) {
1230*61046927SAndroid Build Coastguard Worker       p->queueFamilyProperties = pvr_queue_family_properties;
1231*61046927SAndroid Build Coastguard Worker 
1232*61046927SAndroid Build Coastguard Worker       vk_foreach_struct (ext, p->pNext) {
1233*61046927SAndroid Build Coastguard Worker          vk_debug_ignored_stype(ext->sType);
1234*61046927SAndroid Build Coastguard Worker       }
1235*61046927SAndroid Build Coastguard Worker    }
1236*61046927SAndroid Build Coastguard Worker }
1237*61046927SAndroid Build Coastguard Worker 
pvr_GetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice,VkPhysicalDeviceMemoryProperties2 * pMemoryProperties)1238*61046927SAndroid Build Coastguard Worker void pvr_GetPhysicalDeviceMemoryProperties2(
1239*61046927SAndroid Build Coastguard Worker    VkPhysicalDevice physicalDevice,
1240*61046927SAndroid Build Coastguard Worker    VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
1241*61046927SAndroid Build Coastguard Worker {
1242*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_physical_device, pdevice, physicalDevice);
1243*61046927SAndroid Build Coastguard Worker 
1244*61046927SAndroid Build Coastguard Worker    pMemoryProperties->memoryProperties = pdevice->memory;
1245*61046927SAndroid Build Coastguard Worker 
1246*61046927SAndroid Build Coastguard Worker    vk_foreach_struct (ext, pMemoryProperties->pNext) {
1247*61046927SAndroid Build Coastguard Worker       switch (ext->sType) {
1248*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT: {
1249*61046927SAndroid Build Coastguard Worker          VkPhysicalDeviceMemoryBudgetPropertiesEXT *pMemoryBudget =
1250*61046927SAndroid Build Coastguard Worker             (VkPhysicalDeviceMemoryBudgetPropertiesEXT *)ext;
1251*61046927SAndroid Build Coastguard Worker 
1252*61046927SAndroid Build Coastguard Worker          pMemoryBudget->heapBudget[0] = pvr_compute_heap_budget(pdevice);
1253*61046927SAndroid Build Coastguard Worker          pMemoryBudget->heapUsage[0] = pdevice->heap_used;
1254*61046927SAndroid Build Coastguard Worker 
1255*61046927SAndroid Build Coastguard Worker          for (uint32_t i = 1; i < VK_MAX_MEMORY_HEAPS; i++) {
1256*61046927SAndroid Build Coastguard Worker             pMemoryBudget->heapBudget[i] = 0u;
1257*61046927SAndroid Build Coastguard Worker             pMemoryBudget->heapUsage[i] = 0u;
1258*61046927SAndroid Build Coastguard Worker          }
1259*61046927SAndroid Build Coastguard Worker          break;
1260*61046927SAndroid Build Coastguard Worker       }
1261*61046927SAndroid Build Coastguard Worker       default:
1262*61046927SAndroid Build Coastguard Worker          vk_debug_ignored_stype(ext->sType);
1263*61046927SAndroid Build Coastguard Worker          break;
1264*61046927SAndroid Build Coastguard Worker       }
1265*61046927SAndroid Build Coastguard Worker    }
1266*61046927SAndroid Build Coastguard Worker }
1267*61046927SAndroid Build Coastguard Worker 
pvr_GetInstanceProcAddr(VkInstance _instance,const char * pName)1268*61046927SAndroid Build Coastguard Worker PFN_vkVoidFunction pvr_GetInstanceProcAddr(VkInstance _instance,
1269*61046927SAndroid Build Coastguard Worker                                            const char *pName)
1270*61046927SAndroid Build Coastguard Worker {
1271*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_instance, instance, _instance);
1272*61046927SAndroid Build Coastguard Worker    return vk_instance_get_proc_addr(&instance->vk,
1273*61046927SAndroid Build Coastguard Worker                                     &pvr_instance_entrypoints,
1274*61046927SAndroid Build Coastguard Worker                                     pName);
1275*61046927SAndroid Build Coastguard Worker }
1276*61046927SAndroid Build Coastguard Worker 
1277*61046927SAndroid Build Coastguard Worker /* With version 1+ of the loader interface the ICD should expose
1278*61046927SAndroid Build Coastguard Worker  * vk_icdGetInstanceProcAddr to work around certain LD_PRELOAD issues seen in
1279*61046927SAndroid Build Coastguard Worker  * apps.
1280*61046927SAndroid Build Coastguard Worker  */
1281*61046927SAndroid Build Coastguard Worker PUBLIC
1282*61046927SAndroid Build Coastguard Worker VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vk_icdGetInstanceProcAddr(VkInstance instance,const char * pName)1283*61046927SAndroid Build Coastguard Worker vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName)
1284*61046927SAndroid Build Coastguard Worker {
1285*61046927SAndroid Build Coastguard Worker    return pvr_GetInstanceProcAddr(instance, pName);
1286*61046927SAndroid Build Coastguard Worker }
1287*61046927SAndroid Build Coastguard Worker 
pvr_pds_compute_shader_create_and_upload(struct pvr_device * device,struct pvr_pds_compute_shader_program * program,struct pvr_pds_upload * const pds_upload_out)1288*61046927SAndroid Build Coastguard Worker VkResult pvr_pds_compute_shader_create_and_upload(
1289*61046927SAndroid Build Coastguard Worker    struct pvr_device *device,
1290*61046927SAndroid Build Coastguard Worker    struct pvr_pds_compute_shader_program *program,
1291*61046927SAndroid Build Coastguard Worker    struct pvr_pds_upload *const pds_upload_out)
1292*61046927SAndroid Build Coastguard Worker {
1293*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
1294*61046927SAndroid Build Coastguard Worker    const uint32_t cache_line_size = rogue_get_slc_cache_line_size(dev_info);
1295*61046927SAndroid Build Coastguard Worker    size_t staging_buffer_size;
1296*61046927SAndroid Build Coastguard Worker    uint32_t *staging_buffer;
1297*61046927SAndroid Build Coastguard Worker    uint32_t *data_buffer;
1298*61046927SAndroid Build Coastguard Worker    uint32_t *code_buffer;
1299*61046927SAndroid Build Coastguard Worker    VkResult result;
1300*61046927SAndroid Build Coastguard Worker 
1301*61046927SAndroid Build Coastguard Worker    /* Calculate how much space we'll need for the compute shader PDS program.
1302*61046927SAndroid Build Coastguard Worker     */
1303*61046927SAndroid Build Coastguard Worker    pvr_pds_compute_shader(program, NULL, PDS_GENERATE_SIZES, dev_info);
1304*61046927SAndroid Build Coastguard Worker 
1305*61046927SAndroid Build Coastguard Worker    /* FIXME: Fix the below inconsistency of code size being in bytes whereas
1306*61046927SAndroid Build Coastguard Worker     * data size being in dwords.
1307*61046927SAndroid Build Coastguard Worker     */
1308*61046927SAndroid Build Coastguard Worker    /* Code size is in bytes, data size in dwords. */
1309*61046927SAndroid Build Coastguard Worker    staging_buffer_size =
1310*61046927SAndroid Build Coastguard Worker       PVR_DW_TO_BYTES(program->data_size) + program->code_size;
1311*61046927SAndroid Build Coastguard Worker 
1312*61046927SAndroid Build Coastguard Worker    staging_buffer = vk_alloc(&device->vk.alloc,
1313*61046927SAndroid Build Coastguard Worker                              staging_buffer_size,
1314*61046927SAndroid Build Coastguard Worker                              8U,
1315*61046927SAndroid Build Coastguard Worker                              VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1316*61046927SAndroid Build Coastguard Worker    if (!staging_buffer)
1317*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1318*61046927SAndroid Build Coastguard Worker 
1319*61046927SAndroid Build Coastguard Worker    data_buffer = staging_buffer;
1320*61046927SAndroid Build Coastguard Worker    code_buffer = pvr_pds_compute_shader(program,
1321*61046927SAndroid Build Coastguard Worker                                         data_buffer,
1322*61046927SAndroid Build Coastguard Worker                                         PDS_GENERATE_DATA_SEGMENT,
1323*61046927SAndroid Build Coastguard Worker                                         dev_info);
1324*61046927SAndroid Build Coastguard Worker 
1325*61046927SAndroid Build Coastguard Worker    pvr_pds_compute_shader(program,
1326*61046927SAndroid Build Coastguard Worker                           code_buffer,
1327*61046927SAndroid Build Coastguard Worker                           PDS_GENERATE_CODE_SEGMENT,
1328*61046927SAndroid Build Coastguard Worker                           dev_info);
1329*61046927SAndroid Build Coastguard Worker 
1330*61046927SAndroid Build Coastguard Worker    result = pvr_gpu_upload_pds(device,
1331*61046927SAndroid Build Coastguard Worker                                data_buffer,
1332*61046927SAndroid Build Coastguard Worker                                program->data_size,
1333*61046927SAndroid Build Coastguard Worker                                PVRX(CDMCTRL_KERNEL1_DATA_ADDR_ALIGNMENT),
1334*61046927SAndroid Build Coastguard Worker                                code_buffer,
1335*61046927SAndroid Build Coastguard Worker                                program->code_size / sizeof(uint32_t),
1336*61046927SAndroid Build Coastguard Worker                                PVRX(CDMCTRL_KERNEL2_CODE_ADDR_ALIGNMENT),
1337*61046927SAndroid Build Coastguard Worker                                cache_line_size,
1338*61046927SAndroid Build Coastguard Worker                                pds_upload_out);
1339*61046927SAndroid Build Coastguard Worker 
1340*61046927SAndroid Build Coastguard Worker    vk_free(&device->vk.alloc, staging_buffer);
1341*61046927SAndroid Build Coastguard Worker 
1342*61046927SAndroid Build Coastguard Worker    return result;
1343*61046927SAndroid Build Coastguard Worker }
1344*61046927SAndroid Build Coastguard Worker 
pvr_device_init_compute_fence_program(struct pvr_device * device)1345*61046927SAndroid Build Coastguard Worker static VkResult pvr_device_init_compute_fence_program(struct pvr_device *device)
1346*61046927SAndroid Build Coastguard Worker {
1347*61046927SAndroid Build Coastguard Worker    struct pvr_pds_compute_shader_program program;
1348*61046927SAndroid Build Coastguard Worker 
1349*61046927SAndroid Build Coastguard Worker    pvr_pds_compute_shader_program_init(&program);
1350*61046927SAndroid Build Coastguard Worker    /* Fence kernel. */
1351*61046927SAndroid Build Coastguard Worker    program.fence = true;
1352*61046927SAndroid Build Coastguard Worker    program.clear_pds_barrier = true;
1353*61046927SAndroid Build Coastguard Worker 
1354*61046927SAndroid Build Coastguard Worker    return pvr_pds_compute_shader_create_and_upload(
1355*61046927SAndroid Build Coastguard Worker       device,
1356*61046927SAndroid Build Coastguard Worker       &program,
1357*61046927SAndroid Build Coastguard Worker       &device->pds_compute_fence_program);
1358*61046927SAndroid Build Coastguard Worker }
1359*61046927SAndroid Build Coastguard Worker 
pvr_device_init_compute_empty_program(struct pvr_device * device)1360*61046927SAndroid Build Coastguard Worker static VkResult pvr_device_init_compute_empty_program(struct pvr_device *device)
1361*61046927SAndroid Build Coastguard Worker {
1362*61046927SAndroid Build Coastguard Worker    struct pvr_pds_compute_shader_program program;
1363*61046927SAndroid Build Coastguard Worker 
1364*61046927SAndroid Build Coastguard Worker    pvr_pds_compute_shader_program_init(&program);
1365*61046927SAndroid Build Coastguard Worker    program.clear_pds_barrier = true;
1366*61046927SAndroid Build Coastguard Worker 
1367*61046927SAndroid Build Coastguard Worker    return pvr_pds_compute_shader_create_and_upload(
1368*61046927SAndroid Build Coastguard Worker       device,
1369*61046927SAndroid Build Coastguard Worker       &program,
1370*61046927SAndroid Build Coastguard Worker       &device->pds_compute_empty_program);
1371*61046927SAndroid Build Coastguard Worker }
1372*61046927SAndroid Build Coastguard Worker 
pvr_pds_idfwdf_programs_create_and_upload(struct pvr_device * device,pvr_dev_addr_t usc_addr,uint32_t shareds,uint32_t temps,pvr_dev_addr_t shareds_buffer_addr,struct pvr_pds_upload * const upload_out,struct pvr_pds_upload * const sw_compute_barrier_upload_out)1373*61046927SAndroid Build Coastguard Worker static VkResult pvr_pds_idfwdf_programs_create_and_upload(
1374*61046927SAndroid Build Coastguard Worker    struct pvr_device *device,
1375*61046927SAndroid Build Coastguard Worker    pvr_dev_addr_t usc_addr,
1376*61046927SAndroid Build Coastguard Worker    uint32_t shareds,
1377*61046927SAndroid Build Coastguard Worker    uint32_t temps,
1378*61046927SAndroid Build Coastguard Worker    pvr_dev_addr_t shareds_buffer_addr,
1379*61046927SAndroid Build Coastguard Worker    struct pvr_pds_upload *const upload_out,
1380*61046927SAndroid Build Coastguard Worker    struct pvr_pds_upload *const sw_compute_barrier_upload_out)
1381*61046927SAndroid Build Coastguard Worker {
1382*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
1383*61046927SAndroid Build Coastguard Worker    struct pvr_pds_vertex_shader_sa_program program = {
1384*61046927SAndroid Build Coastguard Worker       .kick_usc = true,
1385*61046927SAndroid Build Coastguard Worker       .clear_pds_barrier = PVR_NEED_SW_COMPUTE_PDS_BARRIER(dev_info),
1386*61046927SAndroid Build Coastguard Worker    };
1387*61046927SAndroid Build Coastguard Worker    size_t staging_buffer_size;
1388*61046927SAndroid Build Coastguard Worker    uint32_t *staging_buffer;
1389*61046927SAndroid Build Coastguard Worker    VkResult result;
1390*61046927SAndroid Build Coastguard Worker 
1391*61046927SAndroid Build Coastguard Worker    /* We'll need to DMA the shareds into the USC's Common Store. */
1392*61046927SAndroid Build Coastguard Worker    program.num_dma_kicks = pvr_pds_encode_dma_burst(program.dma_control,
1393*61046927SAndroid Build Coastguard Worker                                                     program.dma_address,
1394*61046927SAndroid Build Coastguard Worker                                                     0,
1395*61046927SAndroid Build Coastguard Worker                                                     shareds,
1396*61046927SAndroid Build Coastguard Worker                                                     shareds_buffer_addr.addr,
1397*61046927SAndroid Build Coastguard Worker                                                     false,
1398*61046927SAndroid Build Coastguard Worker                                                     dev_info);
1399*61046927SAndroid Build Coastguard Worker 
1400*61046927SAndroid Build Coastguard Worker    /* DMA temp regs. */
1401*61046927SAndroid Build Coastguard Worker    pvr_pds_setup_doutu(&program.usc_task_control,
1402*61046927SAndroid Build Coastguard Worker                        usc_addr.addr,
1403*61046927SAndroid Build Coastguard Worker                        temps,
1404*61046927SAndroid Build Coastguard Worker                        PVRX(PDSINST_DOUTU_SAMPLE_RATE_INSTANCE),
1405*61046927SAndroid Build Coastguard Worker                        false);
1406*61046927SAndroid Build Coastguard Worker 
1407*61046927SAndroid Build Coastguard Worker    pvr_pds_vertex_shader_sa(&program, NULL, PDS_GENERATE_SIZES, dev_info);
1408*61046927SAndroid Build Coastguard Worker 
1409*61046927SAndroid Build Coastguard Worker    staging_buffer_size = PVR_DW_TO_BYTES(program.code_size + program.data_size);
1410*61046927SAndroid Build Coastguard Worker 
1411*61046927SAndroid Build Coastguard Worker    staging_buffer = vk_alloc(&device->vk.alloc,
1412*61046927SAndroid Build Coastguard Worker                              staging_buffer_size,
1413*61046927SAndroid Build Coastguard Worker                              8,
1414*61046927SAndroid Build Coastguard Worker                              VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
1415*61046927SAndroid Build Coastguard Worker    if (!staging_buffer)
1416*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1417*61046927SAndroid Build Coastguard Worker 
1418*61046927SAndroid Build Coastguard Worker    /* FIXME: Add support for PDS_GENERATE_CODEDATA_SEGMENTS? */
1419*61046927SAndroid Build Coastguard Worker    pvr_pds_vertex_shader_sa(&program,
1420*61046927SAndroid Build Coastguard Worker                             staging_buffer,
1421*61046927SAndroid Build Coastguard Worker                             PDS_GENERATE_DATA_SEGMENT,
1422*61046927SAndroid Build Coastguard Worker                             dev_info);
1423*61046927SAndroid Build Coastguard Worker    pvr_pds_vertex_shader_sa(&program,
1424*61046927SAndroid Build Coastguard Worker                             &staging_buffer[program.data_size],
1425*61046927SAndroid Build Coastguard Worker                             PDS_GENERATE_CODE_SEGMENT,
1426*61046927SAndroid Build Coastguard Worker                             dev_info);
1427*61046927SAndroid Build Coastguard Worker 
1428*61046927SAndroid Build Coastguard Worker    /* At the time of writing, the SW_COMPUTE_PDS_BARRIER variant of the program
1429*61046927SAndroid Build Coastguard Worker     * is bigger so we handle it first (if needed) and realloc() for a smaller
1430*61046927SAndroid Build Coastguard Worker     * size.
1431*61046927SAndroid Build Coastguard Worker     */
1432*61046927SAndroid Build Coastguard Worker    if (PVR_NEED_SW_COMPUTE_PDS_BARRIER(dev_info)) {
1433*61046927SAndroid Build Coastguard Worker       /* FIXME: Figure out the define for alignment of 16. */
1434*61046927SAndroid Build Coastguard Worker       result = pvr_gpu_upload_pds(device,
1435*61046927SAndroid Build Coastguard Worker                                   &staging_buffer[0],
1436*61046927SAndroid Build Coastguard Worker                                   program.data_size,
1437*61046927SAndroid Build Coastguard Worker                                   16,
1438*61046927SAndroid Build Coastguard Worker                                   &staging_buffer[program.data_size],
1439*61046927SAndroid Build Coastguard Worker                                   program.code_size,
1440*61046927SAndroid Build Coastguard Worker                                   16,
1441*61046927SAndroid Build Coastguard Worker                                   16,
1442*61046927SAndroid Build Coastguard Worker                                   sw_compute_barrier_upload_out);
1443*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
1444*61046927SAndroid Build Coastguard Worker          vk_free(&device->vk.alloc, staging_buffer);
1445*61046927SAndroid Build Coastguard Worker          return result;
1446*61046927SAndroid Build Coastguard Worker       }
1447*61046927SAndroid Build Coastguard Worker 
1448*61046927SAndroid Build Coastguard Worker       program.clear_pds_barrier = false;
1449*61046927SAndroid Build Coastguard Worker 
1450*61046927SAndroid Build Coastguard Worker       pvr_pds_vertex_shader_sa(&program, NULL, PDS_GENERATE_SIZES, dev_info);
1451*61046927SAndroid Build Coastguard Worker 
1452*61046927SAndroid Build Coastguard Worker       staging_buffer_size =
1453*61046927SAndroid Build Coastguard Worker          PVR_DW_TO_BYTES(program.code_size + program.data_size);
1454*61046927SAndroid Build Coastguard Worker 
1455*61046927SAndroid Build Coastguard Worker       staging_buffer = vk_realloc(&device->vk.alloc,
1456*61046927SAndroid Build Coastguard Worker                                   staging_buffer,
1457*61046927SAndroid Build Coastguard Worker                                   staging_buffer_size,
1458*61046927SAndroid Build Coastguard Worker                                   8,
1459*61046927SAndroid Build Coastguard Worker                                   VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
1460*61046927SAndroid Build Coastguard Worker       if (!staging_buffer) {
1461*61046927SAndroid Build Coastguard Worker          pvr_bo_suballoc_free(sw_compute_barrier_upload_out->pvr_bo);
1462*61046927SAndroid Build Coastguard Worker 
1463*61046927SAndroid Build Coastguard Worker          return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1464*61046927SAndroid Build Coastguard Worker       }
1465*61046927SAndroid Build Coastguard Worker 
1466*61046927SAndroid Build Coastguard Worker       /* FIXME: Add support for PDS_GENERATE_CODEDATA_SEGMENTS? */
1467*61046927SAndroid Build Coastguard Worker       pvr_pds_vertex_shader_sa(&program,
1468*61046927SAndroid Build Coastguard Worker                                staging_buffer,
1469*61046927SAndroid Build Coastguard Worker                                PDS_GENERATE_DATA_SEGMENT,
1470*61046927SAndroid Build Coastguard Worker                                dev_info);
1471*61046927SAndroid Build Coastguard Worker       pvr_pds_vertex_shader_sa(&program,
1472*61046927SAndroid Build Coastguard Worker                                &staging_buffer[program.data_size],
1473*61046927SAndroid Build Coastguard Worker                                PDS_GENERATE_CODE_SEGMENT,
1474*61046927SAndroid Build Coastguard Worker                                dev_info);
1475*61046927SAndroid Build Coastguard Worker    } else {
1476*61046927SAndroid Build Coastguard Worker       *sw_compute_barrier_upload_out = (struct pvr_pds_upload){
1477*61046927SAndroid Build Coastguard Worker          .pvr_bo = NULL,
1478*61046927SAndroid Build Coastguard Worker       };
1479*61046927SAndroid Build Coastguard Worker    }
1480*61046927SAndroid Build Coastguard Worker 
1481*61046927SAndroid Build Coastguard Worker    /* FIXME: Figure out the define for alignment of 16. */
1482*61046927SAndroid Build Coastguard Worker    result = pvr_gpu_upload_pds(device,
1483*61046927SAndroid Build Coastguard Worker                                &staging_buffer[0],
1484*61046927SAndroid Build Coastguard Worker                                program.data_size,
1485*61046927SAndroid Build Coastguard Worker                                16,
1486*61046927SAndroid Build Coastguard Worker                                &staging_buffer[program.data_size],
1487*61046927SAndroid Build Coastguard Worker                                program.code_size,
1488*61046927SAndroid Build Coastguard Worker                                16,
1489*61046927SAndroid Build Coastguard Worker                                16,
1490*61046927SAndroid Build Coastguard Worker                                upload_out);
1491*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
1492*61046927SAndroid Build Coastguard Worker       vk_free(&device->vk.alloc, staging_buffer);
1493*61046927SAndroid Build Coastguard Worker       pvr_bo_suballoc_free(sw_compute_barrier_upload_out->pvr_bo);
1494*61046927SAndroid Build Coastguard Worker 
1495*61046927SAndroid Build Coastguard Worker       return result;
1496*61046927SAndroid Build Coastguard Worker    }
1497*61046927SAndroid Build Coastguard Worker 
1498*61046927SAndroid Build Coastguard Worker    vk_free(&device->vk.alloc, staging_buffer);
1499*61046927SAndroid Build Coastguard Worker 
1500*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1501*61046927SAndroid Build Coastguard Worker }
1502*61046927SAndroid Build Coastguard Worker 
pvr_device_init_compute_idfwdf_state(struct pvr_device * device)1503*61046927SAndroid Build Coastguard Worker static VkResult pvr_device_init_compute_idfwdf_state(struct pvr_device *device)
1504*61046927SAndroid Build Coastguard Worker {
1505*61046927SAndroid Build Coastguard Worker    uint64_t sampler_state[ROGUE_NUM_TEXSTATE_SAMPLER_WORDS];
1506*61046927SAndroid Build Coastguard Worker    uint64_t image_state[ROGUE_NUM_TEXSTATE_IMAGE_WORDS];
1507*61046927SAndroid Build Coastguard Worker    struct util_dynarray usc_program;
1508*61046927SAndroid Build Coastguard Worker    struct pvr_texture_state_info tex_info;
1509*61046927SAndroid Build Coastguard Worker    uint32_t *dword_ptr;
1510*61046927SAndroid Build Coastguard Worker    uint32_t usc_shareds;
1511*61046927SAndroid Build Coastguard Worker    uint32_t usc_temps;
1512*61046927SAndroid Build Coastguard Worker    VkResult result;
1513*61046927SAndroid Build Coastguard Worker 
1514*61046927SAndroid Build Coastguard Worker    util_dynarray_init(&usc_program, NULL);
1515*61046927SAndroid Build Coastguard Worker    pvr_hard_code_get_idfwdf_program(&device->pdevice->dev_info,
1516*61046927SAndroid Build Coastguard Worker                                     &usc_program,
1517*61046927SAndroid Build Coastguard Worker                                     &usc_shareds,
1518*61046927SAndroid Build Coastguard Worker                                     &usc_temps);
1519*61046927SAndroid Build Coastguard Worker 
1520*61046927SAndroid Build Coastguard Worker    device->idfwdf_state.usc_shareds = usc_shareds;
1521*61046927SAndroid Build Coastguard Worker 
1522*61046927SAndroid Build Coastguard Worker    /* FIXME: Figure out the define for alignment of 16. */
1523*61046927SAndroid Build Coastguard Worker    result = pvr_gpu_upload_usc(device,
1524*61046927SAndroid Build Coastguard Worker                                usc_program.data,
1525*61046927SAndroid Build Coastguard Worker                                usc_program.size,
1526*61046927SAndroid Build Coastguard Worker                                16,
1527*61046927SAndroid Build Coastguard Worker                                &device->idfwdf_state.usc);
1528*61046927SAndroid Build Coastguard Worker    util_dynarray_fini(&usc_program);
1529*61046927SAndroid Build Coastguard Worker 
1530*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1531*61046927SAndroid Build Coastguard Worker       return result;
1532*61046927SAndroid Build Coastguard Worker 
1533*61046927SAndroid Build Coastguard Worker    /* TODO: Get the store buffer size from the compiler? */
1534*61046927SAndroid Build Coastguard Worker    /* TODO: How was the size derived here? */
1535*61046927SAndroid Build Coastguard Worker    result = pvr_bo_alloc(device,
1536*61046927SAndroid Build Coastguard Worker                          device->heaps.general_heap,
1537*61046927SAndroid Build Coastguard Worker                          4 * sizeof(float) * 4 * 2,
1538*61046927SAndroid Build Coastguard Worker                          4,
1539*61046927SAndroid Build Coastguard Worker                          0,
1540*61046927SAndroid Build Coastguard Worker                          &device->idfwdf_state.store_bo);
1541*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1542*61046927SAndroid Build Coastguard Worker       goto err_free_usc_program;
1543*61046927SAndroid Build Coastguard Worker 
1544*61046927SAndroid Build Coastguard Worker    result = pvr_bo_alloc(device,
1545*61046927SAndroid Build Coastguard Worker                          device->heaps.general_heap,
1546*61046927SAndroid Build Coastguard Worker                          usc_shareds * ROGUE_REG_SIZE_BYTES,
1547*61046927SAndroid Build Coastguard Worker                          ROGUE_REG_SIZE_BYTES,
1548*61046927SAndroid Build Coastguard Worker                          PVR_BO_ALLOC_FLAG_CPU_MAPPED,
1549*61046927SAndroid Build Coastguard Worker                          &device->idfwdf_state.shareds_bo);
1550*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1551*61046927SAndroid Build Coastguard Worker       goto err_free_store_buffer;
1552*61046927SAndroid Build Coastguard Worker 
1553*61046927SAndroid Build Coastguard Worker    /* Pack state words. */
1554*61046927SAndroid Build Coastguard Worker 
1555*61046927SAndroid Build Coastguard Worker    pvr_csb_pack (&sampler_state[0], TEXSTATE_SAMPLER, sampler) {
1556*61046927SAndroid Build Coastguard Worker       sampler.dadjust = PVRX(TEXSTATE_DADJUST_ZERO_UINT);
1557*61046927SAndroid Build Coastguard Worker       sampler.magfilter = PVRX(TEXSTATE_FILTER_POINT);
1558*61046927SAndroid Build Coastguard Worker       sampler.addrmode_u = PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
1559*61046927SAndroid Build Coastguard Worker       sampler.addrmode_v = PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
1560*61046927SAndroid Build Coastguard Worker    }
1561*61046927SAndroid Build Coastguard Worker 
1562*61046927SAndroid Build Coastguard Worker    /* clang-format off */
1563*61046927SAndroid Build Coastguard Worker    pvr_csb_pack (&sampler_state[1], TEXSTATE_SAMPLER_WORD1, sampler_word1) {}
1564*61046927SAndroid Build Coastguard Worker    /* clang-format on */
1565*61046927SAndroid Build Coastguard Worker 
1566*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(1 + 1 == ROGUE_NUM_TEXSTATE_SAMPLER_WORDS);
1567*61046927SAndroid Build Coastguard Worker 
1568*61046927SAndroid Build Coastguard Worker    tex_info = (struct pvr_texture_state_info){
1569*61046927SAndroid Build Coastguard Worker       .format = VK_FORMAT_R32G32B32A32_SFLOAT,
1570*61046927SAndroid Build Coastguard Worker       .mem_layout = PVR_MEMLAYOUT_LINEAR,
1571*61046927SAndroid Build Coastguard Worker       .flags = PVR_TEXFLAGS_INDEX_LOOKUP,
1572*61046927SAndroid Build Coastguard Worker       .type = VK_IMAGE_VIEW_TYPE_2D,
1573*61046927SAndroid Build Coastguard Worker       .extent = { .width = 4, .height = 2, .depth = 0 },
1574*61046927SAndroid Build Coastguard Worker       .mip_levels = 1,
1575*61046927SAndroid Build Coastguard Worker       .sample_count = 1,
1576*61046927SAndroid Build Coastguard Worker       .stride = 4,
1577*61046927SAndroid Build Coastguard Worker       .swizzle = { PIPE_SWIZZLE_X,
1578*61046927SAndroid Build Coastguard Worker                    PIPE_SWIZZLE_Y,
1579*61046927SAndroid Build Coastguard Worker                    PIPE_SWIZZLE_Z,
1580*61046927SAndroid Build Coastguard Worker                    PIPE_SWIZZLE_W },
1581*61046927SAndroid Build Coastguard Worker       .addr = device->idfwdf_state.store_bo->vma->dev_addr,
1582*61046927SAndroid Build Coastguard Worker    };
1583*61046927SAndroid Build Coastguard Worker 
1584*61046927SAndroid Build Coastguard Worker    result = pvr_pack_tex_state(device, &tex_info, image_state);
1585*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1586*61046927SAndroid Build Coastguard Worker       goto err_free_shareds_buffer;
1587*61046927SAndroid Build Coastguard Worker 
1588*61046927SAndroid Build Coastguard Worker    /* Fill the shareds buffer. */
1589*61046927SAndroid Build Coastguard Worker 
1590*61046927SAndroid Build Coastguard Worker    dword_ptr = (uint32_t *)device->idfwdf_state.shareds_bo->bo->map;
1591*61046927SAndroid Build Coastguard Worker 
1592*61046927SAndroid Build Coastguard Worker #define HIGH_32(val) ((uint32_t)((val) >> 32U))
1593*61046927SAndroid Build Coastguard Worker #define LOW_32(val) ((uint32_t)(val))
1594*61046927SAndroid Build Coastguard Worker 
1595*61046927SAndroid Build Coastguard Worker    /* TODO: Should we use compiler info to setup the shareds data instead of
1596*61046927SAndroid Build Coastguard Worker     * assuming there's always 12 and this is how they should be setup?
1597*61046927SAndroid Build Coastguard Worker     */
1598*61046927SAndroid Build Coastguard Worker 
1599*61046927SAndroid Build Coastguard Worker    dword_ptr[0] = HIGH_32(device->idfwdf_state.store_bo->vma->dev_addr.addr);
1600*61046927SAndroid Build Coastguard Worker    dword_ptr[1] = LOW_32(device->idfwdf_state.store_bo->vma->dev_addr.addr);
1601*61046927SAndroid Build Coastguard Worker 
1602*61046927SAndroid Build Coastguard Worker    /* Pad the shareds as the texture/sample state words are 128 bit aligned. */
1603*61046927SAndroid Build Coastguard Worker    dword_ptr[2] = 0U;
1604*61046927SAndroid Build Coastguard Worker    dword_ptr[3] = 0U;
1605*61046927SAndroid Build Coastguard Worker 
1606*61046927SAndroid Build Coastguard Worker    dword_ptr[4] = LOW_32(image_state[0]);
1607*61046927SAndroid Build Coastguard Worker    dword_ptr[5] = HIGH_32(image_state[0]);
1608*61046927SAndroid Build Coastguard Worker    dword_ptr[6] = LOW_32(image_state[1]);
1609*61046927SAndroid Build Coastguard Worker    dword_ptr[7] = HIGH_32(image_state[1]);
1610*61046927SAndroid Build Coastguard Worker 
1611*61046927SAndroid Build Coastguard Worker    dword_ptr[8] = LOW_32(sampler_state[0]);
1612*61046927SAndroid Build Coastguard Worker    dword_ptr[9] = HIGH_32(sampler_state[0]);
1613*61046927SAndroid Build Coastguard Worker    dword_ptr[10] = LOW_32(sampler_state[1]);
1614*61046927SAndroid Build Coastguard Worker    dword_ptr[11] = HIGH_32(sampler_state[1]);
1615*61046927SAndroid Build Coastguard Worker    assert(11 + 1 == usc_shareds);
1616*61046927SAndroid Build Coastguard Worker 
1617*61046927SAndroid Build Coastguard Worker #undef HIGH_32
1618*61046927SAndroid Build Coastguard Worker #undef LOW_32
1619*61046927SAndroid Build Coastguard Worker 
1620*61046927SAndroid Build Coastguard Worker    pvr_bo_cpu_unmap(device, device->idfwdf_state.shareds_bo);
1621*61046927SAndroid Build Coastguard Worker    dword_ptr = NULL;
1622*61046927SAndroid Build Coastguard Worker 
1623*61046927SAndroid Build Coastguard Worker    /* Generate and upload PDS programs. */
1624*61046927SAndroid Build Coastguard Worker    result = pvr_pds_idfwdf_programs_create_and_upload(
1625*61046927SAndroid Build Coastguard Worker       device,
1626*61046927SAndroid Build Coastguard Worker       device->idfwdf_state.usc->dev_addr,
1627*61046927SAndroid Build Coastguard Worker       usc_shareds,
1628*61046927SAndroid Build Coastguard Worker       usc_temps,
1629*61046927SAndroid Build Coastguard Worker       device->idfwdf_state.shareds_bo->vma->dev_addr,
1630*61046927SAndroid Build Coastguard Worker       &device->idfwdf_state.pds,
1631*61046927SAndroid Build Coastguard Worker       &device->idfwdf_state.sw_compute_barrier_pds);
1632*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1633*61046927SAndroid Build Coastguard Worker       goto err_free_shareds_buffer;
1634*61046927SAndroid Build Coastguard Worker 
1635*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1636*61046927SAndroid Build Coastguard Worker 
1637*61046927SAndroid Build Coastguard Worker err_free_shareds_buffer:
1638*61046927SAndroid Build Coastguard Worker    pvr_bo_free(device, device->idfwdf_state.shareds_bo);
1639*61046927SAndroid Build Coastguard Worker 
1640*61046927SAndroid Build Coastguard Worker err_free_store_buffer:
1641*61046927SAndroid Build Coastguard Worker    pvr_bo_free(device, device->idfwdf_state.store_bo);
1642*61046927SAndroid Build Coastguard Worker 
1643*61046927SAndroid Build Coastguard Worker err_free_usc_program:
1644*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->idfwdf_state.usc);
1645*61046927SAndroid Build Coastguard Worker 
1646*61046927SAndroid Build Coastguard Worker    return result;
1647*61046927SAndroid Build Coastguard Worker }
1648*61046927SAndroid Build Coastguard Worker 
pvr_device_finish_compute_idfwdf_state(struct pvr_device * device)1649*61046927SAndroid Build Coastguard Worker static void pvr_device_finish_compute_idfwdf_state(struct pvr_device *device)
1650*61046927SAndroid Build Coastguard Worker {
1651*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->idfwdf_state.pds.pvr_bo);
1652*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->idfwdf_state.sw_compute_barrier_pds.pvr_bo);
1653*61046927SAndroid Build Coastguard Worker    pvr_bo_free(device, device->idfwdf_state.shareds_bo);
1654*61046927SAndroid Build Coastguard Worker    pvr_bo_free(device, device->idfwdf_state.store_bo);
1655*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->idfwdf_state.usc);
1656*61046927SAndroid Build Coastguard Worker }
1657*61046927SAndroid Build Coastguard Worker 
1658*61046927SAndroid Build Coastguard Worker /* FIXME: We should be calculating the size when we upload the code in
1659*61046927SAndroid Build Coastguard Worker  * pvr_srv_setup_static_pixel_event_program().
1660*61046927SAndroid Build Coastguard Worker  */
pvr_device_get_pixel_event_pds_program_data_size(const struct pvr_device_info * dev_info,uint32_t * const data_size_in_dwords_out)1661*61046927SAndroid Build Coastguard Worker static void pvr_device_get_pixel_event_pds_program_data_size(
1662*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *dev_info,
1663*61046927SAndroid Build Coastguard Worker    uint32_t *const data_size_in_dwords_out)
1664*61046927SAndroid Build Coastguard Worker {
1665*61046927SAndroid Build Coastguard Worker    struct pvr_pds_event_program program = {
1666*61046927SAndroid Build Coastguard Worker       /* No data to DMA, just a DOUTU needed. */
1667*61046927SAndroid Build Coastguard Worker       .num_emit_word_pairs = 0,
1668*61046927SAndroid Build Coastguard Worker    };
1669*61046927SAndroid Build Coastguard Worker 
1670*61046927SAndroid Build Coastguard Worker    pvr_pds_set_sizes_pixel_event(&program, dev_info);
1671*61046927SAndroid Build Coastguard Worker 
1672*61046927SAndroid Build Coastguard Worker    *data_size_in_dwords_out = program.data_size;
1673*61046927SAndroid Build Coastguard Worker }
1674*61046927SAndroid Build Coastguard Worker 
pvr_device_init_nop_program(struct pvr_device * device)1675*61046927SAndroid Build Coastguard Worker static VkResult pvr_device_init_nop_program(struct pvr_device *device)
1676*61046927SAndroid Build Coastguard Worker {
1677*61046927SAndroid Build Coastguard Worker    const uint32_t cache_line_size =
1678*61046927SAndroid Build Coastguard Worker       rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
1679*61046927SAndroid Build Coastguard Worker    struct pvr_pds_kickusc_program program = { 0 };
1680*61046927SAndroid Build Coastguard Worker    struct util_dynarray nop_usc_bin;
1681*61046927SAndroid Build Coastguard Worker    uint32_t staging_buffer_size;
1682*61046927SAndroid Build Coastguard Worker    uint32_t *staging_buffer;
1683*61046927SAndroid Build Coastguard Worker    VkResult result;
1684*61046927SAndroid Build Coastguard Worker 
1685*61046927SAndroid Build Coastguard Worker    pvr_uscgen_nop(&nop_usc_bin);
1686*61046927SAndroid Build Coastguard Worker 
1687*61046927SAndroid Build Coastguard Worker    result = pvr_gpu_upload_usc(device,
1688*61046927SAndroid Build Coastguard Worker                                util_dynarray_begin(&nop_usc_bin),
1689*61046927SAndroid Build Coastguard Worker                                nop_usc_bin.size,
1690*61046927SAndroid Build Coastguard Worker                                cache_line_size,
1691*61046927SAndroid Build Coastguard Worker                                &device->nop_program.usc);
1692*61046927SAndroid Build Coastguard Worker    util_dynarray_fini(&nop_usc_bin);
1693*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1694*61046927SAndroid Build Coastguard Worker       return result;
1695*61046927SAndroid Build Coastguard Worker 
1696*61046927SAndroid Build Coastguard Worker    /* Setup a PDS program that kicks the static USC program. */
1697*61046927SAndroid Build Coastguard Worker    pvr_pds_setup_doutu(&program.usc_task_control,
1698*61046927SAndroid Build Coastguard Worker                        device->nop_program.usc->dev_addr.addr,
1699*61046927SAndroid Build Coastguard Worker                        0U,
1700*61046927SAndroid Build Coastguard Worker                        PVRX(PDSINST_DOUTU_SAMPLE_RATE_INSTANCE),
1701*61046927SAndroid Build Coastguard Worker                        false);
1702*61046927SAndroid Build Coastguard Worker 
1703*61046927SAndroid Build Coastguard Worker    pvr_pds_set_sizes_pixel_shader(&program);
1704*61046927SAndroid Build Coastguard Worker 
1705*61046927SAndroid Build Coastguard Worker    staging_buffer_size = PVR_DW_TO_BYTES(program.code_size + program.data_size);
1706*61046927SAndroid Build Coastguard Worker 
1707*61046927SAndroid Build Coastguard Worker    staging_buffer = vk_alloc(&device->vk.alloc,
1708*61046927SAndroid Build Coastguard Worker                              staging_buffer_size,
1709*61046927SAndroid Build Coastguard Worker                              8U,
1710*61046927SAndroid Build Coastguard Worker                              VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
1711*61046927SAndroid Build Coastguard Worker    if (!staging_buffer) {
1712*61046927SAndroid Build Coastguard Worker       result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1713*61046927SAndroid Build Coastguard Worker       goto err_free_nop_usc_bo;
1714*61046927SAndroid Build Coastguard Worker    }
1715*61046927SAndroid Build Coastguard Worker 
1716*61046927SAndroid Build Coastguard Worker    pvr_pds_generate_pixel_shader_program(&program, staging_buffer);
1717*61046927SAndroid Build Coastguard Worker 
1718*61046927SAndroid Build Coastguard Worker    /* FIXME: Figure out the define for alignment of 16. */
1719*61046927SAndroid Build Coastguard Worker    result = pvr_gpu_upload_pds(device,
1720*61046927SAndroid Build Coastguard Worker                                staging_buffer,
1721*61046927SAndroid Build Coastguard Worker                                program.data_size,
1722*61046927SAndroid Build Coastguard Worker                                16U,
1723*61046927SAndroid Build Coastguard Worker                                &staging_buffer[program.data_size],
1724*61046927SAndroid Build Coastguard Worker                                program.code_size,
1725*61046927SAndroid Build Coastguard Worker                                16U,
1726*61046927SAndroid Build Coastguard Worker                                16U,
1727*61046927SAndroid Build Coastguard Worker                                &device->nop_program.pds);
1728*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1729*61046927SAndroid Build Coastguard Worker       goto err_free_staging_buffer;
1730*61046927SAndroid Build Coastguard Worker 
1731*61046927SAndroid Build Coastguard Worker    vk_free(&device->vk.alloc, staging_buffer);
1732*61046927SAndroid Build Coastguard Worker 
1733*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1734*61046927SAndroid Build Coastguard Worker 
1735*61046927SAndroid Build Coastguard Worker err_free_staging_buffer:
1736*61046927SAndroid Build Coastguard Worker    vk_free(&device->vk.alloc, staging_buffer);
1737*61046927SAndroid Build Coastguard Worker 
1738*61046927SAndroid Build Coastguard Worker err_free_nop_usc_bo:
1739*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->nop_program.usc);
1740*61046927SAndroid Build Coastguard Worker 
1741*61046927SAndroid Build Coastguard Worker    return result;
1742*61046927SAndroid Build Coastguard Worker }
1743*61046927SAndroid Build Coastguard Worker 
pvr_device_init_tile_buffer_state(struct pvr_device * device)1744*61046927SAndroid Build Coastguard Worker static void pvr_device_init_tile_buffer_state(struct pvr_device *device)
1745*61046927SAndroid Build Coastguard Worker {
1746*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&device->tile_buffer_state.mtx, mtx_plain);
1747*61046927SAndroid Build Coastguard Worker 
1748*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < ARRAY_SIZE(device->tile_buffer_state.buffers); i++)
1749*61046927SAndroid Build Coastguard Worker       device->tile_buffer_state.buffers[i] = NULL;
1750*61046927SAndroid Build Coastguard Worker 
1751*61046927SAndroid Build Coastguard Worker    device->tile_buffer_state.buffer_count = 0;
1752*61046927SAndroid Build Coastguard Worker }
1753*61046927SAndroid Build Coastguard Worker 
pvr_device_finish_tile_buffer_state(struct pvr_device * device)1754*61046927SAndroid Build Coastguard Worker static void pvr_device_finish_tile_buffer_state(struct pvr_device *device)
1755*61046927SAndroid Build Coastguard Worker {
1756*61046927SAndroid Build Coastguard Worker    /* Destroy the mutex first to trigger asserts in case it's still locked so
1757*61046927SAndroid Build Coastguard Worker     * that we don't put things in an inconsistent state by freeing buffers that
1758*61046927SAndroid Build Coastguard Worker     * might be in use or attempt to free buffers while new buffers are being
1759*61046927SAndroid Build Coastguard Worker     * allocated.
1760*61046927SAndroid Build Coastguard Worker     */
1761*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->tile_buffer_state.mtx);
1762*61046927SAndroid Build Coastguard Worker 
1763*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < device->tile_buffer_state.buffer_count; i++)
1764*61046927SAndroid Build Coastguard Worker       pvr_bo_free(device, device->tile_buffer_state.buffers[i]);
1765*61046927SAndroid Build Coastguard Worker }
1766*61046927SAndroid Build Coastguard Worker 
1767*61046927SAndroid Build Coastguard Worker /**
1768*61046927SAndroid Build Coastguard Worker  * \brief Ensures that a certain amount of tile buffers are allocated.
1769*61046927SAndroid Build Coastguard Worker  *
1770*61046927SAndroid Build Coastguard Worker  * Make sure that \p capacity amount of tile buffers are allocated. If less were
1771*61046927SAndroid Build Coastguard Worker  * present, append new tile buffers of \p size_in_bytes each to reach the quota.
1772*61046927SAndroid Build Coastguard Worker  */
pvr_device_tile_buffer_ensure_cap(struct pvr_device * device,uint32_t capacity,uint32_t size_in_bytes)1773*61046927SAndroid Build Coastguard Worker VkResult pvr_device_tile_buffer_ensure_cap(struct pvr_device *device,
1774*61046927SAndroid Build Coastguard Worker                                            uint32_t capacity,
1775*61046927SAndroid Build Coastguard Worker                                            uint32_t size_in_bytes)
1776*61046927SAndroid Build Coastguard Worker {
1777*61046927SAndroid Build Coastguard Worker    struct pvr_device_tile_buffer_state *tile_buffer_state =
1778*61046927SAndroid Build Coastguard Worker       &device->tile_buffer_state;
1779*61046927SAndroid Build Coastguard Worker    const uint32_t cache_line_size =
1780*61046927SAndroid Build Coastguard Worker       rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
1781*61046927SAndroid Build Coastguard Worker    VkResult result;
1782*61046927SAndroid Build Coastguard Worker 
1783*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&tile_buffer_state->mtx);
1784*61046927SAndroid Build Coastguard Worker 
1785*61046927SAndroid Build Coastguard Worker    /* Clamping in release and asserting in debug. */
1786*61046927SAndroid Build Coastguard Worker    assert(capacity <= ARRAY_SIZE(tile_buffer_state->buffers));
1787*61046927SAndroid Build Coastguard Worker    capacity = CLAMP(capacity,
1788*61046927SAndroid Build Coastguard Worker                     tile_buffer_state->buffer_count,
1789*61046927SAndroid Build Coastguard Worker                     ARRAY_SIZE(tile_buffer_state->buffers));
1790*61046927SAndroid Build Coastguard Worker 
1791*61046927SAndroid Build Coastguard Worker    /* TODO: Implement bo multialloc? To reduce the amount of syscalls and
1792*61046927SAndroid Build Coastguard Worker     * allocations.
1793*61046927SAndroid Build Coastguard Worker     */
1794*61046927SAndroid Build Coastguard Worker    for (uint32_t i = tile_buffer_state->buffer_count; i < capacity; i++) {
1795*61046927SAndroid Build Coastguard Worker       result = pvr_bo_alloc(device,
1796*61046927SAndroid Build Coastguard Worker                             device->heaps.general_heap,
1797*61046927SAndroid Build Coastguard Worker                             size_in_bytes,
1798*61046927SAndroid Build Coastguard Worker                             cache_line_size,
1799*61046927SAndroid Build Coastguard Worker                             0,
1800*61046927SAndroid Build Coastguard Worker                             &tile_buffer_state->buffers[i]);
1801*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
1802*61046927SAndroid Build Coastguard Worker          for (uint32_t j = tile_buffer_state->buffer_count; j < i; j++)
1803*61046927SAndroid Build Coastguard Worker             pvr_bo_free(device, tile_buffer_state->buffers[j]);
1804*61046927SAndroid Build Coastguard Worker 
1805*61046927SAndroid Build Coastguard Worker          goto err_release_lock;
1806*61046927SAndroid Build Coastguard Worker       }
1807*61046927SAndroid Build Coastguard Worker    }
1808*61046927SAndroid Build Coastguard Worker 
1809*61046927SAndroid Build Coastguard Worker    tile_buffer_state->buffer_count = capacity;
1810*61046927SAndroid Build Coastguard Worker 
1811*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&tile_buffer_state->mtx);
1812*61046927SAndroid Build Coastguard Worker 
1813*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1814*61046927SAndroid Build Coastguard Worker 
1815*61046927SAndroid Build Coastguard Worker err_release_lock:
1816*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&tile_buffer_state->mtx);
1817*61046927SAndroid Build Coastguard Worker 
1818*61046927SAndroid Build Coastguard Worker    return result;
1819*61046927SAndroid Build Coastguard Worker }
1820*61046927SAndroid Build Coastguard Worker 
pvr_device_init_default_sampler_state(struct pvr_device * device)1821*61046927SAndroid Build Coastguard Worker static void pvr_device_init_default_sampler_state(struct pvr_device *device)
1822*61046927SAndroid Build Coastguard Worker {
1823*61046927SAndroid Build Coastguard Worker    pvr_csb_pack (&device->input_attachment_sampler, TEXSTATE_SAMPLER, sampler) {
1824*61046927SAndroid Build Coastguard Worker       sampler.addrmode_u = PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
1825*61046927SAndroid Build Coastguard Worker       sampler.addrmode_v = PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
1826*61046927SAndroid Build Coastguard Worker       sampler.addrmode_w = PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
1827*61046927SAndroid Build Coastguard Worker       sampler.dadjust = PVRX(TEXSTATE_DADJUST_ZERO_UINT);
1828*61046927SAndroid Build Coastguard Worker       sampler.magfilter = PVRX(TEXSTATE_FILTER_POINT);
1829*61046927SAndroid Build Coastguard Worker       sampler.minfilter = PVRX(TEXSTATE_FILTER_POINT);
1830*61046927SAndroid Build Coastguard Worker       sampler.anisoctl = PVRX(TEXSTATE_ANISOCTL_DISABLED);
1831*61046927SAndroid Build Coastguard Worker       sampler.non_normalized_coords = true;
1832*61046927SAndroid Build Coastguard Worker    }
1833*61046927SAndroid Build Coastguard Worker }
1834*61046927SAndroid Build Coastguard Worker 
pvr_CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1835*61046927SAndroid Build Coastguard Worker VkResult pvr_CreateDevice(VkPhysicalDevice physicalDevice,
1836*61046927SAndroid Build Coastguard Worker                           const VkDeviceCreateInfo *pCreateInfo,
1837*61046927SAndroid Build Coastguard Worker                           const VkAllocationCallbacks *pAllocator,
1838*61046927SAndroid Build Coastguard Worker                           VkDevice *pDevice)
1839*61046927SAndroid Build Coastguard Worker {
1840*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_physical_device, pdevice, physicalDevice);
1841*61046927SAndroid Build Coastguard Worker    uint32_t initial_free_list_size = PVR_GLOBAL_FREE_LIST_INITIAL_SIZE;
1842*61046927SAndroid Build Coastguard Worker    struct pvr_instance *instance = pdevice->instance;
1843*61046927SAndroid Build Coastguard Worker    struct vk_device_dispatch_table dispatch_table;
1844*61046927SAndroid Build Coastguard Worker    struct pvr_device *device;
1845*61046927SAndroid Build Coastguard Worker    struct pvr_winsys *ws;
1846*61046927SAndroid Build Coastguard Worker    VkResult result;
1847*61046927SAndroid Build Coastguard Worker 
1848*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
1849*61046927SAndroid Build Coastguard Worker 
1850*61046927SAndroid Build Coastguard Worker    result = pvr_winsys_create(pdevice->render_path,
1851*61046927SAndroid Build Coastguard Worker                               pdevice->display_path,
1852*61046927SAndroid Build Coastguard Worker                               pAllocator ? pAllocator : &instance->vk.alloc,
1853*61046927SAndroid Build Coastguard Worker                               &ws);
1854*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1855*61046927SAndroid Build Coastguard Worker       goto err_out;
1856*61046927SAndroid Build Coastguard Worker 
1857*61046927SAndroid Build Coastguard Worker    device = vk_alloc2(&instance->vk.alloc,
1858*61046927SAndroid Build Coastguard Worker                       pAllocator,
1859*61046927SAndroid Build Coastguard Worker                       sizeof(*device),
1860*61046927SAndroid Build Coastguard Worker                       8,
1861*61046927SAndroid Build Coastguard Worker                       VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1862*61046927SAndroid Build Coastguard Worker    if (!device) {
1863*61046927SAndroid Build Coastguard Worker       result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1864*61046927SAndroid Build Coastguard Worker       goto err_pvr_winsys_destroy;
1865*61046927SAndroid Build Coastguard Worker    }
1866*61046927SAndroid Build Coastguard Worker 
1867*61046927SAndroid Build Coastguard Worker    vk_device_dispatch_table_from_entrypoints(&dispatch_table,
1868*61046927SAndroid Build Coastguard Worker                                              &pvr_device_entrypoints,
1869*61046927SAndroid Build Coastguard Worker                                              true);
1870*61046927SAndroid Build Coastguard Worker 
1871*61046927SAndroid Build Coastguard Worker    vk_device_dispatch_table_from_entrypoints(&dispatch_table,
1872*61046927SAndroid Build Coastguard Worker                                              &wsi_device_entrypoints,
1873*61046927SAndroid Build Coastguard Worker                                              false);
1874*61046927SAndroid Build Coastguard Worker 
1875*61046927SAndroid Build Coastguard Worker    result = vk_device_init(&device->vk,
1876*61046927SAndroid Build Coastguard Worker                            &pdevice->vk,
1877*61046927SAndroid Build Coastguard Worker                            &dispatch_table,
1878*61046927SAndroid Build Coastguard Worker                            pCreateInfo,
1879*61046927SAndroid Build Coastguard Worker                            pAllocator);
1880*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1881*61046927SAndroid Build Coastguard Worker       goto err_free_device;
1882*61046927SAndroid Build Coastguard Worker 
1883*61046927SAndroid Build Coastguard Worker    device->instance = instance;
1884*61046927SAndroid Build Coastguard Worker    device->pdevice = pdevice;
1885*61046927SAndroid Build Coastguard Worker    device->ws = ws;
1886*61046927SAndroid Build Coastguard Worker 
1887*61046927SAndroid Build Coastguard Worker    vk_device_set_drm_fd(&device->vk, ws->render_fd);
1888*61046927SAndroid Build Coastguard Worker 
1889*61046927SAndroid Build Coastguard Worker    if (ws->features.supports_threaded_submit) {
1890*61046927SAndroid Build Coastguard Worker       /* Queue submission can be blocked if the kernel CCBs become full,
1891*61046927SAndroid Build Coastguard Worker        * so enable threaded submit to not block the submitter.
1892*61046927SAndroid Build Coastguard Worker        */
1893*61046927SAndroid Build Coastguard Worker       vk_device_enable_threaded_submit(&device->vk);
1894*61046927SAndroid Build Coastguard Worker    }
1895*61046927SAndroid Build Coastguard Worker 
1896*61046927SAndroid Build Coastguard Worker    ws->ops->get_heaps_info(ws, &device->heaps);
1897*61046927SAndroid Build Coastguard Worker 
1898*61046927SAndroid Build Coastguard Worker    result = pvr_bo_store_create(device);
1899*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1900*61046927SAndroid Build Coastguard Worker       goto err_vk_device_finish;
1901*61046927SAndroid Build Coastguard Worker 
1902*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_init(&device->suballoc_general,
1903*61046927SAndroid Build Coastguard Worker                             device->heaps.general_heap,
1904*61046927SAndroid Build Coastguard Worker                             device,
1905*61046927SAndroid Build Coastguard Worker                             PVR_SUBALLOCATOR_GENERAL_SIZE);
1906*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_init(&device->suballoc_pds,
1907*61046927SAndroid Build Coastguard Worker                             device->heaps.pds_heap,
1908*61046927SAndroid Build Coastguard Worker                             device,
1909*61046927SAndroid Build Coastguard Worker                             PVR_SUBALLOCATOR_PDS_SIZE);
1910*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_init(&device->suballoc_transfer,
1911*61046927SAndroid Build Coastguard Worker                             device->heaps.transfer_frag_heap,
1912*61046927SAndroid Build Coastguard Worker                             device,
1913*61046927SAndroid Build Coastguard Worker                             PVR_SUBALLOCATOR_TRANSFER_SIZE);
1914*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_init(&device->suballoc_usc,
1915*61046927SAndroid Build Coastguard Worker                             device->heaps.usc_heap,
1916*61046927SAndroid Build Coastguard Worker                             device,
1917*61046927SAndroid Build Coastguard Worker                             PVR_SUBALLOCATOR_USC_SIZE);
1918*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_init(&device->suballoc_vis_test,
1919*61046927SAndroid Build Coastguard Worker                             device->heaps.vis_test_heap,
1920*61046927SAndroid Build Coastguard Worker                             device,
1921*61046927SAndroid Build Coastguard Worker                             PVR_SUBALLOCATOR_VIS_TEST_SIZE);
1922*61046927SAndroid Build Coastguard Worker 
1923*61046927SAndroid Build Coastguard Worker    if (p_atomic_inc_return(&instance->active_device_count) >
1924*61046927SAndroid Build Coastguard Worker        PVR_SECONDARY_DEVICE_THRESHOLD) {
1925*61046927SAndroid Build Coastguard Worker       initial_free_list_size = PVR_SECONDARY_DEVICE_FREE_LIST_INITAL_SIZE;
1926*61046927SAndroid Build Coastguard Worker    }
1927*61046927SAndroid Build Coastguard Worker 
1928*61046927SAndroid Build Coastguard Worker    result = pvr_free_list_create(device,
1929*61046927SAndroid Build Coastguard Worker                                  initial_free_list_size,
1930*61046927SAndroid Build Coastguard Worker                                  PVR_GLOBAL_FREE_LIST_MAX_SIZE,
1931*61046927SAndroid Build Coastguard Worker                                  PVR_GLOBAL_FREE_LIST_GROW_SIZE,
1932*61046927SAndroid Build Coastguard Worker                                  PVR_GLOBAL_FREE_LIST_GROW_THRESHOLD,
1933*61046927SAndroid Build Coastguard Worker                                  NULL /* parent_free_list */,
1934*61046927SAndroid Build Coastguard Worker                                  &device->global_free_list);
1935*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1936*61046927SAndroid Build Coastguard Worker       goto err_dec_device_count;
1937*61046927SAndroid Build Coastguard Worker 
1938*61046927SAndroid Build Coastguard Worker    result = pvr_device_init_nop_program(device);
1939*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1940*61046927SAndroid Build Coastguard Worker       goto err_pvr_free_list_destroy;
1941*61046927SAndroid Build Coastguard Worker 
1942*61046927SAndroid Build Coastguard Worker    result = pvr_device_init_compute_fence_program(device);
1943*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1944*61046927SAndroid Build Coastguard Worker       goto err_pvr_free_nop_program;
1945*61046927SAndroid Build Coastguard Worker 
1946*61046927SAndroid Build Coastguard Worker    result = pvr_device_init_compute_empty_program(device);
1947*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1948*61046927SAndroid Build Coastguard Worker       goto err_pvr_free_compute_fence;
1949*61046927SAndroid Build Coastguard Worker 
1950*61046927SAndroid Build Coastguard Worker    result = pvr_device_create_compute_query_programs(device);
1951*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1952*61046927SAndroid Build Coastguard Worker       goto err_pvr_free_compute_empty;
1953*61046927SAndroid Build Coastguard Worker 
1954*61046927SAndroid Build Coastguard Worker    result = pvr_device_init_compute_idfwdf_state(device);
1955*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1956*61046927SAndroid Build Coastguard Worker       goto err_pvr_destroy_compute_query_programs;
1957*61046927SAndroid Build Coastguard Worker 
1958*61046927SAndroid Build Coastguard Worker    result = pvr_device_init_graphics_static_clear_state(device);
1959*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1960*61046927SAndroid Build Coastguard Worker       goto err_pvr_finish_compute_idfwdf;
1961*61046927SAndroid Build Coastguard Worker 
1962*61046927SAndroid Build Coastguard Worker    result = pvr_device_init_spm_load_state(device);
1963*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1964*61046927SAndroid Build Coastguard Worker       goto err_pvr_finish_graphics_static_clear_state;
1965*61046927SAndroid Build Coastguard Worker 
1966*61046927SAndroid Build Coastguard Worker    pvr_device_init_tile_buffer_state(device);
1967*61046927SAndroid Build Coastguard Worker 
1968*61046927SAndroid Build Coastguard Worker    result = pvr_queues_create(device, pCreateInfo);
1969*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1970*61046927SAndroid Build Coastguard Worker       goto err_pvr_finish_tile_buffer_state;
1971*61046927SAndroid Build Coastguard Worker 
1972*61046927SAndroid Build Coastguard Worker    pvr_device_init_default_sampler_state(device);
1973*61046927SAndroid Build Coastguard Worker 
1974*61046927SAndroid Build Coastguard Worker    pvr_spm_init_scratch_buffer_store(device);
1975*61046927SAndroid Build Coastguard Worker 
1976*61046927SAndroid Build Coastguard Worker    result = pvr_init_robustness_buffer(device);
1977*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1978*61046927SAndroid Build Coastguard Worker       goto err_pvr_spm_finish_scratch_buffer_store;
1979*61046927SAndroid Build Coastguard Worker 
1980*61046927SAndroid Build Coastguard Worker    result = pvr_border_color_table_init(&device->border_color_table, device);
1981*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1982*61046927SAndroid Build Coastguard Worker       goto err_pvr_robustness_buffer_finish;
1983*61046927SAndroid Build Coastguard Worker 
1984*61046927SAndroid Build Coastguard Worker    /* FIXME: Move this to a later stage and possibly somewhere other than
1985*61046927SAndroid Build Coastguard Worker     * pvr_device. The purpose of this is so that we don't have to get the size
1986*61046927SAndroid Build Coastguard Worker     * on each kick.
1987*61046927SAndroid Build Coastguard Worker     */
1988*61046927SAndroid Build Coastguard Worker    pvr_device_get_pixel_event_pds_program_data_size(
1989*61046927SAndroid Build Coastguard Worker       &pdevice->dev_info,
1990*61046927SAndroid Build Coastguard Worker       &device->pixel_event_data_size_in_dwords);
1991*61046927SAndroid Build Coastguard Worker 
1992*61046927SAndroid Build Coastguard Worker    device->global_cmd_buffer_submit_count = 0;
1993*61046927SAndroid Build Coastguard Worker    device->global_queue_present_count = 0;
1994*61046927SAndroid Build Coastguard Worker 
1995*61046927SAndroid Build Coastguard Worker    *pDevice = pvr_device_to_handle(device);
1996*61046927SAndroid Build Coastguard Worker 
1997*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1998*61046927SAndroid Build Coastguard Worker 
1999*61046927SAndroid Build Coastguard Worker err_pvr_robustness_buffer_finish:
2000*61046927SAndroid Build Coastguard Worker    pvr_robustness_buffer_finish(device);
2001*61046927SAndroid Build Coastguard Worker 
2002*61046927SAndroid Build Coastguard Worker err_pvr_spm_finish_scratch_buffer_store:
2003*61046927SAndroid Build Coastguard Worker    pvr_spm_finish_scratch_buffer_store(device);
2004*61046927SAndroid Build Coastguard Worker 
2005*61046927SAndroid Build Coastguard Worker    pvr_queues_destroy(device);
2006*61046927SAndroid Build Coastguard Worker 
2007*61046927SAndroid Build Coastguard Worker err_pvr_finish_tile_buffer_state:
2008*61046927SAndroid Build Coastguard Worker    pvr_device_finish_tile_buffer_state(device);
2009*61046927SAndroid Build Coastguard Worker    pvr_device_finish_spm_load_state(device);
2010*61046927SAndroid Build Coastguard Worker 
2011*61046927SAndroid Build Coastguard Worker err_pvr_finish_graphics_static_clear_state:
2012*61046927SAndroid Build Coastguard Worker    pvr_device_finish_graphics_static_clear_state(device);
2013*61046927SAndroid Build Coastguard Worker 
2014*61046927SAndroid Build Coastguard Worker err_pvr_finish_compute_idfwdf:
2015*61046927SAndroid Build Coastguard Worker    pvr_device_finish_compute_idfwdf_state(device);
2016*61046927SAndroid Build Coastguard Worker 
2017*61046927SAndroid Build Coastguard Worker err_pvr_destroy_compute_query_programs:
2018*61046927SAndroid Build Coastguard Worker    pvr_device_destroy_compute_query_programs(device);
2019*61046927SAndroid Build Coastguard Worker 
2020*61046927SAndroid Build Coastguard Worker err_pvr_free_compute_empty:
2021*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->pds_compute_empty_program.pvr_bo);
2022*61046927SAndroid Build Coastguard Worker 
2023*61046927SAndroid Build Coastguard Worker err_pvr_free_compute_fence:
2024*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->pds_compute_fence_program.pvr_bo);
2025*61046927SAndroid Build Coastguard Worker 
2026*61046927SAndroid Build Coastguard Worker err_pvr_free_nop_program:
2027*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->nop_program.pds.pvr_bo);
2028*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->nop_program.usc);
2029*61046927SAndroid Build Coastguard Worker 
2030*61046927SAndroid Build Coastguard Worker err_pvr_free_list_destroy:
2031*61046927SAndroid Build Coastguard Worker    pvr_free_list_destroy(device->global_free_list);
2032*61046927SAndroid Build Coastguard Worker 
2033*61046927SAndroid Build Coastguard Worker err_dec_device_count:
2034*61046927SAndroid Build Coastguard Worker    p_atomic_dec(&device->instance->active_device_count);
2035*61046927SAndroid Build Coastguard Worker 
2036*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_vis_test);
2037*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_usc);
2038*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_transfer);
2039*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_pds);
2040*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_general);
2041*61046927SAndroid Build Coastguard Worker 
2042*61046927SAndroid Build Coastguard Worker    pvr_bo_store_destroy(device);
2043*61046927SAndroid Build Coastguard Worker 
2044*61046927SAndroid Build Coastguard Worker err_vk_device_finish:
2045*61046927SAndroid Build Coastguard Worker    vk_device_finish(&device->vk);
2046*61046927SAndroid Build Coastguard Worker 
2047*61046927SAndroid Build Coastguard Worker err_free_device:
2048*61046927SAndroid Build Coastguard Worker    vk_free(&device->vk.alloc, device);
2049*61046927SAndroid Build Coastguard Worker 
2050*61046927SAndroid Build Coastguard Worker err_pvr_winsys_destroy:
2051*61046927SAndroid Build Coastguard Worker    pvr_winsys_destroy(ws);
2052*61046927SAndroid Build Coastguard Worker 
2053*61046927SAndroid Build Coastguard Worker err_out:
2054*61046927SAndroid Build Coastguard Worker    return result;
2055*61046927SAndroid Build Coastguard Worker }
2056*61046927SAndroid Build Coastguard Worker 
pvr_DestroyDevice(VkDevice _device,const VkAllocationCallbacks * pAllocator)2057*61046927SAndroid Build Coastguard Worker void pvr_DestroyDevice(VkDevice _device,
2058*61046927SAndroid Build Coastguard Worker                        const VkAllocationCallbacks *pAllocator)
2059*61046927SAndroid Build Coastguard Worker {
2060*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2061*61046927SAndroid Build Coastguard Worker 
2062*61046927SAndroid Build Coastguard Worker    if (!device)
2063*61046927SAndroid Build Coastguard Worker       return;
2064*61046927SAndroid Build Coastguard Worker 
2065*61046927SAndroid Build Coastguard Worker    pvr_border_color_table_finish(&device->border_color_table, device);
2066*61046927SAndroid Build Coastguard Worker    pvr_robustness_buffer_finish(device);
2067*61046927SAndroid Build Coastguard Worker    pvr_spm_finish_scratch_buffer_store(device);
2068*61046927SAndroid Build Coastguard Worker    pvr_queues_destroy(device);
2069*61046927SAndroid Build Coastguard Worker    pvr_device_finish_tile_buffer_state(device);
2070*61046927SAndroid Build Coastguard Worker    pvr_device_finish_spm_load_state(device);
2071*61046927SAndroid Build Coastguard Worker    pvr_device_finish_graphics_static_clear_state(device);
2072*61046927SAndroid Build Coastguard Worker    pvr_device_finish_compute_idfwdf_state(device);
2073*61046927SAndroid Build Coastguard Worker    pvr_device_destroy_compute_query_programs(device);
2074*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->pds_compute_empty_program.pvr_bo);
2075*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->pds_compute_fence_program.pvr_bo);
2076*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->nop_program.pds.pvr_bo);
2077*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(device->nop_program.usc);
2078*61046927SAndroid Build Coastguard Worker    pvr_free_list_destroy(device->global_free_list);
2079*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_vis_test);
2080*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_usc);
2081*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_transfer);
2082*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_pds);
2083*61046927SAndroid Build Coastguard Worker    pvr_bo_suballocator_fini(&device->suballoc_general);
2084*61046927SAndroid Build Coastguard Worker    pvr_bo_store_destroy(device);
2085*61046927SAndroid Build Coastguard Worker    pvr_winsys_destroy(device->ws);
2086*61046927SAndroid Build Coastguard Worker    p_atomic_dec(&device->instance->active_device_count);
2087*61046927SAndroid Build Coastguard Worker    vk_device_finish(&device->vk);
2088*61046927SAndroid Build Coastguard Worker    vk_free(&device->vk.alloc, device);
2089*61046927SAndroid Build Coastguard Worker }
2090*61046927SAndroid Build Coastguard Worker 
pvr_EnumerateInstanceLayerProperties(uint32_t * pPropertyCount,VkLayerProperties * pProperties)2091*61046927SAndroid Build Coastguard Worker VkResult pvr_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
2092*61046927SAndroid Build Coastguard Worker                                               VkLayerProperties *pProperties)
2093*61046927SAndroid Build Coastguard Worker {
2094*61046927SAndroid Build Coastguard Worker    if (!pProperties) {
2095*61046927SAndroid Build Coastguard Worker       *pPropertyCount = 0;
2096*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
2097*61046927SAndroid Build Coastguard Worker    }
2098*61046927SAndroid Build Coastguard Worker 
2099*61046927SAndroid Build Coastguard Worker    return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
2100*61046927SAndroid Build Coastguard Worker }
2101*61046927SAndroid Build Coastguard Worker 
free_memory(struct pvr_device * device,struct pvr_device_memory * mem,const VkAllocationCallbacks * pAllocator)2102*61046927SAndroid Build Coastguard Worker static void free_memory(struct pvr_device *device,
2103*61046927SAndroid Build Coastguard Worker                         struct pvr_device_memory *mem,
2104*61046927SAndroid Build Coastguard Worker                         const VkAllocationCallbacks *pAllocator)
2105*61046927SAndroid Build Coastguard Worker {
2106*61046927SAndroid Build Coastguard Worker    if (!mem)
2107*61046927SAndroid Build Coastguard Worker       return;
2108*61046927SAndroid Build Coastguard Worker 
2109*61046927SAndroid Build Coastguard Worker    /* From the Vulkan spec (§11.2.13. Freeing Device Memory):
2110*61046927SAndroid Build Coastguard Worker     *   If a memory object is mapped at the time it is freed, it is implicitly
2111*61046927SAndroid Build Coastguard Worker     *   unmapped.
2112*61046927SAndroid Build Coastguard Worker     */
2113*61046927SAndroid Build Coastguard Worker    if (mem->bo->map)
2114*61046927SAndroid Build Coastguard Worker       device->ws->ops->buffer_unmap(mem->bo);
2115*61046927SAndroid Build Coastguard Worker 
2116*61046927SAndroid Build Coastguard Worker    p_atomic_add(&device->pdevice->heap_used, -mem->bo->size);
2117*61046927SAndroid Build Coastguard Worker 
2118*61046927SAndroid Build Coastguard Worker    device->ws->ops->buffer_destroy(mem->bo);
2119*61046927SAndroid Build Coastguard Worker 
2120*61046927SAndroid Build Coastguard Worker    vk_object_free(&device->vk, pAllocator, mem);
2121*61046927SAndroid Build Coastguard Worker }
2122*61046927SAndroid Build Coastguard Worker 
pvr_AllocateMemory(VkDevice _device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMem)2123*61046927SAndroid Build Coastguard Worker VkResult pvr_AllocateMemory(VkDevice _device,
2124*61046927SAndroid Build Coastguard Worker                             const VkMemoryAllocateInfo *pAllocateInfo,
2125*61046927SAndroid Build Coastguard Worker                             const VkAllocationCallbacks *pAllocator,
2126*61046927SAndroid Build Coastguard Worker                             VkDeviceMemory *pMem)
2127*61046927SAndroid Build Coastguard Worker {
2128*61046927SAndroid Build Coastguard Worker    const VkImportMemoryFdInfoKHR *fd_info = NULL;
2129*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2130*61046927SAndroid Build Coastguard Worker    enum pvr_winsys_bo_type type = PVR_WINSYS_BO_TYPE_GPU;
2131*61046927SAndroid Build Coastguard Worker    struct pvr_device_memory *mem;
2132*61046927SAndroid Build Coastguard Worker    uint64_t heap_used;
2133*61046927SAndroid Build Coastguard Worker    VkResult result;
2134*61046927SAndroid Build Coastguard Worker 
2135*61046927SAndroid Build Coastguard Worker    assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
2136*61046927SAndroid Build Coastguard Worker    assert(pAllocateInfo->allocationSize > 0);
2137*61046927SAndroid Build Coastguard Worker 
2138*61046927SAndroid Build Coastguard Worker    mem = vk_object_alloc(&device->vk,
2139*61046927SAndroid Build Coastguard Worker                          pAllocator,
2140*61046927SAndroid Build Coastguard Worker                          sizeof(*mem),
2141*61046927SAndroid Build Coastguard Worker                          VK_OBJECT_TYPE_DEVICE_MEMORY);
2142*61046927SAndroid Build Coastguard Worker    if (!mem)
2143*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2144*61046927SAndroid Build Coastguard Worker 
2145*61046927SAndroid Build Coastguard Worker    vk_foreach_struct_const (ext, pAllocateInfo->pNext) {
2146*61046927SAndroid Build Coastguard Worker       switch ((unsigned)ext->sType) {
2147*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA:
2148*61046927SAndroid Build Coastguard Worker          if (device->ws->display_fd >= 0)
2149*61046927SAndroid Build Coastguard Worker             type = PVR_WINSYS_BO_TYPE_DISPLAY;
2150*61046927SAndroid Build Coastguard Worker          break;
2151*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR:
2152*61046927SAndroid Build Coastguard Worker          fd_info = (void *)ext;
2153*61046927SAndroid Build Coastguard Worker          break;
2154*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:
2155*61046927SAndroid Build Coastguard Worker          break;
2156*61046927SAndroid Build Coastguard Worker       default:
2157*61046927SAndroid Build Coastguard Worker          vk_debug_ignored_stype(ext->sType);
2158*61046927SAndroid Build Coastguard Worker          break;
2159*61046927SAndroid Build Coastguard Worker       }
2160*61046927SAndroid Build Coastguard Worker    }
2161*61046927SAndroid Build Coastguard Worker 
2162*61046927SAndroid Build Coastguard Worker    if (fd_info && fd_info->handleType) {
2163*61046927SAndroid Build Coastguard Worker       VkDeviceSize aligned_alloc_size =
2164*61046927SAndroid Build Coastguard Worker          ALIGN_POT(pAllocateInfo->allocationSize, device->ws->page_size);
2165*61046927SAndroid Build Coastguard Worker 
2166*61046927SAndroid Build Coastguard Worker       assert(
2167*61046927SAndroid Build Coastguard Worker          fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
2168*61046927SAndroid Build Coastguard Worker          fd_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2169*61046927SAndroid Build Coastguard Worker 
2170*61046927SAndroid Build Coastguard Worker       result = device->ws->ops->buffer_create_from_fd(device->ws,
2171*61046927SAndroid Build Coastguard Worker                                                       fd_info->fd,
2172*61046927SAndroid Build Coastguard Worker                                                       &mem->bo);
2173*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2174*61046927SAndroid Build Coastguard Worker          goto err_vk_object_free_mem;
2175*61046927SAndroid Build Coastguard Worker 
2176*61046927SAndroid Build Coastguard Worker       /* For security purposes, we reject importing the bo if it's smaller
2177*61046927SAndroid Build Coastguard Worker        * than the requested allocation size. This prevents a malicious client
2178*61046927SAndroid Build Coastguard Worker        * from passing a buffer to a trusted client, lying about the size, and
2179*61046927SAndroid Build Coastguard Worker        * telling the trusted client to try and texture from an image that goes
2180*61046927SAndroid Build Coastguard Worker        * out-of-bounds. This sort of thing could lead to GPU hangs or worse
2181*61046927SAndroid Build Coastguard Worker        * in the trusted client. The trusted client can protect itself against
2182*61046927SAndroid Build Coastguard Worker        * this sort of attack but only if it can trust the buffer size.
2183*61046927SAndroid Build Coastguard Worker        */
2184*61046927SAndroid Build Coastguard Worker       if (aligned_alloc_size > mem->bo->size) {
2185*61046927SAndroid Build Coastguard Worker          result = vk_errorf(device,
2186*61046927SAndroid Build Coastguard Worker                             VK_ERROR_INVALID_EXTERNAL_HANDLE,
2187*61046927SAndroid Build Coastguard Worker                             "Aligned requested size too large for the given fd "
2188*61046927SAndroid Build Coastguard Worker                             "%" PRIu64 "B > %" PRIu64 "B",
2189*61046927SAndroid Build Coastguard Worker                             pAllocateInfo->allocationSize,
2190*61046927SAndroid Build Coastguard Worker                             mem->bo->size);
2191*61046927SAndroid Build Coastguard Worker          device->ws->ops->buffer_destroy(mem->bo);
2192*61046927SAndroid Build Coastguard Worker          goto err_vk_object_free_mem;
2193*61046927SAndroid Build Coastguard Worker       }
2194*61046927SAndroid Build Coastguard Worker 
2195*61046927SAndroid Build Coastguard Worker       /* From the Vulkan spec:
2196*61046927SAndroid Build Coastguard Worker        *
2197*61046927SAndroid Build Coastguard Worker        *    "Importing memory from a file descriptor transfers ownership of
2198*61046927SAndroid Build Coastguard Worker        *    the file descriptor from the application to the Vulkan
2199*61046927SAndroid Build Coastguard Worker        *    implementation. The application must not perform any operations on
2200*61046927SAndroid Build Coastguard Worker        *    the file descriptor after a successful import."
2201*61046927SAndroid Build Coastguard Worker        *
2202*61046927SAndroid Build Coastguard Worker        * If the import fails, we leave the file descriptor open.
2203*61046927SAndroid Build Coastguard Worker        */
2204*61046927SAndroid Build Coastguard Worker       close(fd_info->fd);
2205*61046927SAndroid Build Coastguard Worker    } else {
2206*61046927SAndroid Build Coastguard Worker       /* Align physical allocations to the page size of the heap that will be
2207*61046927SAndroid Build Coastguard Worker        * used when binding device memory (see pvr_bind_memory()) to ensure the
2208*61046927SAndroid Build Coastguard Worker        * entire allocation can be mapped.
2209*61046927SAndroid Build Coastguard Worker        */
2210*61046927SAndroid Build Coastguard Worker       const uint64_t alignment = device->heaps.general_heap->page_size;
2211*61046927SAndroid Build Coastguard Worker 
2212*61046927SAndroid Build Coastguard Worker       /* FIXME: Need to determine the flags based on
2213*61046927SAndroid Build Coastguard Worker        * device->pdevice->memory.memoryTypes[pAllocateInfo->memoryTypeIndex].propertyFlags.
2214*61046927SAndroid Build Coastguard Worker        *
2215*61046927SAndroid Build Coastguard Worker        * The alternative would be to store the flags alongside the memory
2216*61046927SAndroid Build Coastguard Worker        * types as an array that's indexed by pAllocateInfo->memoryTypeIndex so
2217*61046927SAndroid Build Coastguard Worker        * that they can be looked up.
2218*61046927SAndroid Build Coastguard Worker        */
2219*61046927SAndroid Build Coastguard Worker       result = device->ws->ops->buffer_create(device->ws,
2220*61046927SAndroid Build Coastguard Worker                                               pAllocateInfo->allocationSize,
2221*61046927SAndroid Build Coastguard Worker                                               alignment,
2222*61046927SAndroid Build Coastguard Worker                                               type,
2223*61046927SAndroid Build Coastguard Worker                                               PVR_WINSYS_BO_FLAG_CPU_ACCESS,
2224*61046927SAndroid Build Coastguard Worker                                               &mem->bo);
2225*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2226*61046927SAndroid Build Coastguard Worker          goto err_vk_object_free_mem;
2227*61046927SAndroid Build Coastguard Worker    }
2228*61046927SAndroid Build Coastguard Worker 
2229*61046927SAndroid Build Coastguard Worker    heap_used = p_atomic_add_return(&device->pdevice->heap_used, mem->bo->size);
2230*61046927SAndroid Build Coastguard Worker    if (heap_used > device->pdevice->memory.memoryHeaps[0].size) {
2231*61046927SAndroid Build Coastguard Worker       free_memory(device, mem, pAllocator);
2232*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
2233*61046927SAndroid Build Coastguard Worker    }
2234*61046927SAndroid Build Coastguard Worker 
2235*61046927SAndroid Build Coastguard Worker    *pMem = pvr_device_memory_to_handle(mem);
2236*61046927SAndroid Build Coastguard Worker 
2237*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2238*61046927SAndroid Build Coastguard Worker 
2239*61046927SAndroid Build Coastguard Worker err_vk_object_free_mem:
2240*61046927SAndroid Build Coastguard Worker    vk_object_free(&device->vk, pAllocator, mem);
2241*61046927SAndroid Build Coastguard Worker 
2242*61046927SAndroid Build Coastguard Worker    return result;
2243*61046927SAndroid Build Coastguard Worker }
2244*61046927SAndroid Build Coastguard Worker 
pvr_GetMemoryFdKHR(VkDevice _device,const VkMemoryGetFdInfoKHR * pGetFdInfo,int * pFd)2245*61046927SAndroid Build Coastguard Worker VkResult pvr_GetMemoryFdKHR(VkDevice _device,
2246*61046927SAndroid Build Coastguard Worker                             const VkMemoryGetFdInfoKHR *pGetFdInfo,
2247*61046927SAndroid Build Coastguard Worker                             int *pFd)
2248*61046927SAndroid Build Coastguard Worker {
2249*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2250*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device_memory, mem, pGetFdInfo->memory);
2251*61046927SAndroid Build Coastguard Worker 
2252*61046927SAndroid Build Coastguard Worker    assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
2253*61046927SAndroid Build Coastguard Worker 
2254*61046927SAndroid Build Coastguard Worker    assert(
2255*61046927SAndroid Build Coastguard Worker       pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
2256*61046927SAndroid Build Coastguard Worker       pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
2257*61046927SAndroid Build Coastguard Worker 
2258*61046927SAndroid Build Coastguard Worker    return device->ws->ops->buffer_get_fd(mem->bo, pFd);
2259*61046927SAndroid Build Coastguard Worker }
2260*61046927SAndroid Build Coastguard Worker 
2261*61046927SAndroid Build Coastguard Worker VkResult
pvr_GetMemoryFdPropertiesKHR(VkDevice _device,VkExternalMemoryHandleTypeFlagBits handleType,int fd,VkMemoryFdPropertiesKHR * pMemoryFdProperties)2262*61046927SAndroid Build Coastguard Worker pvr_GetMemoryFdPropertiesKHR(VkDevice _device,
2263*61046927SAndroid Build Coastguard Worker                              VkExternalMemoryHandleTypeFlagBits handleType,
2264*61046927SAndroid Build Coastguard Worker                              int fd,
2265*61046927SAndroid Build Coastguard Worker                              VkMemoryFdPropertiesKHR *pMemoryFdProperties)
2266*61046927SAndroid Build Coastguard Worker {
2267*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2268*61046927SAndroid Build Coastguard Worker 
2269*61046927SAndroid Build Coastguard Worker    switch (handleType) {
2270*61046927SAndroid Build Coastguard Worker    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
2271*61046927SAndroid Build Coastguard Worker       /* FIXME: This should only allow memory types having
2272*61046927SAndroid Build Coastguard Worker        * VK_MEMORY_PROPERTY_HOST_CACHED_BIT flag set, as
2273*61046927SAndroid Build Coastguard Worker        * dma-buf should be imported using cacheable memory types,
2274*61046927SAndroid Build Coastguard Worker        * given exporter's mmap will always map it as cacheable.
2275*61046927SAndroid Build Coastguard Worker        * Ref:
2276*61046927SAndroid Build Coastguard Worker        * https://www.kernel.org/doc/html/latest/driver-api/dma-buf.html#c.dma_buf_ops
2277*61046927SAndroid Build Coastguard Worker        */
2278*61046927SAndroid Build Coastguard Worker       pMemoryFdProperties->memoryTypeBits =
2279*61046927SAndroid Build Coastguard Worker          (1 << device->pdevice->memory.memoryTypeCount) - 1;
2280*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
2281*61046927SAndroid Build Coastguard Worker    default:
2282*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
2283*61046927SAndroid Build Coastguard Worker    }
2284*61046927SAndroid Build Coastguard Worker }
2285*61046927SAndroid Build Coastguard Worker 
pvr_FreeMemory(VkDevice _device,VkDeviceMemory _mem,const VkAllocationCallbacks * pAllocator)2286*61046927SAndroid Build Coastguard Worker void pvr_FreeMemory(VkDevice _device,
2287*61046927SAndroid Build Coastguard Worker                     VkDeviceMemory _mem,
2288*61046927SAndroid Build Coastguard Worker                     const VkAllocationCallbacks *pAllocator)
2289*61046927SAndroid Build Coastguard Worker {
2290*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2291*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device_memory, mem, _mem);
2292*61046927SAndroid Build Coastguard Worker 
2293*61046927SAndroid Build Coastguard Worker    free_memory(device, mem, pAllocator);
2294*61046927SAndroid Build Coastguard Worker }
2295*61046927SAndroid Build Coastguard Worker 
pvr_MapMemory(VkDevice _device,VkDeviceMemory _memory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags,void ** ppData)2296*61046927SAndroid Build Coastguard Worker VkResult pvr_MapMemory(VkDevice _device,
2297*61046927SAndroid Build Coastguard Worker                        VkDeviceMemory _memory,
2298*61046927SAndroid Build Coastguard Worker                        VkDeviceSize offset,
2299*61046927SAndroid Build Coastguard Worker                        VkDeviceSize size,
2300*61046927SAndroid Build Coastguard Worker                        VkMemoryMapFlags flags,
2301*61046927SAndroid Build Coastguard Worker                        void **ppData)
2302*61046927SAndroid Build Coastguard Worker {
2303*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2304*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device_memory, mem, _memory);
2305*61046927SAndroid Build Coastguard Worker    VkResult result;
2306*61046927SAndroid Build Coastguard Worker 
2307*61046927SAndroid Build Coastguard Worker    if (!mem) {
2308*61046927SAndroid Build Coastguard Worker       *ppData = NULL;
2309*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
2310*61046927SAndroid Build Coastguard Worker    }
2311*61046927SAndroid Build Coastguard Worker 
2312*61046927SAndroid Build Coastguard Worker    if (size == VK_WHOLE_SIZE)
2313*61046927SAndroid Build Coastguard Worker       size = mem->bo->size - offset;
2314*61046927SAndroid Build Coastguard Worker 
2315*61046927SAndroid Build Coastguard Worker    /* From the Vulkan spec version 1.0.32 docs for MapMemory:
2316*61046927SAndroid Build Coastguard Worker     *
2317*61046927SAndroid Build Coastguard Worker     *  * If size is not equal to VK_WHOLE_SIZE, size must be greater than 0
2318*61046927SAndroid Build Coastguard Worker     *    assert(size != 0);
2319*61046927SAndroid Build Coastguard Worker     *  * If size is not equal to VK_WHOLE_SIZE, size must be less than or
2320*61046927SAndroid Build Coastguard Worker     *    equal to the size of the memory minus offset
2321*61046927SAndroid Build Coastguard Worker     */
2322*61046927SAndroid Build Coastguard Worker 
2323*61046927SAndroid Build Coastguard Worker    assert(size > 0);
2324*61046927SAndroid Build Coastguard Worker    assert(offset + size <= mem->bo->size);
2325*61046927SAndroid Build Coastguard Worker 
2326*61046927SAndroid Build Coastguard Worker    /* Check if already mapped */
2327*61046927SAndroid Build Coastguard Worker    if (mem->bo->map) {
2328*61046927SAndroid Build Coastguard Worker       *ppData = (uint8_t *)mem->bo->map + offset;
2329*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
2330*61046927SAndroid Build Coastguard Worker    }
2331*61046927SAndroid Build Coastguard Worker 
2332*61046927SAndroid Build Coastguard Worker    /* Map it all at once */
2333*61046927SAndroid Build Coastguard Worker    result = device->ws->ops->buffer_map(mem->bo);
2334*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2335*61046927SAndroid Build Coastguard Worker       return result;
2336*61046927SAndroid Build Coastguard Worker 
2337*61046927SAndroid Build Coastguard Worker    *ppData = (uint8_t *)mem->bo->map + offset;
2338*61046927SAndroid Build Coastguard Worker 
2339*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2340*61046927SAndroid Build Coastguard Worker }
2341*61046927SAndroid Build Coastguard Worker 
pvr_UnmapMemory(VkDevice _device,VkDeviceMemory _memory)2342*61046927SAndroid Build Coastguard Worker void pvr_UnmapMemory(VkDevice _device, VkDeviceMemory _memory)
2343*61046927SAndroid Build Coastguard Worker {
2344*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2345*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device_memory, mem, _memory);
2346*61046927SAndroid Build Coastguard Worker 
2347*61046927SAndroid Build Coastguard Worker    if (!mem || !mem->bo->map)
2348*61046927SAndroid Build Coastguard Worker       return;
2349*61046927SAndroid Build Coastguard Worker 
2350*61046927SAndroid Build Coastguard Worker    device->ws->ops->buffer_unmap(mem->bo);
2351*61046927SAndroid Build Coastguard Worker }
2352*61046927SAndroid Build Coastguard Worker 
pvr_FlushMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)2353*61046927SAndroid Build Coastguard Worker VkResult pvr_FlushMappedMemoryRanges(VkDevice _device,
2354*61046927SAndroid Build Coastguard Worker                                      uint32_t memoryRangeCount,
2355*61046927SAndroid Build Coastguard Worker                                      const VkMappedMemoryRange *pMemoryRanges)
2356*61046927SAndroid Build Coastguard Worker {
2357*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2358*61046927SAndroid Build Coastguard Worker }
2359*61046927SAndroid Build Coastguard Worker 
2360*61046927SAndroid Build Coastguard Worker VkResult
pvr_InvalidateMappedMemoryRanges(VkDevice _device,uint32_t memoryRangeCount,const VkMappedMemoryRange * pMemoryRanges)2361*61046927SAndroid Build Coastguard Worker pvr_InvalidateMappedMemoryRanges(VkDevice _device,
2362*61046927SAndroid Build Coastguard Worker                                  uint32_t memoryRangeCount,
2363*61046927SAndroid Build Coastguard Worker                                  const VkMappedMemoryRange *pMemoryRanges)
2364*61046927SAndroid Build Coastguard Worker {
2365*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2366*61046927SAndroid Build Coastguard Worker }
2367*61046927SAndroid Build Coastguard Worker 
pvr_GetImageSparseMemoryRequirements2(VkDevice device,const VkImageSparseMemoryRequirementsInfo2 * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)2368*61046927SAndroid Build Coastguard Worker void pvr_GetImageSparseMemoryRequirements2(
2369*61046927SAndroid Build Coastguard Worker    VkDevice device,
2370*61046927SAndroid Build Coastguard Worker    const VkImageSparseMemoryRequirementsInfo2 *pInfo,
2371*61046927SAndroid Build Coastguard Worker    uint32_t *pSparseMemoryRequirementCount,
2372*61046927SAndroid Build Coastguard Worker    VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
2373*61046927SAndroid Build Coastguard Worker {
2374*61046927SAndroid Build Coastguard Worker    *pSparseMemoryRequirementCount = 0;
2375*61046927SAndroid Build Coastguard Worker }
2376*61046927SAndroid Build Coastguard Worker 
pvr_GetDeviceMemoryCommitment(VkDevice device,VkDeviceMemory memory,VkDeviceSize * pCommittedMemoryInBytes)2377*61046927SAndroid Build Coastguard Worker void pvr_GetDeviceMemoryCommitment(VkDevice device,
2378*61046927SAndroid Build Coastguard Worker                                    VkDeviceMemory memory,
2379*61046927SAndroid Build Coastguard Worker                                    VkDeviceSize *pCommittedMemoryInBytes)
2380*61046927SAndroid Build Coastguard Worker {
2381*61046927SAndroid Build Coastguard Worker    *pCommittedMemoryInBytes = 0;
2382*61046927SAndroid Build Coastguard Worker }
2383*61046927SAndroid Build Coastguard Worker 
pvr_bind_memory(struct pvr_device * device,struct pvr_device_memory * mem,VkDeviceSize offset,VkDeviceSize size,VkDeviceSize alignment,struct pvr_winsys_vma ** const vma_out,pvr_dev_addr_t * const dev_addr_out)2384*61046927SAndroid Build Coastguard Worker VkResult pvr_bind_memory(struct pvr_device *device,
2385*61046927SAndroid Build Coastguard Worker                          struct pvr_device_memory *mem,
2386*61046927SAndroid Build Coastguard Worker                          VkDeviceSize offset,
2387*61046927SAndroid Build Coastguard Worker                          VkDeviceSize size,
2388*61046927SAndroid Build Coastguard Worker                          VkDeviceSize alignment,
2389*61046927SAndroid Build Coastguard Worker                          struct pvr_winsys_vma **const vma_out,
2390*61046927SAndroid Build Coastguard Worker                          pvr_dev_addr_t *const dev_addr_out)
2391*61046927SAndroid Build Coastguard Worker {
2392*61046927SAndroid Build Coastguard Worker    VkDeviceSize virt_size =
2393*61046927SAndroid Build Coastguard Worker       size + (offset & (device->heaps.general_heap->page_size - 1));
2394*61046927SAndroid Build Coastguard Worker    struct pvr_winsys_vma *vma;
2395*61046927SAndroid Build Coastguard Worker    pvr_dev_addr_t dev_addr;
2396*61046927SAndroid Build Coastguard Worker    VkResult result;
2397*61046927SAndroid Build Coastguard Worker 
2398*61046927SAndroid Build Coastguard Worker    /* Valid usage:
2399*61046927SAndroid Build Coastguard Worker     *
2400*61046927SAndroid Build Coastguard Worker     *   "memoryOffset must be an integer multiple of the alignment member of
2401*61046927SAndroid Build Coastguard Worker     *    the VkMemoryRequirements structure returned from a call to
2402*61046927SAndroid Build Coastguard Worker     *    vkGetBufferMemoryRequirements with buffer"
2403*61046927SAndroid Build Coastguard Worker     *
2404*61046927SAndroid Build Coastguard Worker     *   "memoryOffset must be an integer multiple of the alignment member of
2405*61046927SAndroid Build Coastguard Worker     *    the VkMemoryRequirements structure returned from a call to
2406*61046927SAndroid Build Coastguard Worker     *    vkGetImageMemoryRequirements with image"
2407*61046927SAndroid Build Coastguard Worker     */
2408*61046927SAndroid Build Coastguard Worker    assert(offset % alignment == 0);
2409*61046927SAndroid Build Coastguard Worker    assert(offset < mem->bo->size);
2410*61046927SAndroid Build Coastguard Worker 
2411*61046927SAndroid Build Coastguard Worker    result = device->ws->ops->heap_alloc(device->heaps.general_heap,
2412*61046927SAndroid Build Coastguard Worker                                         virt_size,
2413*61046927SAndroid Build Coastguard Worker                                         alignment,
2414*61046927SAndroid Build Coastguard Worker                                         &vma);
2415*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2416*61046927SAndroid Build Coastguard Worker       goto err_out;
2417*61046927SAndroid Build Coastguard Worker 
2418*61046927SAndroid Build Coastguard Worker    result = device->ws->ops->vma_map(vma, mem->bo, offset, size, &dev_addr);
2419*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2420*61046927SAndroid Build Coastguard Worker       goto err_free_vma;
2421*61046927SAndroid Build Coastguard Worker 
2422*61046927SAndroid Build Coastguard Worker    *dev_addr_out = dev_addr;
2423*61046927SAndroid Build Coastguard Worker    *vma_out = vma;
2424*61046927SAndroid Build Coastguard Worker 
2425*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2426*61046927SAndroid Build Coastguard Worker 
2427*61046927SAndroid Build Coastguard Worker err_free_vma:
2428*61046927SAndroid Build Coastguard Worker    device->ws->ops->heap_free(vma);
2429*61046927SAndroid Build Coastguard Worker 
2430*61046927SAndroid Build Coastguard Worker err_out:
2431*61046927SAndroid Build Coastguard Worker    return result;
2432*61046927SAndroid Build Coastguard Worker }
2433*61046927SAndroid Build Coastguard Worker 
pvr_unbind_memory(struct pvr_device * device,struct pvr_winsys_vma * vma)2434*61046927SAndroid Build Coastguard Worker void pvr_unbind_memory(struct pvr_device *device, struct pvr_winsys_vma *vma)
2435*61046927SAndroid Build Coastguard Worker {
2436*61046927SAndroid Build Coastguard Worker    device->ws->ops->vma_unmap(vma);
2437*61046927SAndroid Build Coastguard Worker    device->ws->ops->heap_free(vma);
2438*61046927SAndroid Build Coastguard Worker }
2439*61046927SAndroid Build Coastguard Worker 
pvr_BindBufferMemory2(VkDevice _device,uint32_t bindInfoCount,const VkBindBufferMemoryInfo * pBindInfos)2440*61046927SAndroid Build Coastguard Worker VkResult pvr_BindBufferMemory2(VkDevice _device,
2441*61046927SAndroid Build Coastguard Worker                                uint32_t bindInfoCount,
2442*61046927SAndroid Build Coastguard Worker                                const VkBindBufferMemoryInfo *pBindInfos)
2443*61046927SAndroid Build Coastguard Worker {
2444*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2445*61046927SAndroid Build Coastguard Worker    uint32_t i;
2446*61046927SAndroid Build Coastguard Worker 
2447*61046927SAndroid Build Coastguard Worker    for (i = 0; i < bindInfoCount; i++) {
2448*61046927SAndroid Build Coastguard Worker       PVR_FROM_HANDLE(pvr_device_memory, mem, pBindInfos[i].memory);
2449*61046927SAndroid Build Coastguard Worker       PVR_FROM_HANDLE(pvr_buffer, buffer, pBindInfos[i].buffer);
2450*61046927SAndroid Build Coastguard Worker 
2451*61046927SAndroid Build Coastguard Worker       VkResult result = pvr_bind_memory(device,
2452*61046927SAndroid Build Coastguard Worker                                         mem,
2453*61046927SAndroid Build Coastguard Worker                                         pBindInfos[i].memoryOffset,
2454*61046927SAndroid Build Coastguard Worker                                         buffer->vk.size,
2455*61046927SAndroid Build Coastguard Worker                                         buffer->alignment,
2456*61046927SAndroid Build Coastguard Worker                                         &buffer->vma,
2457*61046927SAndroid Build Coastguard Worker                                         &buffer->dev_addr);
2458*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
2459*61046927SAndroid Build Coastguard Worker          while (i--) {
2460*61046927SAndroid Build Coastguard Worker             PVR_FROM_HANDLE(pvr_buffer, buffer, pBindInfos[i].buffer);
2461*61046927SAndroid Build Coastguard Worker             pvr_unbind_memory(device, buffer->vma);
2462*61046927SAndroid Build Coastguard Worker          }
2463*61046927SAndroid Build Coastguard Worker 
2464*61046927SAndroid Build Coastguard Worker          return result;
2465*61046927SAndroid Build Coastguard Worker       }
2466*61046927SAndroid Build Coastguard Worker    }
2467*61046927SAndroid Build Coastguard Worker 
2468*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2469*61046927SAndroid Build Coastguard Worker }
2470*61046927SAndroid Build Coastguard Worker 
pvr_QueueBindSparse(VkQueue _queue,uint32_t bindInfoCount,const VkBindSparseInfo * pBindInfo,VkFence fence)2471*61046927SAndroid Build Coastguard Worker VkResult pvr_QueueBindSparse(VkQueue _queue,
2472*61046927SAndroid Build Coastguard Worker                              uint32_t bindInfoCount,
2473*61046927SAndroid Build Coastguard Worker                              const VkBindSparseInfo *pBindInfo,
2474*61046927SAndroid Build Coastguard Worker                              VkFence fence)
2475*61046927SAndroid Build Coastguard Worker {
2476*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2477*61046927SAndroid Build Coastguard Worker }
2478*61046927SAndroid Build Coastguard Worker 
2479*61046927SAndroid Build Coastguard Worker /* Event functions. */
2480*61046927SAndroid Build Coastguard Worker 
pvr_CreateEvent(VkDevice _device,const VkEventCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkEvent * pEvent)2481*61046927SAndroid Build Coastguard Worker VkResult pvr_CreateEvent(VkDevice _device,
2482*61046927SAndroid Build Coastguard Worker                          const VkEventCreateInfo *pCreateInfo,
2483*61046927SAndroid Build Coastguard Worker                          const VkAllocationCallbacks *pAllocator,
2484*61046927SAndroid Build Coastguard Worker                          VkEvent *pEvent)
2485*61046927SAndroid Build Coastguard Worker {
2486*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2487*61046927SAndroid Build Coastguard Worker 
2488*61046927SAndroid Build Coastguard Worker    struct pvr_event *event = vk_object_alloc(&device->vk,
2489*61046927SAndroid Build Coastguard Worker                                              pAllocator,
2490*61046927SAndroid Build Coastguard Worker                                              sizeof(*event),
2491*61046927SAndroid Build Coastguard Worker                                              VK_OBJECT_TYPE_EVENT);
2492*61046927SAndroid Build Coastguard Worker    if (!event)
2493*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2494*61046927SAndroid Build Coastguard Worker 
2495*61046927SAndroid Build Coastguard Worker    event->sync = NULL;
2496*61046927SAndroid Build Coastguard Worker    event->state = PVR_EVENT_STATE_RESET_BY_HOST;
2497*61046927SAndroid Build Coastguard Worker 
2498*61046927SAndroid Build Coastguard Worker    *pEvent = pvr_event_to_handle(event);
2499*61046927SAndroid Build Coastguard Worker 
2500*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2501*61046927SAndroid Build Coastguard Worker }
2502*61046927SAndroid Build Coastguard Worker 
pvr_DestroyEvent(VkDevice _device,VkEvent _event,const VkAllocationCallbacks * pAllocator)2503*61046927SAndroid Build Coastguard Worker void pvr_DestroyEvent(VkDevice _device,
2504*61046927SAndroid Build Coastguard Worker                       VkEvent _event,
2505*61046927SAndroid Build Coastguard Worker                       const VkAllocationCallbacks *pAllocator)
2506*61046927SAndroid Build Coastguard Worker {
2507*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2508*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_event, event, _event);
2509*61046927SAndroid Build Coastguard Worker 
2510*61046927SAndroid Build Coastguard Worker    if (!event)
2511*61046927SAndroid Build Coastguard Worker       return;
2512*61046927SAndroid Build Coastguard Worker 
2513*61046927SAndroid Build Coastguard Worker    if (event->sync)
2514*61046927SAndroid Build Coastguard Worker       vk_sync_destroy(&device->vk, event->sync);
2515*61046927SAndroid Build Coastguard Worker 
2516*61046927SAndroid Build Coastguard Worker    vk_object_free(&device->vk, pAllocator, event);
2517*61046927SAndroid Build Coastguard Worker }
2518*61046927SAndroid Build Coastguard Worker 
pvr_GetEventStatus(VkDevice _device,VkEvent _event)2519*61046927SAndroid Build Coastguard Worker VkResult pvr_GetEventStatus(VkDevice _device, VkEvent _event)
2520*61046927SAndroid Build Coastguard Worker {
2521*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2522*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_event, event, _event);
2523*61046927SAndroid Build Coastguard Worker    VkResult result;
2524*61046927SAndroid Build Coastguard Worker 
2525*61046927SAndroid Build Coastguard Worker    switch (event->state) {
2526*61046927SAndroid Build Coastguard Worker    case PVR_EVENT_STATE_SET_BY_DEVICE:
2527*61046927SAndroid Build Coastguard Worker       if (!event->sync)
2528*61046927SAndroid Build Coastguard Worker          return VK_EVENT_RESET;
2529*61046927SAndroid Build Coastguard Worker 
2530*61046927SAndroid Build Coastguard Worker       result =
2531*61046927SAndroid Build Coastguard Worker          vk_sync_wait(&device->vk, event->sync, 0U, VK_SYNC_WAIT_COMPLETE, 0);
2532*61046927SAndroid Build Coastguard Worker       result = (result == VK_SUCCESS) ? VK_EVENT_SET : VK_EVENT_RESET;
2533*61046927SAndroid Build Coastguard Worker       break;
2534*61046927SAndroid Build Coastguard Worker 
2535*61046927SAndroid Build Coastguard Worker    case PVR_EVENT_STATE_RESET_BY_DEVICE:
2536*61046927SAndroid Build Coastguard Worker       if (!event->sync)
2537*61046927SAndroid Build Coastguard Worker          return VK_EVENT_RESET;
2538*61046927SAndroid Build Coastguard Worker 
2539*61046927SAndroid Build Coastguard Worker       result =
2540*61046927SAndroid Build Coastguard Worker          vk_sync_wait(&device->vk, event->sync, 0U, VK_SYNC_WAIT_COMPLETE, 0);
2541*61046927SAndroid Build Coastguard Worker       result = (result == VK_SUCCESS) ? VK_EVENT_RESET : VK_EVENT_SET;
2542*61046927SAndroid Build Coastguard Worker       break;
2543*61046927SAndroid Build Coastguard Worker 
2544*61046927SAndroid Build Coastguard Worker    case PVR_EVENT_STATE_SET_BY_HOST:
2545*61046927SAndroid Build Coastguard Worker       result = VK_EVENT_SET;
2546*61046927SAndroid Build Coastguard Worker       break;
2547*61046927SAndroid Build Coastguard Worker 
2548*61046927SAndroid Build Coastguard Worker    case PVR_EVENT_STATE_RESET_BY_HOST:
2549*61046927SAndroid Build Coastguard Worker       result = VK_EVENT_RESET;
2550*61046927SAndroid Build Coastguard Worker       break;
2551*61046927SAndroid Build Coastguard Worker 
2552*61046927SAndroid Build Coastguard Worker    default:
2553*61046927SAndroid Build Coastguard Worker       unreachable("Event object in unknown state");
2554*61046927SAndroid Build Coastguard Worker    }
2555*61046927SAndroid Build Coastguard Worker 
2556*61046927SAndroid Build Coastguard Worker    return result;
2557*61046927SAndroid Build Coastguard Worker }
2558*61046927SAndroid Build Coastguard Worker 
pvr_SetEvent(VkDevice _device,VkEvent _event)2559*61046927SAndroid Build Coastguard Worker VkResult pvr_SetEvent(VkDevice _device, VkEvent _event)
2560*61046927SAndroid Build Coastguard Worker {
2561*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_event, event, _event);
2562*61046927SAndroid Build Coastguard Worker 
2563*61046927SAndroid Build Coastguard Worker    if (event->sync) {
2564*61046927SAndroid Build Coastguard Worker       PVR_FROM_HANDLE(pvr_device, device, _device);
2565*61046927SAndroid Build Coastguard Worker 
2566*61046927SAndroid Build Coastguard Worker       const VkResult result = vk_sync_signal(&device->vk, event->sync, 0);
2567*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2568*61046927SAndroid Build Coastguard Worker          return result;
2569*61046927SAndroid Build Coastguard Worker    }
2570*61046927SAndroid Build Coastguard Worker 
2571*61046927SAndroid Build Coastguard Worker    event->state = PVR_EVENT_STATE_SET_BY_HOST;
2572*61046927SAndroid Build Coastguard Worker 
2573*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2574*61046927SAndroid Build Coastguard Worker }
2575*61046927SAndroid Build Coastguard Worker 
pvr_ResetEvent(VkDevice _device,VkEvent _event)2576*61046927SAndroid Build Coastguard Worker VkResult pvr_ResetEvent(VkDevice _device, VkEvent _event)
2577*61046927SAndroid Build Coastguard Worker {
2578*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_event, event, _event);
2579*61046927SAndroid Build Coastguard Worker 
2580*61046927SAndroid Build Coastguard Worker    if (event->sync) {
2581*61046927SAndroid Build Coastguard Worker       PVR_FROM_HANDLE(pvr_device, device, _device);
2582*61046927SAndroid Build Coastguard Worker 
2583*61046927SAndroid Build Coastguard Worker       const VkResult result = vk_sync_reset(&device->vk, event->sync);
2584*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2585*61046927SAndroid Build Coastguard Worker          return result;
2586*61046927SAndroid Build Coastguard Worker    }
2587*61046927SAndroid Build Coastguard Worker 
2588*61046927SAndroid Build Coastguard Worker    event->state = PVR_EVENT_STATE_RESET_BY_HOST;
2589*61046927SAndroid Build Coastguard Worker 
2590*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2591*61046927SAndroid Build Coastguard Worker }
2592*61046927SAndroid Build Coastguard Worker 
2593*61046927SAndroid Build Coastguard Worker /* Buffer functions. */
2594*61046927SAndroid Build Coastguard Worker 
pvr_CreateBuffer(VkDevice _device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)2595*61046927SAndroid Build Coastguard Worker VkResult pvr_CreateBuffer(VkDevice _device,
2596*61046927SAndroid Build Coastguard Worker                           const VkBufferCreateInfo *pCreateInfo,
2597*61046927SAndroid Build Coastguard Worker                           const VkAllocationCallbacks *pAllocator,
2598*61046927SAndroid Build Coastguard Worker                           VkBuffer *pBuffer)
2599*61046927SAndroid Build Coastguard Worker {
2600*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2601*61046927SAndroid Build Coastguard Worker    const uint32_t alignment = 4096;
2602*61046927SAndroid Build Coastguard Worker    struct pvr_buffer *buffer;
2603*61046927SAndroid Build Coastguard Worker 
2604*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
2605*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->usage != 0);
2606*61046927SAndroid Build Coastguard Worker 
2607*61046927SAndroid Build Coastguard Worker    /* We check against (ULONG_MAX - alignment) to prevent overflow issues */
2608*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->size >= ULONG_MAX - alignment)
2609*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
2610*61046927SAndroid Build Coastguard Worker 
2611*61046927SAndroid Build Coastguard Worker    buffer =
2612*61046927SAndroid Build Coastguard Worker       vk_buffer_create(&device->vk, pCreateInfo, pAllocator, sizeof(*buffer));
2613*61046927SAndroid Build Coastguard Worker    if (!buffer)
2614*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2615*61046927SAndroid Build Coastguard Worker 
2616*61046927SAndroid Build Coastguard Worker    buffer->alignment = alignment;
2617*61046927SAndroid Build Coastguard Worker 
2618*61046927SAndroid Build Coastguard Worker    *pBuffer = pvr_buffer_to_handle(buffer);
2619*61046927SAndroid Build Coastguard Worker 
2620*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2621*61046927SAndroid Build Coastguard Worker }
2622*61046927SAndroid Build Coastguard Worker 
pvr_DestroyBuffer(VkDevice _device,VkBuffer _buffer,const VkAllocationCallbacks * pAllocator)2623*61046927SAndroid Build Coastguard Worker void pvr_DestroyBuffer(VkDevice _device,
2624*61046927SAndroid Build Coastguard Worker                        VkBuffer _buffer,
2625*61046927SAndroid Build Coastguard Worker                        const VkAllocationCallbacks *pAllocator)
2626*61046927SAndroid Build Coastguard Worker {
2627*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2628*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_buffer, buffer, _buffer);
2629*61046927SAndroid Build Coastguard Worker 
2630*61046927SAndroid Build Coastguard Worker    if (!buffer)
2631*61046927SAndroid Build Coastguard Worker       return;
2632*61046927SAndroid Build Coastguard Worker 
2633*61046927SAndroid Build Coastguard Worker    if (buffer->vma)
2634*61046927SAndroid Build Coastguard Worker       pvr_unbind_memory(device, buffer->vma);
2635*61046927SAndroid Build Coastguard Worker 
2636*61046927SAndroid Build Coastguard Worker    vk_buffer_destroy(&device->vk, pAllocator, &buffer->vk);
2637*61046927SAndroid Build Coastguard Worker }
2638*61046927SAndroid Build Coastguard Worker 
pvr_gpu_upload(struct pvr_device * device,struct pvr_winsys_heap * heap,const void * data,size_t size,uint64_t alignment,struct pvr_suballoc_bo ** const pvr_bo_out)2639*61046927SAndroid Build Coastguard Worker VkResult pvr_gpu_upload(struct pvr_device *device,
2640*61046927SAndroid Build Coastguard Worker                         struct pvr_winsys_heap *heap,
2641*61046927SAndroid Build Coastguard Worker                         const void *data,
2642*61046927SAndroid Build Coastguard Worker                         size_t size,
2643*61046927SAndroid Build Coastguard Worker                         uint64_t alignment,
2644*61046927SAndroid Build Coastguard Worker                         struct pvr_suballoc_bo **const pvr_bo_out)
2645*61046927SAndroid Build Coastguard Worker {
2646*61046927SAndroid Build Coastguard Worker    struct pvr_suballoc_bo *suballoc_bo = NULL;
2647*61046927SAndroid Build Coastguard Worker    struct pvr_suballocator *allocator;
2648*61046927SAndroid Build Coastguard Worker    VkResult result;
2649*61046927SAndroid Build Coastguard Worker    void *map;
2650*61046927SAndroid Build Coastguard Worker 
2651*61046927SAndroid Build Coastguard Worker    assert(size > 0);
2652*61046927SAndroid Build Coastguard Worker 
2653*61046927SAndroid Build Coastguard Worker    if (heap == device->heaps.general_heap)
2654*61046927SAndroid Build Coastguard Worker       allocator = &device->suballoc_general;
2655*61046927SAndroid Build Coastguard Worker    else if (heap == device->heaps.pds_heap)
2656*61046927SAndroid Build Coastguard Worker       allocator = &device->suballoc_pds;
2657*61046927SAndroid Build Coastguard Worker    else if (heap == device->heaps.transfer_frag_heap)
2658*61046927SAndroid Build Coastguard Worker       allocator = &device->suballoc_transfer;
2659*61046927SAndroid Build Coastguard Worker    else if (heap == device->heaps.usc_heap)
2660*61046927SAndroid Build Coastguard Worker       allocator = &device->suballoc_usc;
2661*61046927SAndroid Build Coastguard Worker    else
2662*61046927SAndroid Build Coastguard Worker       unreachable("Unknown heap type");
2663*61046927SAndroid Build Coastguard Worker 
2664*61046927SAndroid Build Coastguard Worker    result = pvr_bo_suballoc(allocator, size, alignment, false, &suballoc_bo);
2665*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2666*61046927SAndroid Build Coastguard Worker       return result;
2667*61046927SAndroid Build Coastguard Worker 
2668*61046927SAndroid Build Coastguard Worker    map = pvr_bo_suballoc_get_map_addr(suballoc_bo);
2669*61046927SAndroid Build Coastguard Worker    memcpy(map, data, size);
2670*61046927SAndroid Build Coastguard Worker 
2671*61046927SAndroid Build Coastguard Worker    *pvr_bo_out = suballoc_bo;
2672*61046927SAndroid Build Coastguard Worker 
2673*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2674*61046927SAndroid Build Coastguard Worker }
2675*61046927SAndroid Build Coastguard Worker 
pvr_gpu_upload_usc(struct pvr_device * device,const void * code,size_t code_size,uint64_t code_alignment,struct pvr_suballoc_bo ** const pvr_bo_out)2676*61046927SAndroid Build Coastguard Worker VkResult pvr_gpu_upload_usc(struct pvr_device *device,
2677*61046927SAndroid Build Coastguard Worker                             const void *code,
2678*61046927SAndroid Build Coastguard Worker                             size_t code_size,
2679*61046927SAndroid Build Coastguard Worker                             uint64_t code_alignment,
2680*61046927SAndroid Build Coastguard Worker                             struct pvr_suballoc_bo **const pvr_bo_out)
2681*61046927SAndroid Build Coastguard Worker {
2682*61046927SAndroid Build Coastguard Worker    struct pvr_suballoc_bo *suballoc_bo = NULL;
2683*61046927SAndroid Build Coastguard Worker    VkResult result;
2684*61046927SAndroid Build Coastguard Worker    void *map;
2685*61046927SAndroid Build Coastguard Worker 
2686*61046927SAndroid Build Coastguard Worker    assert(code_size > 0);
2687*61046927SAndroid Build Coastguard Worker 
2688*61046927SAndroid Build Coastguard Worker    /* The USC will prefetch the next instruction, so over allocate by 1
2689*61046927SAndroid Build Coastguard Worker     * instruction to prevent reading off the end of a page into a potentially
2690*61046927SAndroid Build Coastguard Worker     * unallocated page.
2691*61046927SAndroid Build Coastguard Worker     */
2692*61046927SAndroid Build Coastguard Worker    result = pvr_bo_suballoc(&device->suballoc_usc,
2693*61046927SAndroid Build Coastguard Worker                             code_size + ROGUE_MAX_INSTR_BYTES,
2694*61046927SAndroid Build Coastguard Worker                             code_alignment,
2695*61046927SAndroid Build Coastguard Worker                             false,
2696*61046927SAndroid Build Coastguard Worker                             &suballoc_bo);
2697*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2698*61046927SAndroid Build Coastguard Worker       return result;
2699*61046927SAndroid Build Coastguard Worker 
2700*61046927SAndroid Build Coastguard Worker    map = pvr_bo_suballoc_get_map_addr(suballoc_bo);
2701*61046927SAndroid Build Coastguard Worker    memcpy(map, code, code_size);
2702*61046927SAndroid Build Coastguard Worker 
2703*61046927SAndroid Build Coastguard Worker    *pvr_bo_out = suballoc_bo;
2704*61046927SAndroid Build Coastguard Worker 
2705*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2706*61046927SAndroid Build Coastguard Worker }
2707*61046927SAndroid Build Coastguard Worker 
2708*61046927SAndroid Build Coastguard Worker /**
2709*61046927SAndroid Build Coastguard Worker  * \brief Upload PDS program data and code segments from host memory to device
2710*61046927SAndroid Build Coastguard Worker  * memory.
2711*61046927SAndroid Build Coastguard Worker  *
2712*61046927SAndroid Build Coastguard Worker  * \param[in] device            Logical device pointer.
2713*61046927SAndroid Build Coastguard Worker  * \param[in] data              Pointer to PDS data segment to upload.
2714*61046927SAndroid Build Coastguard Worker  * \param[in] data_size_dwords  Size of PDS data segment in dwords.
2715*61046927SAndroid Build Coastguard Worker  * \param[in] data_alignment    Required alignment of the PDS data segment in
2716*61046927SAndroid Build Coastguard Worker  *                              bytes. Must be a power of two.
2717*61046927SAndroid Build Coastguard Worker  * \param[in] code              Pointer to PDS code segment to upload.
2718*61046927SAndroid Build Coastguard Worker  * \param[in] code_size_dwords  Size of PDS code segment in dwords.
2719*61046927SAndroid Build Coastguard Worker  * \param[in] code_alignment    Required alignment of the PDS code segment in
2720*61046927SAndroid Build Coastguard Worker  *                              bytes. Must be a power of two.
2721*61046927SAndroid Build Coastguard Worker  * \param[in] min_alignment     Minimum alignment of the bo holding the PDS
2722*61046927SAndroid Build Coastguard Worker  *                              program in bytes.
2723*61046927SAndroid Build Coastguard Worker  * \param[out] pds_upload_out   On success will be initialized based on the
2724*61046927SAndroid Build Coastguard Worker  *                              uploaded PDS program.
2725*61046927SAndroid Build Coastguard Worker  * \return VK_SUCCESS on success, or error code otherwise.
2726*61046927SAndroid Build Coastguard Worker  */
pvr_gpu_upload_pds(struct pvr_device * device,const uint32_t * data,uint32_t data_size_dwords,uint32_t data_alignment,const uint32_t * code,uint32_t code_size_dwords,uint32_t code_alignment,uint64_t min_alignment,struct pvr_pds_upload * const pds_upload_out)2727*61046927SAndroid Build Coastguard Worker VkResult pvr_gpu_upload_pds(struct pvr_device *device,
2728*61046927SAndroid Build Coastguard Worker                             const uint32_t *data,
2729*61046927SAndroid Build Coastguard Worker                             uint32_t data_size_dwords,
2730*61046927SAndroid Build Coastguard Worker                             uint32_t data_alignment,
2731*61046927SAndroid Build Coastguard Worker                             const uint32_t *code,
2732*61046927SAndroid Build Coastguard Worker                             uint32_t code_size_dwords,
2733*61046927SAndroid Build Coastguard Worker                             uint32_t code_alignment,
2734*61046927SAndroid Build Coastguard Worker                             uint64_t min_alignment,
2735*61046927SAndroid Build Coastguard Worker                             struct pvr_pds_upload *const pds_upload_out)
2736*61046927SAndroid Build Coastguard Worker {
2737*61046927SAndroid Build Coastguard Worker    /* All alignment and sizes below are in bytes. */
2738*61046927SAndroid Build Coastguard Worker    const size_t data_size = PVR_DW_TO_BYTES(data_size_dwords);
2739*61046927SAndroid Build Coastguard Worker    const size_t code_size = PVR_DW_TO_BYTES(code_size_dwords);
2740*61046927SAndroid Build Coastguard Worker    const uint64_t data_aligned_size = ALIGN_POT(data_size, data_alignment);
2741*61046927SAndroid Build Coastguard Worker    const uint64_t code_aligned_size = ALIGN_POT(code_size, code_alignment);
2742*61046927SAndroid Build Coastguard Worker    const uint32_t code_offset = ALIGN_POT(data_aligned_size, code_alignment);
2743*61046927SAndroid Build Coastguard Worker    const uint64_t bo_alignment = MAX2(min_alignment, data_alignment);
2744*61046927SAndroid Build Coastguard Worker    const uint64_t bo_size = (!!code) ? (code_offset + code_aligned_size)
2745*61046927SAndroid Build Coastguard Worker                                      : data_aligned_size;
2746*61046927SAndroid Build Coastguard Worker    VkResult result;
2747*61046927SAndroid Build Coastguard Worker    void *map;
2748*61046927SAndroid Build Coastguard Worker 
2749*61046927SAndroid Build Coastguard Worker    assert(code || data);
2750*61046927SAndroid Build Coastguard Worker    assert(!code || (code_size_dwords != 0 && code_alignment != 0));
2751*61046927SAndroid Build Coastguard Worker    assert(!data || (data_size_dwords != 0 && data_alignment != 0));
2752*61046927SAndroid Build Coastguard Worker 
2753*61046927SAndroid Build Coastguard Worker    result = pvr_bo_suballoc(&device->suballoc_pds,
2754*61046927SAndroid Build Coastguard Worker                             bo_size,
2755*61046927SAndroid Build Coastguard Worker                             bo_alignment,
2756*61046927SAndroid Build Coastguard Worker                             true,
2757*61046927SAndroid Build Coastguard Worker                             &pds_upload_out->pvr_bo);
2758*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2759*61046927SAndroid Build Coastguard Worker       return result;
2760*61046927SAndroid Build Coastguard Worker 
2761*61046927SAndroid Build Coastguard Worker    map = pvr_bo_suballoc_get_map_addr(pds_upload_out->pvr_bo);
2762*61046927SAndroid Build Coastguard Worker 
2763*61046927SAndroid Build Coastguard Worker    if (data) {
2764*61046927SAndroid Build Coastguard Worker       memcpy(map, data, data_size);
2765*61046927SAndroid Build Coastguard Worker 
2766*61046927SAndroid Build Coastguard Worker       pds_upload_out->data_offset = pds_upload_out->pvr_bo->dev_addr.addr -
2767*61046927SAndroid Build Coastguard Worker                                     device->heaps.pds_heap->base_addr.addr;
2768*61046927SAndroid Build Coastguard Worker 
2769*61046927SAndroid Build Coastguard Worker       /* Store data size in dwords. */
2770*61046927SAndroid Build Coastguard Worker       assert(data_aligned_size % 4 == 0);
2771*61046927SAndroid Build Coastguard Worker       pds_upload_out->data_size = data_aligned_size / 4;
2772*61046927SAndroid Build Coastguard Worker    } else {
2773*61046927SAndroid Build Coastguard Worker       pds_upload_out->data_offset = 0;
2774*61046927SAndroid Build Coastguard Worker       pds_upload_out->data_size = 0;
2775*61046927SAndroid Build Coastguard Worker    }
2776*61046927SAndroid Build Coastguard Worker 
2777*61046927SAndroid Build Coastguard Worker    if (code) {
2778*61046927SAndroid Build Coastguard Worker       memcpy((uint8_t *)map + code_offset, code, code_size);
2779*61046927SAndroid Build Coastguard Worker 
2780*61046927SAndroid Build Coastguard Worker       pds_upload_out->code_offset =
2781*61046927SAndroid Build Coastguard Worker          (pds_upload_out->pvr_bo->dev_addr.addr + code_offset) -
2782*61046927SAndroid Build Coastguard Worker          device->heaps.pds_heap->base_addr.addr;
2783*61046927SAndroid Build Coastguard Worker 
2784*61046927SAndroid Build Coastguard Worker       /* Store code size in dwords. */
2785*61046927SAndroid Build Coastguard Worker       assert(code_aligned_size % 4 == 0);
2786*61046927SAndroid Build Coastguard Worker       pds_upload_out->code_size = code_aligned_size / 4;
2787*61046927SAndroid Build Coastguard Worker    } else {
2788*61046927SAndroid Build Coastguard Worker       pds_upload_out->code_offset = 0;
2789*61046927SAndroid Build Coastguard Worker       pds_upload_out->code_size = 0;
2790*61046927SAndroid Build Coastguard Worker    }
2791*61046927SAndroid Build Coastguard Worker 
2792*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2793*61046927SAndroid Build Coastguard Worker }
2794*61046927SAndroid Build Coastguard Worker 
2795*61046927SAndroid Build Coastguard Worker static VkResult
pvr_framebuffer_create_ppp_state(struct pvr_device * device,struct pvr_framebuffer * framebuffer)2796*61046927SAndroid Build Coastguard Worker pvr_framebuffer_create_ppp_state(struct pvr_device *device,
2797*61046927SAndroid Build Coastguard Worker                                  struct pvr_framebuffer *framebuffer)
2798*61046927SAndroid Build Coastguard Worker {
2799*61046927SAndroid Build Coastguard Worker    const uint32_t cache_line_size =
2800*61046927SAndroid Build Coastguard Worker       rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
2801*61046927SAndroid Build Coastguard Worker    uint32_t ppp_state[3];
2802*61046927SAndroid Build Coastguard Worker    VkResult result;
2803*61046927SAndroid Build Coastguard Worker 
2804*61046927SAndroid Build Coastguard Worker    pvr_csb_pack (&ppp_state[0], TA_STATE_HEADER, header) {
2805*61046927SAndroid Build Coastguard Worker       header.pres_terminate = true;
2806*61046927SAndroid Build Coastguard Worker    }
2807*61046927SAndroid Build Coastguard Worker 
2808*61046927SAndroid Build Coastguard Worker    pvr_csb_pack (&ppp_state[1], TA_STATE_TERMINATE0, term0) {
2809*61046927SAndroid Build Coastguard Worker       term0.clip_right =
2810*61046927SAndroid Build Coastguard Worker          DIV_ROUND_UP(
2811*61046927SAndroid Build Coastguard Worker             framebuffer->width,
2812*61046927SAndroid Build Coastguard Worker             PVRX(TA_STATE_TERMINATE0_CLIP_RIGHT_BLOCK_SIZE_IN_PIXELS)) -
2813*61046927SAndroid Build Coastguard Worker          1;
2814*61046927SAndroid Build Coastguard Worker       term0.clip_bottom =
2815*61046927SAndroid Build Coastguard Worker          DIV_ROUND_UP(
2816*61046927SAndroid Build Coastguard Worker             framebuffer->height,
2817*61046927SAndroid Build Coastguard Worker             PVRX(TA_STATE_TERMINATE0_CLIP_BOTTOM_BLOCK_SIZE_IN_PIXELS)) -
2818*61046927SAndroid Build Coastguard Worker          1;
2819*61046927SAndroid Build Coastguard Worker    }
2820*61046927SAndroid Build Coastguard Worker 
2821*61046927SAndroid Build Coastguard Worker    pvr_csb_pack (&ppp_state[2], TA_STATE_TERMINATE1, term1) {
2822*61046927SAndroid Build Coastguard Worker       term1.render_target = 0;
2823*61046927SAndroid Build Coastguard Worker       term1.clip_left = 0;
2824*61046927SAndroid Build Coastguard Worker    }
2825*61046927SAndroid Build Coastguard Worker 
2826*61046927SAndroid Build Coastguard Worker    result = pvr_gpu_upload(device,
2827*61046927SAndroid Build Coastguard Worker                            device->heaps.general_heap,
2828*61046927SAndroid Build Coastguard Worker                            ppp_state,
2829*61046927SAndroid Build Coastguard Worker                            sizeof(ppp_state),
2830*61046927SAndroid Build Coastguard Worker                            cache_line_size,
2831*61046927SAndroid Build Coastguard Worker                            &framebuffer->ppp_state_bo);
2832*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2833*61046927SAndroid Build Coastguard Worker       return result;
2834*61046927SAndroid Build Coastguard Worker 
2835*61046927SAndroid Build Coastguard Worker    /* Calculate the size of PPP state in dwords. */
2836*61046927SAndroid Build Coastguard Worker    framebuffer->ppp_state_size = sizeof(ppp_state) / sizeof(uint32_t);
2837*61046927SAndroid Build Coastguard Worker 
2838*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2839*61046927SAndroid Build Coastguard Worker }
2840*61046927SAndroid Build Coastguard Worker 
pvr_render_targets_init(struct pvr_render_target * render_targets,uint32_t render_targets_count)2841*61046927SAndroid Build Coastguard Worker static bool pvr_render_targets_init(struct pvr_render_target *render_targets,
2842*61046927SAndroid Build Coastguard Worker                                     uint32_t render_targets_count)
2843*61046927SAndroid Build Coastguard Worker {
2844*61046927SAndroid Build Coastguard Worker    uint32_t i;
2845*61046927SAndroid Build Coastguard Worker 
2846*61046927SAndroid Build Coastguard Worker    for (i = 0; i < render_targets_count; i++) {
2847*61046927SAndroid Build Coastguard Worker       if (pthread_mutex_init(&render_targets[i].mutex, NULL))
2848*61046927SAndroid Build Coastguard Worker          goto err_mutex_destroy;
2849*61046927SAndroid Build Coastguard Worker    }
2850*61046927SAndroid Build Coastguard Worker 
2851*61046927SAndroid Build Coastguard Worker    return true;
2852*61046927SAndroid Build Coastguard Worker 
2853*61046927SAndroid Build Coastguard Worker err_mutex_destroy:
2854*61046927SAndroid Build Coastguard Worker    while (i--)
2855*61046927SAndroid Build Coastguard Worker       pthread_mutex_destroy(&render_targets[i].mutex);
2856*61046927SAndroid Build Coastguard Worker 
2857*61046927SAndroid Build Coastguard Worker    return false;
2858*61046927SAndroid Build Coastguard Worker }
2859*61046927SAndroid Build Coastguard Worker 
pvr_render_targets_fini(struct pvr_render_target * render_targets,uint32_t render_targets_count)2860*61046927SAndroid Build Coastguard Worker static void pvr_render_targets_fini(struct pvr_render_target *render_targets,
2861*61046927SAndroid Build Coastguard Worker                                     uint32_t render_targets_count)
2862*61046927SAndroid Build Coastguard Worker {
2863*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < render_targets_count; i++) {
2864*61046927SAndroid Build Coastguard Worker       if (render_targets[i].valid) {
2865*61046927SAndroid Build Coastguard Worker          pvr_render_target_dataset_destroy(render_targets[i].rt_dataset);
2866*61046927SAndroid Build Coastguard Worker          render_targets[i].valid = false;
2867*61046927SAndroid Build Coastguard Worker       }
2868*61046927SAndroid Build Coastguard Worker 
2869*61046927SAndroid Build Coastguard Worker       pthread_mutex_destroy(&render_targets[i].mutex);
2870*61046927SAndroid Build Coastguard Worker    }
2871*61046927SAndroid Build Coastguard Worker }
2872*61046927SAndroid Build Coastguard Worker 
pvr_CreateFramebuffer(VkDevice _device,const VkFramebufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFramebuffer * pFramebuffer)2873*61046927SAndroid Build Coastguard Worker VkResult pvr_CreateFramebuffer(VkDevice _device,
2874*61046927SAndroid Build Coastguard Worker                                const VkFramebufferCreateInfo *pCreateInfo,
2875*61046927SAndroid Build Coastguard Worker                                const VkAllocationCallbacks *pAllocator,
2876*61046927SAndroid Build Coastguard Worker                                VkFramebuffer *pFramebuffer)
2877*61046927SAndroid Build Coastguard Worker {
2878*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_render_pass, pass, pCreateInfo->renderPass);
2879*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
2880*61046927SAndroid Build Coastguard Worker    struct pvr_spm_bgobj_state *spm_bgobj_state_per_render;
2881*61046927SAndroid Build Coastguard Worker    struct pvr_spm_eot_state *spm_eot_state_per_render;
2882*61046927SAndroid Build Coastguard Worker    struct pvr_render_target *render_targets;
2883*61046927SAndroid Build Coastguard Worker    struct pvr_framebuffer *framebuffer;
2884*61046927SAndroid Build Coastguard Worker    struct pvr_image_view **attachments;
2885*61046927SAndroid Build Coastguard Worker    uint32_t render_targets_count;
2886*61046927SAndroid Build Coastguard Worker    uint64_t scratch_buffer_size;
2887*61046927SAndroid Build Coastguard Worker    VkResult result;
2888*61046927SAndroid Build Coastguard Worker 
2889*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
2890*61046927SAndroid Build Coastguard Worker 
2891*61046927SAndroid Build Coastguard Worker    render_targets_count =
2892*61046927SAndroid Build Coastguard Worker       PVR_RENDER_TARGETS_PER_FRAMEBUFFER(&device->pdevice->dev_info);
2893*61046927SAndroid Build Coastguard Worker 
2894*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC(ma);
2895*61046927SAndroid Build Coastguard Worker    vk_multialloc_add(&ma, &framebuffer, __typeof__(*framebuffer), 1);
2896*61046927SAndroid Build Coastguard Worker    vk_multialloc_add(&ma,
2897*61046927SAndroid Build Coastguard Worker                      &attachments,
2898*61046927SAndroid Build Coastguard Worker                      __typeof__(*attachments),
2899*61046927SAndroid Build Coastguard Worker                      pCreateInfo->attachmentCount);
2900*61046927SAndroid Build Coastguard Worker    vk_multialloc_add(&ma,
2901*61046927SAndroid Build Coastguard Worker                      &render_targets,
2902*61046927SAndroid Build Coastguard Worker                      __typeof__(*render_targets),
2903*61046927SAndroid Build Coastguard Worker                      render_targets_count);
2904*61046927SAndroid Build Coastguard Worker    vk_multialloc_add(&ma,
2905*61046927SAndroid Build Coastguard Worker                      &spm_eot_state_per_render,
2906*61046927SAndroid Build Coastguard Worker                      __typeof__(*spm_eot_state_per_render),
2907*61046927SAndroid Build Coastguard Worker                      pass->hw_setup->render_count);
2908*61046927SAndroid Build Coastguard Worker    vk_multialloc_add(&ma,
2909*61046927SAndroid Build Coastguard Worker                      &spm_bgobj_state_per_render,
2910*61046927SAndroid Build Coastguard Worker                      __typeof__(*spm_bgobj_state_per_render),
2911*61046927SAndroid Build Coastguard Worker                      pass->hw_setup->render_count);
2912*61046927SAndroid Build Coastguard Worker 
2913*61046927SAndroid Build Coastguard Worker    if (!vk_multialloc_zalloc2(&ma,
2914*61046927SAndroid Build Coastguard Worker                               &device->vk.alloc,
2915*61046927SAndroid Build Coastguard Worker                               pAllocator,
2916*61046927SAndroid Build Coastguard Worker                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
2917*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2918*61046927SAndroid Build Coastguard Worker 
2919*61046927SAndroid Build Coastguard Worker    vk_object_base_init(&device->vk,
2920*61046927SAndroid Build Coastguard Worker                        &framebuffer->base,
2921*61046927SAndroid Build Coastguard Worker                        VK_OBJECT_TYPE_FRAMEBUFFER);
2922*61046927SAndroid Build Coastguard Worker 
2923*61046927SAndroid Build Coastguard Worker    framebuffer->width = pCreateInfo->width;
2924*61046927SAndroid Build Coastguard Worker    framebuffer->height = pCreateInfo->height;
2925*61046927SAndroid Build Coastguard Worker    framebuffer->layers = pCreateInfo->layers;
2926*61046927SAndroid Build Coastguard Worker 
2927*61046927SAndroid Build Coastguard Worker    framebuffer->attachments = attachments;
2928*61046927SAndroid Build Coastguard Worker    framebuffer->attachment_count = pCreateInfo->attachmentCount;
2929*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < framebuffer->attachment_count; i++) {
2930*61046927SAndroid Build Coastguard Worker       framebuffer->attachments[i] =
2931*61046927SAndroid Build Coastguard Worker          pvr_image_view_from_handle(pCreateInfo->pAttachments[i]);
2932*61046927SAndroid Build Coastguard Worker    }
2933*61046927SAndroid Build Coastguard Worker 
2934*61046927SAndroid Build Coastguard Worker    result = pvr_framebuffer_create_ppp_state(device, framebuffer);
2935*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2936*61046927SAndroid Build Coastguard Worker       goto err_free_framebuffer;
2937*61046927SAndroid Build Coastguard Worker 
2938*61046927SAndroid Build Coastguard Worker    framebuffer->render_targets = render_targets;
2939*61046927SAndroid Build Coastguard Worker    framebuffer->render_targets_count = render_targets_count;
2940*61046927SAndroid Build Coastguard Worker    if (!pvr_render_targets_init(framebuffer->render_targets,
2941*61046927SAndroid Build Coastguard Worker                                 render_targets_count)) {
2942*61046927SAndroid Build Coastguard Worker       result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2943*61046927SAndroid Build Coastguard Worker       goto err_free_ppp_state_bo;
2944*61046927SAndroid Build Coastguard Worker    }
2945*61046927SAndroid Build Coastguard Worker 
2946*61046927SAndroid Build Coastguard Worker    scratch_buffer_size =
2947*61046927SAndroid Build Coastguard Worker       pvr_spm_scratch_buffer_calc_required_size(pass,
2948*61046927SAndroid Build Coastguard Worker                                                 framebuffer->width,
2949*61046927SAndroid Build Coastguard Worker                                                 framebuffer->height);
2950*61046927SAndroid Build Coastguard Worker 
2951*61046927SAndroid Build Coastguard Worker    result = pvr_spm_scratch_buffer_get_buffer(device,
2952*61046927SAndroid Build Coastguard Worker                                               scratch_buffer_size,
2953*61046927SAndroid Build Coastguard Worker                                               &framebuffer->scratch_buffer);
2954*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
2955*61046927SAndroid Build Coastguard Worker       goto err_finish_render_targets;
2956*61046927SAndroid Build Coastguard Worker 
2957*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < pass->hw_setup->render_count; i++) {
2958*61046927SAndroid Build Coastguard Worker       uint32_t emit_count;
2959*61046927SAndroid Build Coastguard Worker 
2960*61046927SAndroid Build Coastguard Worker       result = pvr_spm_init_eot_state(device,
2961*61046927SAndroid Build Coastguard Worker                                       &spm_eot_state_per_render[i],
2962*61046927SAndroid Build Coastguard Worker                                       framebuffer,
2963*61046927SAndroid Build Coastguard Worker                                       &pass->hw_setup->renders[i],
2964*61046927SAndroid Build Coastguard Worker                                       &emit_count);
2965*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2966*61046927SAndroid Build Coastguard Worker          goto err_finish_eot_state;
2967*61046927SAndroid Build Coastguard Worker 
2968*61046927SAndroid Build Coastguard Worker       result = pvr_spm_init_bgobj_state(device,
2969*61046927SAndroid Build Coastguard Worker                                         &spm_bgobj_state_per_render[i],
2970*61046927SAndroid Build Coastguard Worker                                         framebuffer,
2971*61046927SAndroid Build Coastguard Worker                                         &pass->hw_setup->renders[i],
2972*61046927SAndroid Build Coastguard Worker                                         emit_count);
2973*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
2974*61046927SAndroid Build Coastguard Worker          goto err_finish_bgobj_state;
2975*61046927SAndroid Build Coastguard Worker 
2976*61046927SAndroid Build Coastguard Worker       continue;
2977*61046927SAndroid Build Coastguard Worker 
2978*61046927SAndroid Build Coastguard Worker err_finish_bgobj_state:
2979*61046927SAndroid Build Coastguard Worker       pvr_spm_finish_eot_state(device, &spm_eot_state_per_render[i]);
2980*61046927SAndroid Build Coastguard Worker 
2981*61046927SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < i; j++)
2982*61046927SAndroid Build Coastguard Worker          pvr_spm_finish_bgobj_state(device, &spm_bgobj_state_per_render[j]);
2983*61046927SAndroid Build Coastguard Worker 
2984*61046927SAndroid Build Coastguard Worker err_finish_eot_state:
2985*61046927SAndroid Build Coastguard Worker       for (uint32_t j = 0; j < i; j++)
2986*61046927SAndroid Build Coastguard Worker          pvr_spm_finish_eot_state(device, &spm_eot_state_per_render[j]);
2987*61046927SAndroid Build Coastguard Worker 
2988*61046927SAndroid Build Coastguard Worker       goto err_finish_render_targets;
2989*61046927SAndroid Build Coastguard Worker    }
2990*61046927SAndroid Build Coastguard Worker 
2991*61046927SAndroid Build Coastguard Worker    framebuffer->render_count = pass->hw_setup->render_count;
2992*61046927SAndroid Build Coastguard Worker    framebuffer->spm_eot_state_per_render = spm_eot_state_per_render;
2993*61046927SAndroid Build Coastguard Worker    framebuffer->spm_bgobj_state_per_render = spm_bgobj_state_per_render;
2994*61046927SAndroid Build Coastguard Worker 
2995*61046927SAndroid Build Coastguard Worker    *pFramebuffer = pvr_framebuffer_to_handle(framebuffer);
2996*61046927SAndroid Build Coastguard Worker 
2997*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
2998*61046927SAndroid Build Coastguard Worker 
2999*61046927SAndroid Build Coastguard Worker err_finish_render_targets:
3000*61046927SAndroid Build Coastguard Worker    pvr_render_targets_fini(framebuffer->render_targets, render_targets_count);
3001*61046927SAndroid Build Coastguard Worker 
3002*61046927SAndroid Build Coastguard Worker err_free_ppp_state_bo:
3003*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(framebuffer->ppp_state_bo);
3004*61046927SAndroid Build Coastguard Worker 
3005*61046927SAndroid Build Coastguard Worker err_free_framebuffer:
3006*61046927SAndroid Build Coastguard Worker    vk_object_base_finish(&framebuffer->base);
3007*61046927SAndroid Build Coastguard Worker    vk_free2(&device->vk.alloc, pAllocator, framebuffer);
3008*61046927SAndroid Build Coastguard Worker 
3009*61046927SAndroid Build Coastguard Worker    return result;
3010*61046927SAndroid Build Coastguard Worker }
3011*61046927SAndroid Build Coastguard Worker 
pvr_DestroyFramebuffer(VkDevice _device,VkFramebuffer _fb,const VkAllocationCallbacks * pAllocator)3012*61046927SAndroid Build Coastguard Worker void pvr_DestroyFramebuffer(VkDevice _device,
3013*61046927SAndroid Build Coastguard Worker                             VkFramebuffer _fb,
3014*61046927SAndroid Build Coastguard Worker                             const VkAllocationCallbacks *pAllocator)
3015*61046927SAndroid Build Coastguard Worker {
3016*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_framebuffer, framebuffer, _fb);
3017*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
3018*61046927SAndroid Build Coastguard Worker 
3019*61046927SAndroid Build Coastguard Worker    if (!framebuffer)
3020*61046927SAndroid Build Coastguard Worker       return;
3021*61046927SAndroid Build Coastguard Worker 
3022*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < framebuffer->render_count; i++) {
3023*61046927SAndroid Build Coastguard Worker       pvr_spm_finish_bgobj_state(device,
3024*61046927SAndroid Build Coastguard Worker                                  &framebuffer->spm_bgobj_state_per_render[i]);
3025*61046927SAndroid Build Coastguard Worker 
3026*61046927SAndroid Build Coastguard Worker       pvr_spm_finish_eot_state(device,
3027*61046927SAndroid Build Coastguard Worker                                &framebuffer->spm_eot_state_per_render[i]);
3028*61046927SAndroid Build Coastguard Worker    }
3029*61046927SAndroid Build Coastguard Worker 
3030*61046927SAndroid Build Coastguard Worker    pvr_spm_scratch_buffer_release(device, framebuffer->scratch_buffer);
3031*61046927SAndroid Build Coastguard Worker    pvr_render_targets_fini(framebuffer->render_targets,
3032*61046927SAndroid Build Coastguard Worker                            framebuffer->render_targets_count);
3033*61046927SAndroid Build Coastguard Worker    pvr_bo_suballoc_free(framebuffer->ppp_state_bo);
3034*61046927SAndroid Build Coastguard Worker    vk_object_base_finish(&framebuffer->base);
3035*61046927SAndroid Build Coastguard Worker    vk_free2(&device->vk.alloc, pAllocator, framebuffer);
3036*61046927SAndroid Build Coastguard Worker }
3037*61046927SAndroid Build Coastguard Worker 
3038*61046927SAndroid Build Coastguard Worker static uint32_t
pvr_sampler_get_hw_filter_from_vk(const struct pvr_device_info * dev_info,VkFilter filter)3039*61046927SAndroid Build Coastguard Worker pvr_sampler_get_hw_filter_from_vk(const struct pvr_device_info *dev_info,
3040*61046927SAndroid Build Coastguard Worker                                   VkFilter filter)
3041*61046927SAndroid Build Coastguard Worker {
3042*61046927SAndroid Build Coastguard Worker    switch (filter) {
3043*61046927SAndroid Build Coastguard Worker    case VK_FILTER_NEAREST:
3044*61046927SAndroid Build Coastguard Worker       return PVRX(TEXSTATE_FILTER_POINT);
3045*61046927SAndroid Build Coastguard Worker    case VK_FILTER_LINEAR:
3046*61046927SAndroid Build Coastguard Worker       return PVRX(TEXSTATE_FILTER_LINEAR);
3047*61046927SAndroid Build Coastguard Worker    default:
3048*61046927SAndroid Build Coastguard Worker       unreachable("Unknown filter type.");
3049*61046927SAndroid Build Coastguard Worker    }
3050*61046927SAndroid Build Coastguard Worker }
3051*61046927SAndroid Build Coastguard Worker 
3052*61046927SAndroid Build Coastguard Worker static uint32_t
pvr_sampler_get_hw_addr_mode_from_vk(VkSamplerAddressMode addr_mode)3053*61046927SAndroid Build Coastguard Worker pvr_sampler_get_hw_addr_mode_from_vk(VkSamplerAddressMode addr_mode)
3054*61046927SAndroid Build Coastguard Worker {
3055*61046927SAndroid Build Coastguard Worker    switch (addr_mode) {
3056*61046927SAndroid Build Coastguard Worker    case VK_SAMPLER_ADDRESS_MODE_REPEAT:
3057*61046927SAndroid Build Coastguard Worker       return PVRX(TEXSTATE_ADDRMODE_REPEAT);
3058*61046927SAndroid Build Coastguard Worker    case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
3059*61046927SAndroid Build Coastguard Worker       return PVRX(TEXSTATE_ADDRMODE_FLIP);
3060*61046927SAndroid Build Coastguard Worker    case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
3061*61046927SAndroid Build Coastguard Worker       return PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_EDGE);
3062*61046927SAndroid Build Coastguard Worker    case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
3063*61046927SAndroid Build Coastguard Worker       return PVRX(TEXSTATE_ADDRMODE_FLIP_ONCE_THEN_CLAMP);
3064*61046927SAndroid Build Coastguard Worker    case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
3065*61046927SAndroid Build Coastguard Worker       return PVRX(TEXSTATE_ADDRMODE_CLAMP_TO_BORDER);
3066*61046927SAndroid Build Coastguard Worker    default:
3067*61046927SAndroid Build Coastguard Worker       unreachable("Invalid sampler address mode.");
3068*61046927SAndroid Build Coastguard Worker    }
3069*61046927SAndroid Build Coastguard Worker }
3070*61046927SAndroid Build Coastguard Worker 
pvr_CreateSampler(VkDevice _device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)3071*61046927SAndroid Build Coastguard Worker VkResult pvr_CreateSampler(VkDevice _device,
3072*61046927SAndroid Build Coastguard Worker                            const VkSamplerCreateInfo *pCreateInfo,
3073*61046927SAndroid Build Coastguard Worker                            const VkAllocationCallbacks *pAllocator,
3074*61046927SAndroid Build Coastguard Worker                            VkSampler *pSampler)
3075*61046927SAndroid Build Coastguard Worker {
3076*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
3077*61046927SAndroid Build Coastguard Worker    uint32_t border_color_table_index;
3078*61046927SAndroid Build Coastguard Worker    struct pvr_sampler *sampler;
3079*61046927SAndroid Build Coastguard Worker    float lod_rounding_bias;
3080*61046927SAndroid Build Coastguard Worker    VkFilter min_filter;
3081*61046927SAndroid Build Coastguard Worker    VkFilter mag_filter;
3082*61046927SAndroid Build Coastguard Worker    VkResult result;
3083*61046927SAndroid Build Coastguard Worker    float min_lod;
3084*61046927SAndroid Build Coastguard Worker    float max_lod;
3085*61046927SAndroid Build Coastguard Worker 
3086*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(sizeof(((union pvr_sampler_descriptor *)NULL)->data) ==
3087*61046927SAndroid Build Coastguard Worker                  sizeof(((union pvr_sampler_descriptor *)NULL)->words));
3088*61046927SAndroid Build Coastguard Worker 
3089*61046927SAndroid Build Coastguard Worker    sampler =
3090*61046927SAndroid Build Coastguard Worker       vk_sampler_create(&device->vk, pCreateInfo, pAllocator, sizeof(*sampler));
3091*61046927SAndroid Build Coastguard Worker    if (!sampler) {
3092*61046927SAndroid Build Coastguard Worker       result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
3093*61046927SAndroid Build Coastguard Worker       goto err_out;
3094*61046927SAndroid Build Coastguard Worker    }
3095*61046927SAndroid Build Coastguard Worker 
3096*61046927SAndroid Build Coastguard Worker    mag_filter = pCreateInfo->magFilter;
3097*61046927SAndroid Build Coastguard Worker    min_filter = pCreateInfo->minFilter;
3098*61046927SAndroid Build Coastguard Worker 
3099*61046927SAndroid Build Coastguard Worker    result =
3100*61046927SAndroid Build Coastguard Worker       pvr_border_color_table_get_or_create_entry(&device->border_color_table,
3101*61046927SAndroid Build Coastguard Worker                                                  sampler,
3102*61046927SAndroid Build Coastguard Worker                                                  &border_color_table_index);
3103*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
3104*61046927SAndroid Build Coastguard Worker       goto err_free_sampler;
3105*61046927SAndroid Build Coastguard Worker 
3106*61046927SAndroid Build Coastguard Worker    if (PVR_HAS_QUIRK(&device->pdevice->dev_info, 51025)) {
3107*61046927SAndroid Build Coastguard Worker       /* The min/mag filters may need adjustment here, the GPU should decide
3108*61046927SAndroid Build Coastguard Worker        * which of the two filters to use based on the clamped LOD value: LOD
3109*61046927SAndroid Build Coastguard Worker        * <= 0 implies magnification, while LOD > 0 implies minification.
3110*61046927SAndroid Build Coastguard Worker        *
3111*61046927SAndroid Build Coastguard Worker        * As a workaround, we override magFilter with minFilter if we know that
3112*61046927SAndroid Build Coastguard Worker        * the magnification filter will never be used due to clamping anyway
3113*61046927SAndroid Build Coastguard Worker        * (i.e. minLod > 0). Conversely, we override minFilter with magFilter
3114*61046927SAndroid Build Coastguard Worker        * if maxLod <= 0.
3115*61046927SAndroid Build Coastguard Worker        */
3116*61046927SAndroid Build Coastguard Worker       if (pCreateInfo->minLod > 0.0f) {
3117*61046927SAndroid Build Coastguard Worker          /* The clamped LOD will always be positive => always minify. */
3118*61046927SAndroid Build Coastguard Worker          mag_filter = pCreateInfo->minFilter;
3119*61046927SAndroid Build Coastguard Worker       }
3120*61046927SAndroid Build Coastguard Worker 
3121*61046927SAndroid Build Coastguard Worker       if (pCreateInfo->maxLod <= 0.0f) {
3122*61046927SAndroid Build Coastguard Worker          /* The clamped LOD will always be negative or zero => always
3123*61046927SAndroid Build Coastguard Worker           * magnify.
3124*61046927SAndroid Build Coastguard Worker           */
3125*61046927SAndroid Build Coastguard Worker          min_filter = pCreateInfo->magFilter;
3126*61046927SAndroid Build Coastguard Worker       }
3127*61046927SAndroid Build Coastguard Worker    }
3128*61046927SAndroid Build Coastguard Worker 
3129*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->compareEnable) {
3130*61046927SAndroid Build Coastguard Worker       sampler->descriptor.data.compare_op =
3131*61046927SAndroid Build Coastguard Worker          (uint32_t)pvr_texstate_cmpmode(pCreateInfo->compareOp);
3132*61046927SAndroid Build Coastguard Worker    } else {
3133*61046927SAndroid Build Coastguard Worker       sampler->descriptor.data.compare_op =
3134*61046927SAndroid Build Coastguard Worker          (uint32_t)pvr_texstate_cmpmode(VK_COMPARE_OP_NEVER);
3135*61046927SAndroid Build Coastguard Worker    }
3136*61046927SAndroid Build Coastguard Worker 
3137*61046927SAndroid Build Coastguard Worker    sampler->descriptor.data.word3 = 0;
3138*61046927SAndroid Build Coastguard Worker    pvr_csb_pack (&sampler->descriptor.data.sampler_word,
3139*61046927SAndroid Build Coastguard Worker                  TEXSTATE_SAMPLER,
3140*61046927SAndroid Build Coastguard Worker                  word) {
3141*61046927SAndroid Build Coastguard Worker       const struct pvr_device_info *dev_info = &device->pdevice->dev_info;
3142*61046927SAndroid Build Coastguard Worker       const float lod_clamp_max = (float)PVRX(TEXSTATE_CLAMP_MAX) /
3143*61046927SAndroid Build Coastguard Worker                                   (1 << PVRX(TEXSTATE_CLAMP_FRACTIONAL_BITS));
3144*61046927SAndroid Build Coastguard Worker       const float max_dadjust = ((float)(PVRX(TEXSTATE_DADJUST_MAX_UINT) -
3145*61046927SAndroid Build Coastguard Worker                                          PVRX(TEXSTATE_DADJUST_ZERO_UINT))) /
3146*61046927SAndroid Build Coastguard Worker                                 (1 << PVRX(TEXSTATE_DADJUST_FRACTIONAL_BITS));
3147*61046927SAndroid Build Coastguard Worker       const float min_dadjust = ((float)(PVRX(TEXSTATE_DADJUST_MIN_UINT) -
3148*61046927SAndroid Build Coastguard Worker                                          PVRX(TEXSTATE_DADJUST_ZERO_UINT))) /
3149*61046927SAndroid Build Coastguard Worker                                 (1 << PVRX(TEXSTATE_DADJUST_FRACTIONAL_BITS));
3150*61046927SAndroid Build Coastguard Worker 
3151*61046927SAndroid Build Coastguard Worker       word.magfilter = pvr_sampler_get_hw_filter_from_vk(dev_info, mag_filter);
3152*61046927SAndroid Build Coastguard Worker       word.minfilter = pvr_sampler_get_hw_filter_from_vk(dev_info, min_filter);
3153*61046927SAndroid Build Coastguard Worker 
3154*61046927SAndroid Build Coastguard Worker       if (pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR)
3155*61046927SAndroid Build Coastguard Worker          word.mipfilter = true;
3156*61046927SAndroid Build Coastguard Worker 
3157*61046927SAndroid Build Coastguard Worker       word.addrmode_u =
3158*61046927SAndroid Build Coastguard Worker          pvr_sampler_get_hw_addr_mode_from_vk(pCreateInfo->addressModeU);
3159*61046927SAndroid Build Coastguard Worker       word.addrmode_v =
3160*61046927SAndroid Build Coastguard Worker          pvr_sampler_get_hw_addr_mode_from_vk(pCreateInfo->addressModeV);
3161*61046927SAndroid Build Coastguard Worker       word.addrmode_w =
3162*61046927SAndroid Build Coastguard Worker          pvr_sampler_get_hw_addr_mode_from_vk(pCreateInfo->addressModeW);
3163*61046927SAndroid Build Coastguard Worker 
3164*61046927SAndroid Build Coastguard Worker       /* TODO: Figure out defines for these. */
3165*61046927SAndroid Build Coastguard Worker       if (word.addrmode_u == PVRX(TEXSTATE_ADDRMODE_FLIP))
3166*61046927SAndroid Build Coastguard Worker          sampler->descriptor.data.word3 |= 0x40000000;
3167*61046927SAndroid Build Coastguard Worker 
3168*61046927SAndroid Build Coastguard Worker       if (word.addrmode_v == PVRX(TEXSTATE_ADDRMODE_FLIP))
3169*61046927SAndroid Build Coastguard Worker          sampler->descriptor.data.word3 |= 0x20000000;
3170*61046927SAndroid Build Coastguard Worker 
3171*61046927SAndroid Build Coastguard Worker       /* The Vulkan 1.0.205 spec says:
3172*61046927SAndroid Build Coastguard Worker        *
3173*61046927SAndroid Build Coastguard Worker        *    The absolute value of mipLodBias must be less than or equal to
3174*61046927SAndroid Build Coastguard Worker        *    VkPhysicalDeviceLimits::maxSamplerLodBias.
3175*61046927SAndroid Build Coastguard Worker        */
3176*61046927SAndroid Build Coastguard Worker       word.dadjust =
3177*61046927SAndroid Build Coastguard Worker          PVRX(TEXSTATE_DADJUST_ZERO_UINT) +
3178*61046927SAndroid Build Coastguard Worker          util_signed_fixed(
3179*61046927SAndroid Build Coastguard Worker             CLAMP(pCreateInfo->mipLodBias, min_dadjust, max_dadjust),
3180*61046927SAndroid Build Coastguard Worker             PVRX(TEXSTATE_DADJUST_FRACTIONAL_BITS));
3181*61046927SAndroid Build Coastguard Worker 
3182*61046927SAndroid Build Coastguard Worker       /* Anisotropy is not supported for now. */
3183*61046927SAndroid Build Coastguard Worker       word.anisoctl = PVRX(TEXSTATE_ANISOCTL_DISABLED);
3184*61046927SAndroid Build Coastguard Worker 
3185*61046927SAndroid Build Coastguard Worker       if (PVR_HAS_QUIRK(&device->pdevice->dev_info, 51025) &&
3186*61046927SAndroid Build Coastguard Worker           pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_NEAREST) {
3187*61046927SAndroid Build Coastguard Worker          /* When MIPMAP_MODE_NEAREST is enabled, the LOD level should be
3188*61046927SAndroid Build Coastguard Worker           * selected by adding 0.5 and then truncating the input LOD value.
3189*61046927SAndroid Build Coastguard Worker           * This hardware adds the 0.5 bias before clamping against
3190*61046927SAndroid Build Coastguard Worker           * lodmin/lodmax, while Vulkan specifies the bias to be added after
3191*61046927SAndroid Build Coastguard Worker           * clamping. We compensate for this difference by adding the 0.5
3192*61046927SAndroid Build Coastguard Worker           * bias to the LOD bounds, too.
3193*61046927SAndroid Build Coastguard Worker           */
3194*61046927SAndroid Build Coastguard Worker          lod_rounding_bias = 0.5f;
3195*61046927SAndroid Build Coastguard Worker       } else {
3196*61046927SAndroid Build Coastguard Worker          lod_rounding_bias = 0.0f;
3197*61046927SAndroid Build Coastguard Worker       }
3198*61046927SAndroid Build Coastguard Worker 
3199*61046927SAndroid Build Coastguard Worker       min_lod = pCreateInfo->minLod + lod_rounding_bias;
3200*61046927SAndroid Build Coastguard Worker       word.minlod = util_unsigned_fixed(CLAMP(min_lod, 0.0f, lod_clamp_max),
3201*61046927SAndroid Build Coastguard Worker                                         PVRX(TEXSTATE_CLAMP_FRACTIONAL_BITS));
3202*61046927SAndroid Build Coastguard Worker 
3203*61046927SAndroid Build Coastguard Worker       max_lod = pCreateInfo->maxLod + lod_rounding_bias;
3204*61046927SAndroid Build Coastguard Worker       word.maxlod = util_unsigned_fixed(CLAMP(max_lod, 0.0f, lod_clamp_max),
3205*61046927SAndroid Build Coastguard Worker                                         PVRX(TEXSTATE_CLAMP_FRACTIONAL_BITS));
3206*61046927SAndroid Build Coastguard Worker 
3207*61046927SAndroid Build Coastguard Worker       word.bordercolor_index = border_color_table_index;
3208*61046927SAndroid Build Coastguard Worker 
3209*61046927SAndroid Build Coastguard Worker       if (pCreateInfo->unnormalizedCoordinates)
3210*61046927SAndroid Build Coastguard Worker          word.non_normalized_coords = true;
3211*61046927SAndroid Build Coastguard Worker    }
3212*61046927SAndroid Build Coastguard Worker 
3213*61046927SAndroid Build Coastguard Worker    *pSampler = pvr_sampler_to_handle(sampler);
3214*61046927SAndroid Build Coastguard Worker 
3215*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
3216*61046927SAndroid Build Coastguard Worker 
3217*61046927SAndroid Build Coastguard Worker err_free_sampler:
3218*61046927SAndroid Build Coastguard Worker    vk_object_free(&device->vk, pAllocator, sampler);
3219*61046927SAndroid Build Coastguard Worker 
3220*61046927SAndroid Build Coastguard Worker err_out:
3221*61046927SAndroid Build Coastguard Worker    return result;
3222*61046927SAndroid Build Coastguard Worker }
3223*61046927SAndroid Build Coastguard Worker 
pvr_DestroySampler(VkDevice _device,VkSampler _sampler,const VkAllocationCallbacks * pAllocator)3224*61046927SAndroid Build Coastguard Worker void pvr_DestroySampler(VkDevice _device,
3225*61046927SAndroid Build Coastguard Worker                         VkSampler _sampler,
3226*61046927SAndroid Build Coastguard Worker                         const VkAllocationCallbacks *pAllocator)
3227*61046927SAndroid Build Coastguard Worker {
3228*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
3229*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_sampler, sampler, _sampler);
3230*61046927SAndroid Build Coastguard Worker 
3231*61046927SAndroid Build Coastguard Worker    if (!sampler)
3232*61046927SAndroid Build Coastguard Worker       return;
3233*61046927SAndroid Build Coastguard Worker 
3234*61046927SAndroid Build Coastguard Worker    vk_sampler_destroy(&device->vk, pAllocator, &sampler->vk);
3235*61046927SAndroid Build Coastguard Worker }
3236*61046927SAndroid Build Coastguard Worker 
pvr_GetBufferMemoryRequirements2(VkDevice _device,const VkBufferMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)3237*61046927SAndroid Build Coastguard Worker void pvr_GetBufferMemoryRequirements2(
3238*61046927SAndroid Build Coastguard Worker    VkDevice _device,
3239*61046927SAndroid Build Coastguard Worker    const VkBufferMemoryRequirementsInfo2 *pInfo,
3240*61046927SAndroid Build Coastguard Worker    VkMemoryRequirements2 *pMemoryRequirements)
3241*61046927SAndroid Build Coastguard Worker {
3242*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_buffer, buffer, pInfo->buffer);
3243*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
3244*61046927SAndroid Build Coastguard Worker    uint64_t size;
3245*61046927SAndroid Build Coastguard Worker 
3246*61046927SAndroid Build Coastguard Worker    /* The Vulkan 1.0.166 spec says:
3247*61046927SAndroid Build Coastguard Worker     *
3248*61046927SAndroid Build Coastguard Worker     *    memoryTypeBits is a bitmask and contains one bit set for every
3249*61046927SAndroid Build Coastguard Worker     *    supported memory type for the resource. Bit 'i' is set if and only
3250*61046927SAndroid Build Coastguard Worker     *    if the memory type 'i' in the VkPhysicalDeviceMemoryProperties
3251*61046927SAndroid Build Coastguard Worker     *    structure for the physical device is supported for the resource.
3252*61046927SAndroid Build Coastguard Worker     *
3253*61046927SAndroid Build Coastguard Worker     * All types are currently supported for buffers.
3254*61046927SAndroid Build Coastguard Worker     */
3255*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.memoryTypeBits =
3256*61046927SAndroid Build Coastguard Worker       (1ul << device->pdevice->memory.memoryTypeCount) - 1;
3257*61046927SAndroid Build Coastguard Worker 
3258*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.alignment = buffer->alignment;
3259*61046927SAndroid Build Coastguard Worker 
3260*61046927SAndroid Build Coastguard Worker    size = buffer->vk.size;
3261*61046927SAndroid Build Coastguard Worker 
3262*61046927SAndroid Build Coastguard Worker    if (size % device->ws->page_size == 0 ||
3263*61046927SAndroid Build Coastguard Worker        size % device->ws->page_size >
3264*61046927SAndroid Build Coastguard Worker           device->ws->page_size - PVR_BUFFER_MEMORY_PADDING_SIZE) {
3265*61046927SAndroid Build Coastguard Worker       /* TODO: We can save memory by having one extra virtual page mapped
3266*61046927SAndroid Build Coastguard Worker        * in and having the first and last virtual page mapped to the first
3267*61046927SAndroid Build Coastguard Worker        * physical address.
3268*61046927SAndroid Build Coastguard Worker        */
3269*61046927SAndroid Build Coastguard Worker       size += PVR_BUFFER_MEMORY_PADDING_SIZE;
3270*61046927SAndroid Build Coastguard Worker    }
3271*61046927SAndroid Build Coastguard Worker 
3272*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.size =
3273*61046927SAndroid Build Coastguard Worker       ALIGN_POT(size, buffer->alignment);
3274*61046927SAndroid Build Coastguard Worker }
3275*61046927SAndroid Build Coastguard Worker 
pvr_GetImageMemoryRequirements2(VkDevice _device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)3276*61046927SAndroid Build Coastguard Worker void pvr_GetImageMemoryRequirements2(VkDevice _device,
3277*61046927SAndroid Build Coastguard Worker                                      const VkImageMemoryRequirementsInfo2 *pInfo,
3278*61046927SAndroid Build Coastguard Worker                                      VkMemoryRequirements2 *pMemoryRequirements)
3279*61046927SAndroid Build Coastguard Worker {
3280*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_device, device, _device);
3281*61046927SAndroid Build Coastguard Worker    PVR_FROM_HANDLE(pvr_image, image, pInfo->image);
3282*61046927SAndroid Build Coastguard Worker 
3283*61046927SAndroid Build Coastguard Worker    /* The Vulkan 1.0.166 spec says:
3284*61046927SAndroid Build Coastguard Worker     *
3285*61046927SAndroid Build Coastguard Worker     *    memoryTypeBits is a bitmask and contains one bit set for every
3286*61046927SAndroid Build Coastguard Worker     *    supported memory type for the resource. Bit 'i' is set if and only
3287*61046927SAndroid Build Coastguard Worker     *    if the memory type 'i' in the VkPhysicalDeviceMemoryProperties
3288*61046927SAndroid Build Coastguard Worker     *    structure for the physical device is supported for the resource.
3289*61046927SAndroid Build Coastguard Worker     *
3290*61046927SAndroid Build Coastguard Worker     * All types are currently supported for images.
3291*61046927SAndroid Build Coastguard Worker     */
3292*61046927SAndroid Build Coastguard Worker    const uint32_t memory_types =
3293*61046927SAndroid Build Coastguard Worker       (1ul << device->pdevice->memory.memoryTypeCount) - 1;
3294*61046927SAndroid Build Coastguard Worker 
3295*61046927SAndroid Build Coastguard Worker    /* TODO: The returned size is aligned here in case of arrays/CEM (as is done
3296*61046927SAndroid Build Coastguard Worker     * in GetImageMemoryRequirements()), but this should be known at image
3297*61046927SAndroid Build Coastguard Worker     * creation time (pCreateInfo->arrayLayers > 1). This is confirmed in
3298*61046927SAndroid Build Coastguard Worker     * ImageCreate()/ImageGetMipMapOffsetInBytes() where it aligns the size to
3299*61046927SAndroid Build Coastguard Worker     * 4096 if pCreateInfo->arrayLayers > 1. So is the alignment here actually
3300*61046927SAndroid Build Coastguard Worker     * necessary? If not, what should it be when pCreateInfo->arrayLayers == 1?
3301*61046927SAndroid Build Coastguard Worker     *
3302*61046927SAndroid Build Coastguard Worker     * Note: Presumably the 4096 alignment requirement comes from the Vulkan
3303*61046927SAndroid Build Coastguard Worker     * driver setting RGX_CR_TPU_TAG_CEM_4K_FACE_PACKING_EN when setting up
3304*61046927SAndroid Build Coastguard Worker     * render and compute jobs.
3305*61046927SAndroid Build Coastguard Worker     */
3306*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.alignment = image->alignment;
3307*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.size =
3308*61046927SAndroid Build Coastguard Worker       align64(image->size, image->alignment);
3309*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.memoryTypeBits = memory_types;
3310*61046927SAndroid Build Coastguard Worker }
3311