1 /*
2 * Copyright © 2022 Imagination Technologies Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stddef.h>
26 #include <stdint.h>
27 #include <vulkan/vulkan.h>
28
29 #include "pvr_bo.h"
30 #include "pvr_csb.h"
31 #include "pvr_device_info.h"
32 #include "pvr_private.h"
33 #include "util/macros.h"
34 #include "vk_log.h"
35 #include "vk_object.h"
36
pvr_CreateQueryPool(VkDevice _device,const VkQueryPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkQueryPool * pQueryPool)37 VkResult pvr_CreateQueryPool(VkDevice _device,
38 const VkQueryPoolCreateInfo *pCreateInfo,
39 const VkAllocationCallbacks *pAllocator,
40 VkQueryPool *pQueryPool)
41 {
42 PVR_FROM_HANDLE(pvr_device, device, _device);
43 const uint32_t core_count = device->pdevice->dev_runtime_info.core_count;
44 const uint32_t query_size = pCreateInfo->queryCount * sizeof(uint32_t);
45 struct pvr_query_pool *pool;
46 uint64_t alloc_size;
47 VkResult result;
48
49 /* Vulkan 1.0 supports only occlusion, timestamp, and pipeline statistics
50 * query.
51 * We don't currently support timestamp queries.
52 * VkQueueFamilyProperties->timestampValidBits = 0.
53 * We don't currently support pipeline statistics queries.
54 * VkPhysicalDeviceFeatures->pipelineStatisticsQuery = false.
55 */
56 assert(!device->features.pipelineStatisticsQuery);
57 assert(pCreateInfo->queryType == VK_QUERY_TYPE_OCCLUSION);
58
59 pool = vk_object_alloc(&device->vk,
60 pAllocator,
61 sizeof(*pool),
62 VK_OBJECT_TYPE_QUERY_POOL);
63 if (!pool)
64 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
65
66 pool->result_stride =
67 ALIGN_POT(query_size, PVRX(CR_ISP_OCLQRY_BASE_ADDR_ALIGNMENT));
68
69 /* Each Phantom writes to a separate offset within the vis test heap so
70 * allocate space for the total number of Phantoms.
71 */
72 alloc_size = pool->result_stride * core_count;
73
74 result = pvr_bo_alloc(device,
75 device->heaps.vis_test_heap,
76 alloc_size,
77 PVRX(CR_ISP_OCLQRY_BASE_ADDR_ALIGNMENT),
78 PVR_BO_ALLOC_FLAG_CPU_MAPPED,
79 &pool->result_buffer);
80 if (result != VK_SUCCESS)
81 goto err_free_pool;
82
83 result = pvr_bo_alloc(device,
84 device->heaps.vis_test_heap,
85 query_size,
86 sizeof(uint32_t),
87 PVR_BO_ALLOC_FLAG_CPU_MAPPED,
88 &pool->availability_buffer);
89 if (result != VK_SUCCESS)
90 goto err_free_result_buffer;
91
92 *pQueryPool = pvr_query_pool_to_handle(pool);
93
94 return VK_SUCCESS;
95
96 err_free_result_buffer:
97 pvr_bo_free(device, pool->result_buffer);
98
99 err_free_pool:
100 vk_object_free(&device->vk, pAllocator, pool);
101
102 return result;
103 }
104
pvr_DestroyQueryPool(VkDevice _device,VkQueryPool queryPool,const VkAllocationCallbacks * pAllocator)105 void pvr_DestroyQueryPool(VkDevice _device,
106 VkQueryPool queryPool,
107 const VkAllocationCallbacks *pAllocator)
108 {
109 PVR_FROM_HANDLE(pvr_query_pool, pool, queryPool);
110 PVR_FROM_HANDLE(pvr_device, device, _device);
111
112 pvr_bo_free(device, pool->availability_buffer);
113 pvr_bo_free(device, pool->result_buffer);
114
115 vk_object_free(&device->vk, pAllocator, pool);
116 }
117
pvr_GetQueryPoolResults(VkDevice _device,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,size_t dataSize,void * pData,VkDeviceSize stride,VkQueryResultFlags flags)118 VkResult pvr_GetQueryPoolResults(VkDevice _device,
119 VkQueryPool queryPool,
120 uint32_t firstQuery,
121 uint32_t queryCount,
122 size_t dataSize,
123 void *pData,
124 VkDeviceSize stride,
125 VkQueryResultFlags flags)
126 {
127 assert(!"Unimplemented");
128 return VK_SUCCESS;
129 }
130
pvr_CmdResetQueryPool(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount)131 void pvr_CmdResetQueryPool(VkCommandBuffer commandBuffer,
132 VkQueryPool queryPool,
133 uint32_t firstQuery,
134 uint32_t queryCount)
135 {
136 assert(!"Unimplemented");
137 }
138
pvr_CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize stride,VkQueryResultFlags flags)139 void pvr_CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer,
140 VkQueryPool queryPool,
141 uint32_t firstQuery,
142 uint32_t queryCount,
143 VkBuffer dstBuffer,
144 VkDeviceSize dstOffset,
145 VkDeviceSize stride,
146 VkQueryResultFlags flags)
147 {
148 assert(!"Unimplemented");
149 }
150
pvr_CmdBeginQuery(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t query,VkQueryControlFlags flags)151 void pvr_CmdBeginQuery(VkCommandBuffer commandBuffer,
152 VkQueryPool queryPool,
153 uint32_t query,
154 VkQueryControlFlags flags)
155 {
156 assert(!"Unimplemented");
157 }
158
pvr_CmdEndQuery(VkCommandBuffer commandBuffer,VkQueryPool queryPool,uint32_t query)159 void pvr_CmdEndQuery(VkCommandBuffer commandBuffer,
160 VkQueryPool queryPool,
161 uint32_t query)
162 {
163 assert(!"Unimplemented");
164 }
165