VkProtectedContextTest.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /*
  2. * Copyright 2019 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. // This is a Vulkan protected memory specific test.
  8. #include "include/core/SkTypes.h"
  9. #if SK_SUPPORT_GPU && defined(SK_VULKAN)
  10. #include "include/core/SkCanvas.h"
  11. #include "include/core/SkMaskFilter.h"
  12. #include "include/core/SkPaint.h"
  13. #include "include/core/SkSurface.h"
  14. #include "include/gpu/GrBackendSurface.h"
  15. #include "include/gpu/vk/GrVkBackendContext.h"
  16. #include "include/gpu/vk/GrVkExtensions.h"
  17. #include "tests/Test.h"
  18. #include "tools/gpu/GrContextFactory.h"
  19. #include "tools/gpu/vk/VkTestUtils.h"
  20. namespace {
  21. #define DECLARE_VK_PROC(name) PFN_vk##name fVk##name
  22. #define ACQUIRE_INST_VK_PROC(name) \
  23. fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, fBackendContext.fInstance,\
  24. VK_NULL_HANDLE)); \
  25. if (fVk##name == nullptr) { \
  26. ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name); \
  27. return false; \
  28. }
  29. #define ACQUIRE_DEVICE_VK_PROC(name) \
  30. fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, VK_NULL_HANDLE, fDevice)); \
  31. if (fVk##name == nullptr) { \
  32. ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name); \
  33. return false; \
  34. }
  35. class VulkanTestHelper {
  36. public:
  37. VulkanTestHelper(bool isProtected) : fIsProtected(isProtected) {}
  38. ~VulkanTestHelper() {
  39. cleanup();
  40. }
  41. bool init(skiatest::Reporter* reporter);
  42. GrContext* grContext() { return fGrContext.get(); }
  43. sk_sp<SkSurface> createSkSurface(skiatest::Reporter* reporter);
  44. private:
  45. void cleanup();
  46. DECLARE_VK_PROC(DestroyInstance);
  47. DECLARE_VK_PROC(DeviceWaitIdle);
  48. DECLARE_VK_PROC(DestroyDevice);
  49. bool fIsProtected = false;
  50. VkDevice fDevice = VK_NULL_HANDLE;
  51. GrVkExtensions* fExtensions = nullptr;
  52. VkPhysicalDeviceFeatures2* fFeatures = nullptr;
  53. VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
  54. PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugCallback = nullptr;
  55. GrVkBackendContext fBackendContext;
  56. sk_sp<GrContext> fGrContext;
  57. };
  58. } // namespace
  59. bool VulkanTestHelper::init(skiatest::Reporter* reporter) {
  60. PFN_vkGetInstanceProcAddr instProc;
  61. PFN_vkGetDeviceProcAddr devProc;
  62. if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
  63. return false;
  64. }
  65. auto getProc = [&instProc, &devProc](const char* proc_name,
  66. VkInstance instance, VkDevice device) {
  67. if (device != VK_NULL_HANDLE) {
  68. return devProc(device, proc_name);
  69. }
  70. return instProc(instance, proc_name);
  71. };
  72. fExtensions = new GrVkExtensions();
  73. fFeatures = new VkPhysicalDeviceFeatures2;
  74. memset(fFeatures, 0, sizeof(VkPhysicalDeviceFeatures2));
  75. fFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
  76. fFeatures->pNext = nullptr;
  77. fBackendContext.fInstance = VK_NULL_HANDLE;
  78. fBackendContext.fDevice = VK_NULL_HANDLE;
  79. if (!sk_gpu_test::CreateVkBackendContext(getProc, &fBackendContext, fExtensions,
  80. fFeatures, &fDebugCallback, nullptr,
  81. sk_gpu_test::CanPresentFn(), fIsProtected)) {
  82. return false;
  83. }
  84. fDevice = fBackendContext.fDevice;
  85. if (fDebugCallback != VK_NULL_HANDLE) {
  86. fDestroyDebugCallback = (PFN_vkDestroyDebugReportCallbackEXT) instProc(
  87. fBackendContext.fInstance, "vkDestroyDebugReportCallbackEXT");
  88. }
  89. ACQUIRE_INST_VK_PROC(DestroyInstance)
  90. ACQUIRE_INST_VK_PROC(DeviceWaitIdle)
  91. ACQUIRE_INST_VK_PROC(DestroyDevice)
  92. fGrContext = GrContext::MakeVulkan(fBackendContext);
  93. if (!fGrContext) {
  94. return false;
  95. }
  96. return true;
  97. }
  98. void VulkanTestHelper::cleanup() {
  99. fGrContext.reset();
  100. fBackendContext.fMemoryAllocator.reset();
  101. if (fDevice != VK_NULL_HANDLE) {
  102. fVkDeviceWaitIdle(fDevice);
  103. fVkDestroyDevice(fDevice, nullptr);
  104. fDevice = VK_NULL_HANDLE;
  105. }
  106. if (fDebugCallback != VK_NULL_HANDLE) {
  107. fDestroyDebugCallback(fBackendContext.fInstance, fDebugCallback, nullptr);
  108. }
  109. if (fBackendContext.fInstance != VK_NULL_HANDLE) {
  110. fVkDestroyInstance(fBackendContext.fInstance, nullptr);
  111. fBackendContext.fInstance = VK_NULL_HANDLE;
  112. }
  113. delete fExtensions;
  114. sk_gpu_test::FreeVulkanFeaturesStructs(fFeatures);
  115. delete fFeatures;
  116. }
  117. sk_sp<SkSurface> VulkanTestHelper::createSkSurface(skiatest::Reporter* reporter) {
  118. const int kW = 8;
  119. const int kH = 8;
  120. GrBackendTexture backendTex = grContext()->createBackendTexture(
  121. kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
  122. fIsProtected ? GrProtected::kYes : GrProtected::kNo);
  123. REPORTER_ASSERT(reporter, backendTex.isValid());
  124. REPORTER_ASSERT(reporter, backendTex.isProtected() == fIsProtected);
  125. SkSurfaceProps surfaceProps =
  126. SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
  127. sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
  128. grContext(), backendTex, kTopLeft_GrSurfaceOrigin, 1,
  129. kRGBA_8888_SkColorType, nullptr, &surfaceProps);
  130. REPORTER_ASSERT(reporter, surface);
  131. return surface;
  132. }
  133. DEF_GPUTEST(VkProtectedContext_CreateNonprotectedContext, reporter, options) {
  134. auto nonprotectedTestHelper = std::make_unique<VulkanTestHelper>(false);
  135. REPORTER_ASSERT(reporter, nonprotectedTestHelper->init(reporter));
  136. }
  137. DEF_GPUTEST(VkProtectedContext_CreateProtectedContext, reporter, options) {
  138. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  139. if (!protectedTestHelper->init(reporter)) {
  140. return;
  141. }
  142. }
  143. DEF_GPUTEST(VkProtectedContext_CreateProtectedSkSurface, reporter, options) {
  144. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  145. if (!protectedTestHelper->init(reporter)) {
  146. return;
  147. }
  148. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  149. const int kW = 8;
  150. const int kH = 8;
  151. GrBackendTexture backendTex =
  152. protectedTestHelper->grContext()->createBackendTexture(
  153. kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
  154. GrProtected::kYes);
  155. REPORTER_ASSERT(reporter, backendTex.isValid());
  156. REPORTER_ASSERT(reporter, backendTex.isProtected());
  157. SkSurfaceProps surfaceProps =
  158. SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
  159. sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(
  160. protectedTestHelper->grContext(), backendTex, kTopLeft_GrSurfaceOrigin, 1,
  161. kRGBA_8888_SkColorType, nullptr, &surfaceProps);
  162. REPORTER_ASSERT(reporter, surface);
  163. protectedTestHelper->grContext()->deleteBackendTexture(backendTex);
  164. }
  165. DEF_GPUTEST(VkProtectedContext_CreateNonprotectedTextureInProtectedContext, reporter, options) {
  166. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  167. if (!protectedTestHelper->init(reporter)) {
  168. return;
  169. }
  170. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  171. const int kW = 8;
  172. const int kH = 8;
  173. GrBackendTexture backendTex =
  174. protectedTestHelper->grContext()->createBackendTexture(
  175. kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
  176. GrProtected::kNo);
  177. REPORTER_ASSERT(reporter, !backendTex.isValid());
  178. }
  179. DEF_GPUTEST(VkProtectedContext_CreateProtectedTextureInNonprotectedContext, reporter, options) {
  180. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(false);
  181. if (!protectedTestHelper->init(reporter)) {
  182. return;
  183. }
  184. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  185. const int kW = 8;
  186. const int kH = 8;
  187. GrBackendTexture backendTex =
  188. protectedTestHelper->grContext()->createBackendTexture(
  189. kW, kH, kRGBA_8888_SkColorType, GrMipMapped::kNo, GrRenderable::kNo,
  190. GrProtected::kYes);
  191. REPORTER_ASSERT(reporter, !backendTex.isValid());
  192. }
  193. DEF_GPUTEST(VkProtectedContext_ReadFromProtectedSurface, reporter, options) {
  194. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  195. if (!protectedTestHelper->init(reporter)) {
  196. return;
  197. }
  198. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  199. auto surface = protectedTestHelper->createSkSurface(reporter);
  200. REPORTER_ASSERT(reporter, surface);
  201. REPORTER_ASSERT(reporter,
  202. !surface->readPixels(SkImageInfo(), nullptr, 8, 0, 0));
  203. protectedTestHelper->grContext()->deleteBackendTexture(
  204. surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
  205. }
  206. DEF_GPUTEST(VkProtectedContext_DrawRectangle, reporter, options) {
  207. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  208. if (!protectedTestHelper->init(reporter)) {
  209. return;
  210. }
  211. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  212. auto surface = protectedTestHelper->createSkSurface(reporter);
  213. REPORTER_ASSERT(reporter, surface);
  214. SkCanvas* canvas = surface->getCanvas();
  215. REPORTER_ASSERT(reporter, canvas);
  216. SkPaint paint;
  217. paint.setColor(SK_ColorBLACK);
  218. canvas->drawRect(SkRect::MakeWH(4, 4), paint);
  219. GrFlushInfo flushInfo;
  220. flushInfo.fFlags = kSyncCpu_GrFlushFlag;
  221. surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  222. protectedTestHelper->grContext()->deleteBackendTexture(
  223. surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
  224. }
  225. DEF_GPUTEST(VkProtectedContext_DrawRectangleWithAntiAlias, reporter, options) {
  226. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  227. if (!protectedTestHelper->init(reporter)) {
  228. return;
  229. }
  230. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  231. auto surface = protectedTestHelper->createSkSurface(reporter);
  232. REPORTER_ASSERT(reporter, surface);
  233. SkCanvas* canvas = surface->getCanvas();
  234. REPORTER_ASSERT(reporter, canvas);
  235. SkPaint paint;
  236. paint.setColor(SK_ColorBLACK);
  237. paint.setAntiAlias(true);
  238. canvas->drawRect(SkRect::MakeWH(4, 4), paint);
  239. GrFlushInfo flushInfo;
  240. flushInfo.fFlags = kSyncCpu_GrFlushFlag;
  241. surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  242. protectedTestHelper->grContext()->deleteBackendTexture(
  243. surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
  244. }
  245. DEF_GPUTEST(VkProtectedContext_DrawRectangleWithBlendMode, reporter, options) {
  246. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  247. if (!protectedTestHelper->init(reporter)) {
  248. return;
  249. }
  250. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  251. auto surface = protectedTestHelper->createSkSurface(reporter);
  252. REPORTER_ASSERT(reporter, surface);
  253. SkCanvas* canvas = surface->getCanvas();
  254. REPORTER_ASSERT(reporter, canvas);
  255. SkPaint paint;
  256. paint.setColor(SK_ColorBLACK);
  257. paint.setBlendMode(SkBlendMode::kColorDodge);
  258. canvas->drawRect(SkRect::MakeWH(4, 4), paint);
  259. GrFlushInfo flushInfo;
  260. flushInfo.fFlags = kSyncCpu_GrFlushFlag;
  261. surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  262. protectedTestHelper->grContext()->deleteBackendTexture(
  263. surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
  264. }
  265. DEF_GPUTEST(VkProtectedContext_DrawRectangleWithFilter, reporter, options) {
  266. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  267. if (!protectedTestHelper->init(reporter)) {
  268. return;
  269. }
  270. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  271. auto surface = protectedTestHelper->createSkSurface(reporter);
  272. REPORTER_ASSERT(reporter, surface);
  273. SkCanvas* canvas = surface->getCanvas();
  274. REPORTER_ASSERT(reporter, canvas);
  275. SkPaint paint;
  276. paint.setColor(SK_ColorBLACK);
  277. paint.setStyle(SkPaint::kFill_Style);
  278. paint.setMaskFilter(SkMaskFilter::MakeBlur(
  279. SkBlurStyle::kOuter_SkBlurStyle, 1.1f));
  280. canvas->drawRect(SkRect::MakeWH(4, 4), paint);
  281. GrFlushInfo flushInfo;
  282. flushInfo.fFlags = kSyncCpu_GrFlushFlag;
  283. surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  284. protectedTestHelper->grContext()->deleteBackendTexture(
  285. surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
  286. }
  287. DEF_GPUTEST(VkProtectedContext_DrawThinPath, reporter, options) {
  288. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  289. if (!protectedTestHelper->init(reporter)) {
  290. return;
  291. }
  292. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  293. auto surface = protectedTestHelper->createSkSurface(reporter);
  294. REPORTER_ASSERT(reporter, surface);
  295. SkCanvas* canvas = surface->getCanvas();
  296. REPORTER_ASSERT(reporter, canvas);
  297. SkPaint paint;
  298. paint.setColor(SK_ColorBLACK);
  299. paint.setStyle(SkPaint::kStroke_Style);
  300. paint.setAntiAlias(true);
  301. paint.setStrokeWidth(.4f);
  302. canvas->drawPath(SkPath().moveTo(4, 4).lineTo(6, 6), paint);
  303. GrFlushInfo flushInfo;
  304. flushInfo.fFlags = kSyncCpu_GrFlushFlag;
  305. surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  306. protectedTestHelper->grContext()->deleteBackendTexture(
  307. surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
  308. }
  309. DEF_GPUTEST(VkProtectedContext_SaveLayer, reporter, options) {
  310. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  311. if (!protectedTestHelper->init(reporter)) {
  312. return;
  313. }
  314. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  315. auto surface = protectedTestHelper->createSkSurface(reporter);
  316. REPORTER_ASSERT(reporter, surface);
  317. SkCanvas* canvas = surface->getCanvas();
  318. REPORTER_ASSERT(reporter, canvas);
  319. canvas->saveLayer(nullptr, nullptr);
  320. SkPaint paint;
  321. paint.setColor(SK_ColorBLACK);
  322. canvas->drawRect(SkRect::MakeWH(4, 4), paint);
  323. canvas->restore();
  324. GrFlushInfo flushInfo;
  325. flushInfo.fFlags = kSyncCpu_GrFlushFlag;
  326. surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  327. protectedTestHelper->grContext()->deleteBackendTexture(
  328. surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
  329. }
  330. DEF_GPUTEST(VkProtectedContext_DrawProtectedImageOnProtectedSurface, reporter, options) {
  331. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  332. if (!protectedTestHelper->init(reporter)) {
  333. return;
  334. }
  335. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  336. // Create protected image.
  337. auto surface1 = protectedTestHelper->createSkSurface(reporter);
  338. REPORTER_ASSERT(reporter, surface1);
  339. auto image = surface1->makeImageSnapshot();
  340. REPORTER_ASSERT(reporter, image);
  341. // Create protected canvas.
  342. auto surface2 = protectedTestHelper->createSkSurface(reporter);
  343. REPORTER_ASSERT(reporter, surface2);
  344. SkCanvas* canvas = surface2->getCanvas();
  345. REPORTER_ASSERT(reporter, canvas);
  346. canvas->drawImage(image, 0, 0);
  347. GrFlushInfo flushInfo;
  348. flushInfo.fFlags = kSyncCpu_GrFlushFlag;
  349. surface1->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  350. protectedTestHelper->grContext()->deleteBackendTexture(
  351. surface1->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
  352. surface2->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfo);
  353. protectedTestHelper->grContext()->deleteBackendTexture(
  354. surface2->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess));
  355. }
  356. //////////////////////////////////////////////////////////////////////////////////////////////////
  357. // Test out DDLs using a protected Vulkan context
  358. void DDLMakeRenderTargetTestImpl(GrContext* context, skiatest::Reporter* reporter);
  359. DEF_GPUTEST(VkProtectedContext_DDLMakeRenderTargetTest, reporter, ctxInfo) {
  360. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  361. if (!protectedTestHelper->init(reporter)) {
  362. return;
  363. }
  364. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  365. DDLMakeRenderTargetTestImpl(protectedTestHelper->grContext(), reporter);
  366. }
  367. void DDLSurfaceCharacterizationTestImpl(GrContext* context, skiatest::Reporter* reporter);
  368. DEF_GPUTEST(VkProtectedContext_DDLSurfaceCharacterizationTest, reporter, ctxInfo) {
  369. auto protectedTestHelper = std::make_unique<VulkanTestHelper>(true);
  370. if (!protectedTestHelper->init(reporter)) {
  371. return;
  372. }
  373. REPORTER_ASSERT(reporter, protectedTestHelper->grContext() != nullptr);
  374. DDLSurfaceCharacterizationTestImpl(protectedTestHelper->grContext(), reporter);
  375. }
  376. #endif // SK_SUPPORT_GPU && defined(SK_VULKAN)