1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2018 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker // This is a GPU-backend specific test. It relies on static initializers to work
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
11*c8dee2aaSAndroid Build Coastguard Worker
12*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GANESH) && defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26 && defined(SK_VULKAN)
13*c8dee2aaSAndroid Build Coastguard Worker
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSemaphore.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/MutableTextureState.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkBackendSemaphore.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkDirectContext.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkTypes.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/vk/VulkanBackendContext.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/vk/VulkanExtensions.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/vk/VulkanMemoryAllocator.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/vk/VulkanMutableTextureState.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkAutoMalloc.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpu.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProxyProvider.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SkGr.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLDefines.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLUtil.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/GrContextFactory.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/vk/VkTestUtils.h"
44*c8dee2aaSAndroid Build Coastguard Worker
45*c8dee2aaSAndroid Build Coastguard Worker #include <android/hardware_buffer.h>
46*c8dee2aaSAndroid Build Coastguard Worker #include <cinttypes>
47*c8dee2aaSAndroid Build Coastguard Worker
48*c8dee2aaSAndroid Build Coastguard Worker #include <EGL/egl.h>
49*c8dee2aaSAndroid Build Coastguard Worker #include <EGL/eglext.h>
50*c8dee2aaSAndroid Build Coastguard Worker #include <GLES/gl.h>
51*c8dee2aaSAndroid Build Coastguard Worker #include <GLES/glext.h>
52*c8dee2aaSAndroid Build Coastguard Worker
53*c8dee2aaSAndroid Build Coastguard Worker static const int DEV_W = 16, DEV_H = 16;
54*c8dee2aaSAndroid Build Coastguard Worker
55*c8dee2aaSAndroid Build Coastguard Worker class BaseTestHelper {
56*c8dee2aaSAndroid Build Coastguard Worker public:
~BaseTestHelper()57*c8dee2aaSAndroid Build Coastguard Worker virtual ~BaseTestHelper() {}
58*c8dee2aaSAndroid Build Coastguard Worker
59*c8dee2aaSAndroid Build Coastguard Worker virtual bool init(skiatest::Reporter* reporter) = 0;
60*c8dee2aaSAndroid Build Coastguard Worker
61*c8dee2aaSAndroid Build Coastguard Worker virtual void cleanup() = 0;
62*c8dee2aaSAndroid Build Coastguard Worker // This is used to release a surface back to the external queue in vulkan
63*c8dee2aaSAndroid Build Coastguard Worker virtual void releaseSurfaceToExternal(SkSurface*) = 0;
64*c8dee2aaSAndroid Build Coastguard Worker virtual void releaseImage() = 0;
65*c8dee2aaSAndroid Build Coastguard Worker
66*c8dee2aaSAndroid Build Coastguard Worker virtual sk_sp<SkImage> importHardwareBufferForRead(skiatest::Reporter* reporter,
67*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) = 0;
68*c8dee2aaSAndroid Build Coastguard Worker virtual sk_sp<SkSurface> importHardwareBufferForWrite(skiatest::Reporter* reporter,
69*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) = 0;
70*c8dee2aaSAndroid Build Coastguard Worker
71*c8dee2aaSAndroid Build Coastguard Worker virtual void doClientSync() = 0;
72*c8dee2aaSAndroid Build Coastguard Worker virtual bool flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter, sk_sp<SkSurface>) = 0;
73*c8dee2aaSAndroid Build Coastguard Worker virtual bool importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle,
74*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface>) = 0;
75*c8dee2aaSAndroid Build Coastguard Worker
76*c8dee2aaSAndroid Build Coastguard Worker virtual void makeCurrent() = 0;
77*c8dee2aaSAndroid Build Coastguard Worker
78*c8dee2aaSAndroid Build Coastguard Worker virtual GrDirectContext* directContext() = 0;
79*c8dee2aaSAndroid Build Coastguard Worker
getFdHandle()80*c8dee2aaSAndroid Build Coastguard Worker int getFdHandle() { return fFdHandle; }
81*c8dee2aaSAndroid Build Coastguard Worker
82*c8dee2aaSAndroid Build Coastguard Worker protected:
BaseTestHelper()83*c8dee2aaSAndroid Build Coastguard Worker BaseTestHelper() {}
84*c8dee2aaSAndroid Build Coastguard Worker
85*c8dee2aaSAndroid Build Coastguard Worker int fFdHandle = 0;
86*c8dee2aaSAndroid Build Coastguard Worker };
87*c8dee2aaSAndroid Build Coastguard Worker
88*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
89*c8dee2aaSAndroid Build Coastguard Worker class EGLTestHelper : public BaseTestHelper {
90*c8dee2aaSAndroid Build Coastguard Worker public:
EGLTestHelper(const GrContextOptions & options)91*c8dee2aaSAndroid Build Coastguard Worker EGLTestHelper(const GrContextOptions& options) : fFactory(options) {}
92*c8dee2aaSAndroid Build Coastguard Worker
~EGLTestHelper()93*c8dee2aaSAndroid Build Coastguard Worker ~EGLTestHelper() override {}
94*c8dee2aaSAndroid Build Coastguard Worker
releaseImage()95*c8dee2aaSAndroid Build Coastguard Worker void releaseImage() override {
96*c8dee2aaSAndroid Build Coastguard Worker this->makeCurrent();
97*c8dee2aaSAndroid Build Coastguard Worker if (!fGLCtx) {
98*c8dee2aaSAndroid Build Coastguard Worker return;
99*c8dee2aaSAndroid Build Coastguard Worker }
100*c8dee2aaSAndroid Build Coastguard Worker if (EGL_NO_IMAGE_KHR != fImage) {
101*c8dee2aaSAndroid Build Coastguard Worker fGLCtx->destroyEGLImage(fImage);
102*c8dee2aaSAndroid Build Coastguard Worker fImage = EGL_NO_IMAGE_KHR;
103*c8dee2aaSAndroid Build Coastguard Worker }
104*c8dee2aaSAndroid Build Coastguard Worker if (fTexID) {
105*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL(fGLCtx->gl(), DeleteTextures(1, &fTexID));
106*c8dee2aaSAndroid Build Coastguard Worker fTexID = 0;
107*c8dee2aaSAndroid Build Coastguard Worker }
108*c8dee2aaSAndroid Build Coastguard Worker }
109*c8dee2aaSAndroid Build Coastguard Worker
releaseSurfaceToExternal(SkSurface *)110*c8dee2aaSAndroid Build Coastguard Worker void releaseSurfaceToExternal(SkSurface*) override {}
111*c8dee2aaSAndroid Build Coastguard Worker
cleanup()112*c8dee2aaSAndroid Build Coastguard Worker void cleanup() override {
113*c8dee2aaSAndroid Build Coastguard Worker this->releaseImage();
114*c8dee2aaSAndroid Build Coastguard Worker }
115*c8dee2aaSAndroid Build Coastguard Worker
116*c8dee2aaSAndroid Build Coastguard Worker bool init(skiatest::Reporter* reporter) override;
117*c8dee2aaSAndroid Build Coastguard Worker
118*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> importHardwareBufferForRead(skiatest::Reporter* reporter,
119*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) override;
120*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> importHardwareBufferForWrite(skiatest::Reporter* reporter,
121*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) override;
122*c8dee2aaSAndroid Build Coastguard Worker
123*c8dee2aaSAndroid Build Coastguard Worker void doClientSync() override;
124*c8dee2aaSAndroid Build Coastguard Worker bool flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter, sk_sp<SkSurface>) override;
125*c8dee2aaSAndroid Build Coastguard Worker bool importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle,
126*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface>) override;
127*c8dee2aaSAndroid Build Coastguard Worker
makeCurrent()128*c8dee2aaSAndroid Build Coastguard Worker void makeCurrent() override { fGLCtx->makeCurrent(); }
129*c8dee2aaSAndroid Build Coastguard Worker
directContext()130*c8dee2aaSAndroid Build Coastguard Worker GrDirectContext* directContext() override { return fDirectContext; }
131*c8dee2aaSAndroid Build Coastguard Worker
132*c8dee2aaSAndroid Build Coastguard Worker private:
133*c8dee2aaSAndroid Build Coastguard Worker bool importHardwareBuffer(skiatest::Reporter* reporter, AHardwareBuffer* buffer);
134*c8dee2aaSAndroid Build Coastguard Worker
135*c8dee2aaSAndroid Build Coastguard Worker typedef EGLClientBuffer (*EGLGetNativeClientBufferANDROIDProc)(const struct AHardwareBuffer*);
136*c8dee2aaSAndroid Build Coastguard Worker typedef EGLImageKHR (*EGLCreateImageKHRProc)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer,
137*c8dee2aaSAndroid Build Coastguard Worker const EGLint*);
138*c8dee2aaSAndroid Build Coastguard Worker typedef void (*EGLImageTargetTexture2DOESProc)(EGLenum, void*);
139*c8dee2aaSAndroid Build Coastguard Worker EGLGetNativeClientBufferANDROIDProc fEGLGetNativeClientBufferANDROID;
140*c8dee2aaSAndroid Build Coastguard Worker EGLCreateImageKHRProc fEGLCreateImageKHR;
141*c8dee2aaSAndroid Build Coastguard Worker EGLImageTargetTexture2DOESProc fEGLImageTargetTexture2DOES;
142*c8dee2aaSAndroid Build Coastguard Worker
143*c8dee2aaSAndroid Build Coastguard Worker PFNEGLCREATESYNCKHRPROC fEGLCreateSyncKHR;
144*c8dee2aaSAndroid Build Coastguard Worker PFNEGLWAITSYNCKHRPROC fEGLWaitSyncKHR;
145*c8dee2aaSAndroid Build Coastguard Worker PFNEGLGETSYNCATTRIBKHRPROC fEGLGetSyncAttribKHR;
146*c8dee2aaSAndroid Build Coastguard Worker PFNEGLDUPNATIVEFENCEFDANDROIDPROC fEGLDupNativeFenceFDANDROID;
147*c8dee2aaSAndroid Build Coastguard Worker PFNEGLDESTROYSYNCKHRPROC fEGLDestroySyncKHR;
148*c8dee2aaSAndroid Build Coastguard Worker
149*c8dee2aaSAndroid Build Coastguard Worker EGLImageKHR fImage = EGL_NO_IMAGE_KHR;
150*c8dee2aaSAndroid Build Coastguard Worker GrGLuint fTexID = 0;
151*c8dee2aaSAndroid Build Coastguard Worker
152*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::GrContextFactory fFactory;
153*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::ContextInfo fGLESContextInfo;
154*c8dee2aaSAndroid Build Coastguard Worker
155*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::GLTestContext* fGLCtx = nullptr;
156*c8dee2aaSAndroid Build Coastguard Worker GrDirectContext* fDirectContext = nullptr;
157*c8dee2aaSAndroid Build Coastguard Worker };
158*c8dee2aaSAndroid Build Coastguard Worker
init(skiatest::Reporter * reporter)159*c8dee2aaSAndroid Build Coastguard Worker bool EGLTestHelper::init(skiatest::Reporter* reporter) {
160*c8dee2aaSAndroid Build Coastguard Worker fGLESContextInfo = fFactory.getContextInfo(skgpu::ContextType::kGLES);
161*c8dee2aaSAndroid Build Coastguard Worker fDirectContext = fGLESContextInfo.directContext();
162*c8dee2aaSAndroid Build Coastguard Worker fGLCtx = fGLESContextInfo.glContext();
163*c8dee2aaSAndroid Build Coastguard Worker if (!fDirectContext || !fGLCtx) {
164*c8dee2aaSAndroid Build Coastguard Worker return false;
165*c8dee2aaSAndroid Build Coastguard Worker }
166*c8dee2aaSAndroid Build Coastguard Worker
167*c8dee2aaSAndroid Build Coastguard Worker if (kGLES_GrGLStandard != fGLCtx->gl()->fStandard) {
168*c8dee2aaSAndroid Build Coastguard Worker return false;
169*c8dee2aaSAndroid Build Coastguard Worker }
170*c8dee2aaSAndroid Build Coastguard Worker
171*c8dee2aaSAndroid Build Coastguard Worker // Confirm we have egl and the needed extensions
172*c8dee2aaSAndroid Build Coastguard Worker if (!fGLCtx->gl()->hasExtension("EGL_KHR_image") ||
173*c8dee2aaSAndroid Build Coastguard Worker !fGLCtx->gl()->hasExtension("EGL_ANDROID_get_native_client_buffer") ||
174*c8dee2aaSAndroid Build Coastguard Worker !fGLCtx->gl()->hasExtension("GL_OES_EGL_image_external") ||
175*c8dee2aaSAndroid Build Coastguard Worker !fGLCtx->gl()->hasExtension("GL_OES_EGL_image") ||
176*c8dee2aaSAndroid Build Coastguard Worker !fGLCtx->gl()->hasExtension("EGL_KHR_fence_sync") ||
177*c8dee2aaSAndroid Build Coastguard Worker !fGLCtx->gl()->hasExtension("EGL_ANDROID_native_fence_sync")) {
178*c8dee2aaSAndroid Build Coastguard Worker return false;
179*c8dee2aaSAndroid Build Coastguard Worker }
180*c8dee2aaSAndroid Build Coastguard Worker
181*c8dee2aaSAndroid Build Coastguard Worker fEGLGetNativeClientBufferANDROID =
182*c8dee2aaSAndroid Build Coastguard Worker (EGLGetNativeClientBufferANDROIDProc) eglGetProcAddress("eglGetNativeClientBufferANDROID");
183*c8dee2aaSAndroid Build Coastguard Worker if (!fEGLGetNativeClientBufferANDROID) {
184*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to get the eglGetNativeClientBufferAndroid proc");
185*c8dee2aaSAndroid Build Coastguard Worker return false;
186*c8dee2aaSAndroid Build Coastguard Worker }
187*c8dee2aaSAndroid Build Coastguard Worker
188*c8dee2aaSAndroid Build Coastguard Worker fEGLCreateImageKHR = (EGLCreateImageKHRProc) eglGetProcAddress("eglCreateImageKHR");
189*c8dee2aaSAndroid Build Coastguard Worker if (!fEGLCreateImageKHR) {
190*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to get the proc eglCreateImageKHR");
191*c8dee2aaSAndroid Build Coastguard Worker return false;
192*c8dee2aaSAndroid Build Coastguard Worker }
193*c8dee2aaSAndroid Build Coastguard Worker
194*c8dee2aaSAndroid Build Coastguard Worker fEGLImageTargetTexture2DOES =
195*c8dee2aaSAndroid Build Coastguard Worker (EGLImageTargetTexture2DOESProc) eglGetProcAddress("glEGLImageTargetTexture2DOES");
196*c8dee2aaSAndroid Build Coastguard Worker if (!fEGLImageTargetTexture2DOES) {
197*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to get the proc EGLImageTargetTexture2DOES");
198*c8dee2aaSAndroid Build Coastguard Worker return false;
199*c8dee2aaSAndroid Build Coastguard Worker }
200*c8dee2aaSAndroid Build Coastguard Worker
201*c8dee2aaSAndroid Build Coastguard Worker fEGLCreateSyncKHR = (PFNEGLCREATESYNCKHRPROC) eglGetProcAddress("eglCreateSyncKHR");
202*c8dee2aaSAndroid Build Coastguard Worker if (!fEGLCreateSyncKHR) {
203*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to get the proc eglCreateSyncKHR");
204*c8dee2aaSAndroid Build Coastguard Worker return false;
205*c8dee2aaSAndroid Build Coastguard Worker
206*c8dee2aaSAndroid Build Coastguard Worker }
207*c8dee2aaSAndroid Build Coastguard Worker fEGLWaitSyncKHR = (PFNEGLWAITSYNCKHRPROC) eglGetProcAddress("eglWaitSyncKHR");
208*c8dee2aaSAndroid Build Coastguard Worker if (!fEGLWaitSyncKHR) {
209*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to get the proc eglWaitSyncKHR");
210*c8dee2aaSAndroid Build Coastguard Worker return false;
211*c8dee2aaSAndroid Build Coastguard Worker
212*c8dee2aaSAndroid Build Coastguard Worker }
213*c8dee2aaSAndroid Build Coastguard Worker fEGLGetSyncAttribKHR = (PFNEGLGETSYNCATTRIBKHRPROC) eglGetProcAddress("eglGetSyncAttribKHR");
214*c8dee2aaSAndroid Build Coastguard Worker if (!fEGLGetSyncAttribKHR) {
215*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to get the proc eglGetSyncAttribKHR");
216*c8dee2aaSAndroid Build Coastguard Worker return false;
217*c8dee2aaSAndroid Build Coastguard Worker
218*c8dee2aaSAndroid Build Coastguard Worker }
219*c8dee2aaSAndroid Build Coastguard Worker fEGLDupNativeFenceFDANDROID =
220*c8dee2aaSAndroid Build Coastguard Worker (PFNEGLDUPNATIVEFENCEFDANDROIDPROC) eglGetProcAddress("eglDupNativeFenceFDANDROID");
221*c8dee2aaSAndroid Build Coastguard Worker if (!fEGLDupNativeFenceFDANDROID) {
222*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to get the proc eglDupNativeFenceFDANDROID");
223*c8dee2aaSAndroid Build Coastguard Worker return false;
224*c8dee2aaSAndroid Build Coastguard Worker
225*c8dee2aaSAndroid Build Coastguard Worker }
226*c8dee2aaSAndroid Build Coastguard Worker fEGLDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC) eglGetProcAddress("eglDestroySyncKHR");
227*c8dee2aaSAndroid Build Coastguard Worker if (!fEGLDestroySyncKHR) {
228*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to get the proc eglDestroySyncKHR");
229*c8dee2aaSAndroid Build Coastguard Worker return false;
230*c8dee2aaSAndroid Build Coastguard Worker
231*c8dee2aaSAndroid Build Coastguard Worker }
232*c8dee2aaSAndroid Build Coastguard Worker
233*c8dee2aaSAndroid Build Coastguard Worker return true;
234*c8dee2aaSAndroid Build Coastguard Worker }
235*c8dee2aaSAndroid Build Coastguard Worker
importHardwareBuffer(skiatest::Reporter * reporter,AHardwareBuffer * buffer)236*c8dee2aaSAndroid Build Coastguard Worker bool EGLTestHelper::importHardwareBuffer(skiatest::Reporter* reporter, AHardwareBuffer* buffer) {
237*c8dee2aaSAndroid Build Coastguard Worker while (fGLCtx->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {}
238*c8dee2aaSAndroid Build Coastguard Worker
239*c8dee2aaSAndroid Build Coastguard Worker EGLClientBuffer eglClientBuffer = fEGLGetNativeClientBufferANDROID(buffer);
240*c8dee2aaSAndroid Build Coastguard Worker EGLint eglAttribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
241*c8dee2aaSAndroid Build Coastguard Worker EGL_NONE };
242*c8dee2aaSAndroid Build Coastguard Worker EGLDisplay eglDisplay = eglGetCurrentDisplay();
243*c8dee2aaSAndroid Build Coastguard Worker fImage = fEGLCreateImageKHR(eglDisplay, EGL_NO_CONTEXT,
244*c8dee2aaSAndroid Build Coastguard Worker EGL_NATIVE_BUFFER_ANDROID,
245*c8dee2aaSAndroid Build Coastguard Worker eglClientBuffer, eglAttribs);
246*c8dee2aaSAndroid Build Coastguard Worker if (EGL_NO_IMAGE_KHR == fImage) {
247*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Could not create EGL image, err = (%#x)\n", (int) eglGetError() );
248*c8dee2aaSAndroid Build Coastguard Worker return false;
249*c8dee2aaSAndroid Build Coastguard Worker }
250*c8dee2aaSAndroid Build Coastguard Worker
251*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL(fGLCtx->gl(), GenTextures(1, &fTexID));
252*c8dee2aaSAndroid Build Coastguard Worker if (!fTexID) {
253*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to create GL Texture");
254*c8dee2aaSAndroid Build Coastguard Worker return false;
255*c8dee2aaSAndroid Build Coastguard Worker }
256*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL_NOERRCHECK(fGLCtx->gl(), BindTexture(GR_GL_TEXTURE_2D, fTexID));
257*c8dee2aaSAndroid Build Coastguard Worker if (fGLCtx->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {
258*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to bind GL Texture");
259*c8dee2aaSAndroid Build Coastguard Worker return false;
260*c8dee2aaSAndroid Build Coastguard Worker }
261*c8dee2aaSAndroid Build Coastguard Worker
262*c8dee2aaSAndroid Build Coastguard Worker fEGLImageTargetTexture2DOES(GL_TEXTURE_2D, fImage);
263*c8dee2aaSAndroid Build Coastguard Worker if (GrGLenum error = fGLCtx->gl()->fFunctions.fGetError(); error != GR_GL_NO_ERROR) {
264*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "EGLImageTargetTexture2DOES failed (%#x)", (int) error);
265*c8dee2aaSAndroid Build Coastguard Worker return false;
266*c8dee2aaSAndroid Build Coastguard Worker }
267*c8dee2aaSAndroid Build Coastguard Worker
268*c8dee2aaSAndroid Build Coastguard Worker fDirectContext->resetContext(kTextureBinding_GrGLBackendState);
269*c8dee2aaSAndroid Build Coastguard Worker return true;
270*c8dee2aaSAndroid Build Coastguard Worker }
271*c8dee2aaSAndroid Build Coastguard Worker
importHardwareBufferForRead(skiatest::Reporter * reporter,AHardwareBuffer * buffer)272*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> EGLTestHelper::importHardwareBufferForRead(skiatest::Reporter* reporter,
273*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) {
274*c8dee2aaSAndroid Build Coastguard Worker if (!this->importHardwareBuffer(reporter, buffer)) {
275*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
276*c8dee2aaSAndroid Build Coastguard Worker }
277*c8dee2aaSAndroid Build Coastguard Worker GrGLTextureInfo textureInfo;
278*c8dee2aaSAndroid Build Coastguard Worker textureInfo.fTarget = GR_GL_TEXTURE_2D;
279*c8dee2aaSAndroid Build Coastguard Worker textureInfo.fID = fTexID;
280*c8dee2aaSAndroid Build Coastguard Worker textureInfo.fFormat = GR_GL_RGBA8;
281*c8dee2aaSAndroid Build Coastguard Worker
282*c8dee2aaSAndroid Build Coastguard Worker auto backendTex = GrBackendTextures::MakeGL(DEV_W, DEV_H, skgpu::Mipmapped::kNo, textureInfo);
283*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, backendTex.isValid());
284*c8dee2aaSAndroid Build Coastguard Worker
285*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> image = SkImages::BorrowTextureFrom(fDirectContext,
286*c8dee2aaSAndroid Build Coastguard Worker backendTex,
287*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
288*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
289*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType,
290*c8dee2aaSAndroid Build Coastguard Worker nullptr);
291*c8dee2aaSAndroid Build Coastguard Worker
292*c8dee2aaSAndroid Build Coastguard Worker if (!image) {
293*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to make wrapped GL SkImage");
294*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
295*c8dee2aaSAndroid Build Coastguard Worker }
296*c8dee2aaSAndroid Build Coastguard Worker
297*c8dee2aaSAndroid Build Coastguard Worker return image;
298*c8dee2aaSAndroid Build Coastguard Worker }
299*c8dee2aaSAndroid Build Coastguard Worker
importHardwareBufferForWrite(skiatest::Reporter * reporter,AHardwareBuffer * buffer)300*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> EGLTestHelper::importHardwareBufferForWrite(skiatest::Reporter* reporter,
301*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) {
302*c8dee2aaSAndroid Build Coastguard Worker if (!this->importHardwareBuffer(reporter, buffer)) {
303*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
304*c8dee2aaSAndroid Build Coastguard Worker }
305*c8dee2aaSAndroid Build Coastguard Worker GrGLTextureInfo textureInfo;
306*c8dee2aaSAndroid Build Coastguard Worker textureInfo.fTarget = GR_GL_TEXTURE_2D;
307*c8dee2aaSAndroid Build Coastguard Worker textureInfo.fID = fTexID;
308*c8dee2aaSAndroid Build Coastguard Worker textureInfo.fFormat = GR_GL_RGBA8;
309*c8dee2aaSAndroid Build Coastguard Worker
310*c8dee2aaSAndroid Build Coastguard Worker auto backendTex = GrBackendTextures::MakeGL(DEV_W, DEV_H, skgpu::Mipmapped::kNo, textureInfo);
311*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, backendTex.isValid());
312*c8dee2aaSAndroid Build Coastguard Worker
313*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface = SkSurfaces::WrapBackendTexture(fDirectContext,
314*c8dee2aaSAndroid Build Coastguard Worker backendTex,
315*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
316*c8dee2aaSAndroid Build Coastguard Worker 0,
317*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
318*c8dee2aaSAndroid Build Coastguard Worker nullptr,
319*c8dee2aaSAndroid Build Coastguard Worker nullptr);
320*c8dee2aaSAndroid Build Coastguard Worker
321*c8dee2aaSAndroid Build Coastguard Worker if (!surface) {
322*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to make wrapped GL SkSurface");
323*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
324*c8dee2aaSAndroid Build Coastguard Worker }
325*c8dee2aaSAndroid Build Coastguard Worker
326*c8dee2aaSAndroid Build Coastguard Worker return surface;
327*c8dee2aaSAndroid Build Coastguard Worker }
328*c8dee2aaSAndroid Build Coastguard Worker
flushSurfaceAndSignalSemaphore(skiatest::Reporter * reporter,sk_sp<SkSurface> surface)329*c8dee2aaSAndroid Build Coastguard Worker bool EGLTestHelper::flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter,
330*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface) {
331*c8dee2aaSAndroid Build Coastguard Worker skgpu::ganesh::FlushAndSubmit(surface);
332*c8dee2aaSAndroid Build Coastguard Worker
333*c8dee2aaSAndroid Build Coastguard Worker EGLDisplay eglDisplay = eglGetCurrentDisplay();
334*c8dee2aaSAndroid Build Coastguard Worker EGLSyncKHR eglsync = fEGLCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
335*c8dee2aaSAndroid Build Coastguard Worker if (EGL_NO_SYNC_KHR == eglsync) {
336*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to create EGLSync for EGL_SYNC_NATIVE_FENCE_ANDROID\n");
337*c8dee2aaSAndroid Build Coastguard Worker return false;
338*c8dee2aaSAndroid Build Coastguard Worker }
339*c8dee2aaSAndroid Build Coastguard Worker
340*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL(fGLCtx->gl(), Flush());
341*c8dee2aaSAndroid Build Coastguard Worker fFdHandle = fEGLDupNativeFenceFDANDROID(eglDisplay, eglsync);
342*c8dee2aaSAndroid Build Coastguard Worker
343*c8dee2aaSAndroid Build Coastguard Worker EGLint result = fEGLDestroySyncKHR(eglDisplay, eglsync);
344*c8dee2aaSAndroid Build Coastguard Worker if (EGL_TRUE != result) {
345*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to delete EGLSync, error: %d\n", result);
346*c8dee2aaSAndroid Build Coastguard Worker return false;
347*c8dee2aaSAndroid Build Coastguard Worker }
348*c8dee2aaSAndroid Build Coastguard Worker
349*c8dee2aaSAndroid Build Coastguard Worker return true;
350*c8dee2aaSAndroid Build Coastguard Worker }
351*c8dee2aaSAndroid Build Coastguard Worker
importAndWaitOnSemaphore(skiatest::Reporter * reporter,int fdHandle,sk_sp<SkSurface> surface)352*c8dee2aaSAndroid Build Coastguard Worker bool EGLTestHelper::importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle,
353*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface) {
354*c8dee2aaSAndroid Build Coastguard Worker EGLDisplay eglDisplay = eglGetCurrentDisplay();
355*c8dee2aaSAndroid Build Coastguard Worker EGLint attr[] = {
356*c8dee2aaSAndroid Build Coastguard Worker EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fdHandle,
357*c8dee2aaSAndroid Build Coastguard Worker EGL_NONE
358*c8dee2aaSAndroid Build Coastguard Worker };
359*c8dee2aaSAndroid Build Coastguard Worker EGLSyncKHR eglsync = fEGLCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attr);
360*c8dee2aaSAndroid Build Coastguard Worker if (EGL_NO_SYNC_KHR == eglsync) {
361*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter,
362*c8dee2aaSAndroid Build Coastguard Worker "Failed to create EGLSync when importing EGL_SYNC_NATIVE_FENCE_FD_ANDROID\n");
363*c8dee2aaSAndroid Build Coastguard Worker return false;
364*c8dee2aaSAndroid Build Coastguard Worker }
365*c8dee2aaSAndroid Build Coastguard Worker EGLint result = fEGLWaitSyncKHR(eglDisplay, eglsync, 0);
366*c8dee2aaSAndroid Build Coastguard Worker if (EGL_TRUE != result) {
367*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed called to eglWaitSyncKHR, error: %d\n", result);
368*c8dee2aaSAndroid Build Coastguard Worker // Don't return false yet, try to delete the sync first
369*c8dee2aaSAndroid Build Coastguard Worker }
370*c8dee2aaSAndroid Build Coastguard Worker result = fEGLDestroySyncKHR(eglDisplay, eglsync);
371*c8dee2aaSAndroid Build Coastguard Worker if (EGL_TRUE != result) {
372*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to delete EGLSync, error: %d\n", result);
373*c8dee2aaSAndroid Build Coastguard Worker return false;
374*c8dee2aaSAndroid Build Coastguard Worker }
375*c8dee2aaSAndroid Build Coastguard Worker return true;
376*c8dee2aaSAndroid Build Coastguard Worker }
377*c8dee2aaSAndroid Build Coastguard Worker
doClientSync()378*c8dee2aaSAndroid Build Coastguard Worker void EGLTestHelper::doClientSync() {
379*c8dee2aaSAndroid Build Coastguard Worker this->directContext()->flush();
380*c8dee2aaSAndroid Build Coastguard Worker this->directContext()->submit(GrSyncCpu::kYes);
381*c8dee2aaSAndroid Build Coastguard Worker }
382*c8dee2aaSAndroid Build Coastguard Worker #endif // SK_GL
383*c8dee2aaSAndroid Build Coastguard Worker
384*c8dee2aaSAndroid Build Coastguard Worker #define DECLARE_VK_PROC(name) PFN_vk##name fVk##name
385*c8dee2aaSAndroid Build Coastguard Worker
386*c8dee2aaSAndroid Build Coastguard Worker #define ACQUIRE_INST_VK_PROC(name) \
387*c8dee2aaSAndroid Build Coastguard Worker do { \
388*c8dee2aaSAndroid Build Coastguard Worker fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, fBackendContext.fInstance,\
389*c8dee2aaSAndroid Build Coastguard Worker VK_NULL_HANDLE)); \
390*c8dee2aaSAndroid Build Coastguard Worker if (fVk##name == nullptr) { \
391*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name); \
392*c8dee2aaSAndroid Build Coastguard Worker return false; \
393*c8dee2aaSAndroid Build Coastguard Worker } \
394*c8dee2aaSAndroid Build Coastguard Worker } while(false)
395*c8dee2aaSAndroid Build Coastguard Worker
396*c8dee2aaSAndroid Build Coastguard Worker #define ACQUIRE_DEVICE_VK_PROC(name) \
397*c8dee2aaSAndroid Build Coastguard Worker do { \
398*c8dee2aaSAndroid Build Coastguard Worker fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, VK_NULL_HANDLE, fDevice)); \
399*c8dee2aaSAndroid Build Coastguard Worker if (fVk##name == nullptr) { \
400*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Function ptr for vk%s could not be acquired\n", #name); \
401*c8dee2aaSAndroid Build Coastguard Worker return false; \
402*c8dee2aaSAndroid Build Coastguard Worker } \
403*c8dee2aaSAndroid Build Coastguard Worker } while(false)
404*c8dee2aaSAndroid Build Coastguard Worker
405*c8dee2aaSAndroid Build Coastguard Worker class VulkanTestHelper : public BaseTestHelper {
406*c8dee2aaSAndroid Build Coastguard Worker public:
VulkanTestHelper()407*c8dee2aaSAndroid Build Coastguard Worker VulkanTestHelper() {}
408*c8dee2aaSAndroid Build Coastguard Worker
~VulkanTestHelper()409*c8dee2aaSAndroid Build Coastguard Worker ~VulkanTestHelper() override {}
410*c8dee2aaSAndroid Build Coastguard Worker
releaseImage()411*c8dee2aaSAndroid Build Coastguard Worker void releaseImage() override {
412*c8dee2aaSAndroid Build Coastguard Worker if (VK_NULL_HANDLE == fDevice) {
413*c8dee2aaSAndroid Build Coastguard Worker return;
414*c8dee2aaSAndroid Build Coastguard Worker }
415*c8dee2aaSAndroid Build Coastguard Worker if (fImage != VK_NULL_HANDLE) {
416*c8dee2aaSAndroid Build Coastguard Worker fVkDestroyImage(fDevice, fImage, nullptr);
417*c8dee2aaSAndroid Build Coastguard Worker fImage = VK_NULL_HANDLE;
418*c8dee2aaSAndroid Build Coastguard Worker }
419*c8dee2aaSAndroid Build Coastguard Worker
420*c8dee2aaSAndroid Build Coastguard Worker if (fMemory != VK_NULL_HANDLE) {
421*c8dee2aaSAndroid Build Coastguard Worker fVkFreeMemory(fDevice, fMemory, nullptr);
422*c8dee2aaSAndroid Build Coastguard Worker fMemory = VK_NULL_HANDLE;
423*c8dee2aaSAndroid Build Coastguard Worker }
424*c8dee2aaSAndroid Build Coastguard Worker }
425*c8dee2aaSAndroid Build Coastguard Worker
releaseSurfaceToExternal(SkSurface * surface)426*c8dee2aaSAndroid Build Coastguard Worker void releaseSurfaceToExternal(SkSurface* surface) override {
427*c8dee2aaSAndroid Build Coastguard Worker skgpu::MutableTextureState newState = skgpu::MutableTextureStates::MakeVulkan(
428*c8dee2aaSAndroid Build Coastguard Worker VK_IMAGE_LAYOUT_UNDEFINED, VK_QUEUE_FAMILY_EXTERNAL);
429*c8dee2aaSAndroid Build Coastguard Worker fDirectContext->flush(surface, {}, &newState);
430*c8dee2aaSAndroid Build Coastguard Worker }
431*c8dee2aaSAndroid Build Coastguard Worker
cleanup()432*c8dee2aaSAndroid Build Coastguard Worker void cleanup() override {
433*c8dee2aaSAndroid Build Coastguard Worker fDirectContext.reset();
434*c8dee2aaSAndroid Build Coastguard Worker this->releaseImage();
435*c8dee2aaSAndroid Build Coastguard Worker if (fSignalSemaphore != VK_NULL_HANDLE) {
436*c8dee2aaSAndroid Build Coastguard Worker fVkDestroySemaphore(fDevice, fSignalSemaphore, nullptr);
437*c8dee2aaSAndroid Build Coastguard Worker fSignalSemaphore = VK_NULL_HANDLE;
438*c8dee2aaSAndroid Build Coastguard Worker }
439*c8dee2aaSAndroid Build Coastguard Worker fBackendContext.fMemoryAllocator.reset();
440*c8dee2aaSAndroid Build Coastguard Worker if (fDevice != VK_NULL_HANDLE) {
441*c8dee2aaSAndroid Build Coastguard Worker fVkDeviceWaitIdle(fDevice);
442*c8dee2aaSAndroid Build Coastguard Worker fVkDestroyDevice(fDevice, nullptr);
443*c8dee2aaSAndroid Build Coastguard Worker fDevice = VK_NULL_HANDLE;
444*c8dee2aaSAndroid Build Coastguard Worker }
445*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_ENABLE_VK_LAYERS
446*c8dee2aaSAndroid Build Coastguard Worker if (fDebugCallback != VK_NULL_HANDLE) {
447*c8dee2aaSAndroid Build Coastguard Worker fDestroyDebugCallback(fBackendContext.fInstance, fDebugCallback, nullptr);
448*c8dee2aaSAndroid Build Coastguard Worker }
449*c8dee2aaSAndroid Build Coastguard Worker #endif
450*c8dee2aaSAndroid Build Coastguard Worker if (fBackendContext.fInstance != VK_NULL_HANDLE) {
451*c8dee2aaSAndroid Build Coastguard Worker fVkDestroyInstance(fBackendContext.fInstance, nullptr);
452*c8dee2aaSAndroid Build Coastguard Worker fBackendContext.fInstance = VK_NULL_HANDLE;
453*c8dee2aaSAndroid Build Coastguard Worker }
454*c8dee2aaSAndroid Build Coastguard Worker
455*c8dee2aaSAndroid Build Coastguard Worker delete fExtensions;
456*c8dee2aaSAndroid Build Coastguard Worker
457*c8dee2aaSAndroid Build Coastguard Worker sk_gpu_test::FreeVulkanFeaturesStructs(fFeatures);
458*c8dee2aaSAndroid Build Coastguard Worker delete fFeatures;
459*c8dee2aaSAndroid Build Coastguard Worker }
460*c8dee2aaSAndroid Build Coastguard Worker
461*c8dee2aaSAndroid Build Coastguard Worker bool init(skiatest::Reporter* reporter) override;
462*c8dee2aaSAndroid Build Coastguard Worker
doClientSync()463*c8dee2aaSAndroid Build Coastguard Worker void doClientSync() override {
464*c8dee2aaSAndroid Build Coastguard Worker if (!fDirectContext) {
465*c8dee2aaSAndroid Build Coastguard Worker return;
466*c8dee2aaSAndroid Build Coastguard Worker }
467*c8dee2aaSAndroid Build Coastguard Worker
468*c8dee2aaSAndroid Build Coastguard Worker fDirectContext->submit(GrSyncCpu::kYes);
469*c8dee2aaSAndroid Build Coastguard Worker }
470*c8dee2aaSAndroid Build Coastguard Worker
471*c8dee2aaSAndroid Build Coastguard Worker bool flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter, sk_sp<SkSurface>) override;
472*c8dee2aaSAndroid Build Coastguard Worker bool importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle,
473*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface>) override;
474*c8dee2aaSAndroid Build Coastguard Worker
475*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> importHardwareBufferForRead(skiatest::Reporter* reporter,
476*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) override;
477*c8dee2aaSAndroid Build Coastguard Worker
478*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> importHardwareBufferForWrite(skiatest::Reporter* reporter,
479*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) override;
480*c8dee2aaSAndroid Build Coastguard Worker
makeCurrent()481*c8dee2aaSAndroid Build Coastguard Worker void makeCurrent() override {}
482*c8dee2aaSAndroid Build Coastguard Worker
directContext()483*c8dee2aaSAndroid Build Coastguard Worker GrDirectContext* directContext() override { return fDirectContext.get(); }
484*c8dee2aaSAndroid Build Coastguard Worker
485*c8dee2aaSAndroid Build Coastguard Worker private:
486*c8dee2aaSAndroid Build Coastguard Worker bool checkOptimalHardwareBuffer(skiatest::Reporter* reporter);
487*c8dee2aaSAndroid Build Coastguard Worker
488*c8dee2aaSAndroid Build Coastguard Worker bool importHardwareBuffer(skiatest::Reporter* reporter, AHardwareBuffer* buffer, bool forWrite,
489*c8dee2aaSAndroid Build Coastguard Worker GrVkImageInfo* outImageInfo);
490*c8dee2aaSAndroid Build Coastguard Worker
491*c8dee2aaSAndroid Build Coastguard Worker bool setupSemaphoreForSignaling(skiatest::Reporter* reporter, GrBackendSemaphore*);
492*c8dee2aaSAndroid Build Coastguard Worker bool exportSemaphore(skiatest::Reporter* reporter, const GrBackendSemaphore&);
493*c8dee2aaSAndroid Build Coastguard Worker
494*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(DestroyInstance);
495*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(DeviceWaitIdle);
496*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(DestroyDevice);
497*c8dee2aaSAndroid Build Coastguard Worker
498*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(GetPhysicalDeviceExternalSemaphoreProperties);
499*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(GetPhysicalDeviceImageFormatProperties2);
500*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(GetPhysicalDeviceMemoryProperties2);
501*c8dee2aaSAndroid Build Coastguard Worker
502*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(GetAndroidHardwareBufferPropertiesANDROID);
503*c8dee2aaSAndroid Build Coastguard Worker
504*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(CreateImage);
505*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(GetImageMemoryRequirements2);
506*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(DestroyImage);
507*c8dee2aaSAndroid Build Coastguard Worker
508*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(AllocateMemory);
509*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(BindImageMemory2);
510*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(FreeMemory);
511*c8dee2aaSAndroid Build Coastguard Worker
512*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(CreateSemaphore);
513*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(GetSemaphoreFdKHR);
514*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(ImportSemaphoreFdKHR);
515*c8dee2aaSAndroid Build Coastguard Worker DECLARE_VK_PROC(DestroySemaphore);
516*c8dee2aaSAndroid Build Coastguard Worker
517*c8dee2aaSAndroid Build Coastguard Worker VkImage fImage = VK_NULL_HANDLE;
518*c8dee2aaSAndroid Build Coastguard Worker VkDeviceMemory fMemory = VK_NULL_HANDLE;
519*c8dee2aaSAndroid Build Coastguard Worker
520*c8dee2aaSAndroid Build Coastguard Worker skgpu::VulkanExtensions* fExtensions = nullptr;
521*c8dee2aaSAndroid Build Coastguard Worker VkPhysicalDeviceFeatures2* fFeatures = nullptr;
522*c8dee2aaSAndroid Build Coastguard Worker VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
523*c8dee2aaSAndroid Build Coastguard Worker PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugCallback = nullptr;
524*c8dee2aaSAndroid Build Coastguard Worker
525*c8dee2aaSAndroid Build Coastguard Worker // We hold on to the semaphore so we can delete once the GPU is done.
526*c8dee2aaSAndroid Build Coastguard Worker VkSemaphore fSignalSemaphore = VK_NULL_HANDLE;
527*c8dee2aaSAndroid Build Coastguard Worker
528*c8dee2aaSAndroid Build Coastguard Worker VkDevice fDevice = VK_NULL_HANDLE;
529*c8dee2aaSAndroid Build Coastguard Worker
530*c8dee2aaSAndroid Build Coastguard Worker skgpu::VulkanBackendContext fBackendContext;
531*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrDirectContext> fDirectContext;
532*c8dee2aaSAndroid Build Coastguard Worker };
533*c8dee2aaSAndroid Build Coastguard Worker
init(skiatest::Reporter * reporter)534*c8dee2aaSAndroid Build Coastguard Worker bool VulkanTestHelper::init(skiatest::Reporter* reporter) {
535*c8dee2aaSAndroid Build Coastguard Worker PFN_vkGetInstanceProcAddr instProc;
536*c8dee2aaSAndroid Build Coastguard Worker if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
537*c8dee2aaSAndroid Build Coastguard Worker return false;
538*c8dee2aaSAndroid Build Coastguard Worker }
539*c8dee2aaSAndroid Build Coastguard Worker
540*c8dee2aaSAndroid Build Coastguard Worker fExtensions = new skgpu::VulkanExtensions();
541*c8dee2aaSAndroid Build Coastguard Worker fFeatures = new VkPhysicalDeviceFeatures2;
542*c8dee2aaSAndroid Build Coastguard Worker memset(fFeatures, 0, sizeof(VkPhysicalDeviceFeatures2));
543*c8dee2aaSAndroid Build Coastguard Worker fFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
544*c8dee2aaSAndroid Build Coastguard Worker fFeatures->pNext = nullptr;
545*c8dee2aaSAndroid Build Coastguard Worker
546*c8dee2aaSAndroid Build Coastguard Worker fBackendContext.fInstance = VK_NULL_HANDLE;
547*c8dee2aaSAndroid Build Coastguard Worker fBackendContext.fDevice = VK_NULL_HANDLE;
548*c8dee2aaSAndroid Build Coastguard Worker
549*c8dee2aaSAndroid Build Coastguard Worker if (!sk_gpu_test::CreateVkBackendContext(instProc, &fBackendContext, fExtensions,
550*c8dee2aaSAndroid Build Coastguard Worker fFeatures, &fDebugCallback)) {
551*c8dee2aaSAndroid Build Coastguard Worker return false;
552*c8dee2aaSAndroid Build Coastguard Worker }
553*c8dee2aaSAndroid Build Coastguard Worker fDevice = fBackendContext.fDevice;
554*c8dee2aaSAndroid Build Coastguard Worker auto getProc = fBackendContext.fGetProc;
555*c8dee2aaSAndroid Build Coastguard Worker
556*c8dee2aaSAndroid Build Coastguard Worker if (fDebugCallback != VK_NULL_HANDLE) {
557*c8dee2aaSAndroid Build Coastguard Worker fDestroyDebugCallback = (PFN_vkDestroyDebugReportCallbackEXT) instProc(
558*c8dee2aaSAndroid Build Coastguard Worker fBackendContext.fInstance, "vkDestroyDebugReportCallbackEXT");
559*c8dee2aaSAndroid Build Coastguard Worker }
560*c8dee2aaSAndroid Build Coastguard Worker
561*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_INST_VK_PROC(DestroyInstance);
562*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_INST_VK_PROC(DeviceWaitIdle);
563*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_INST_VK_PROC(DestroyDevice);
564*c8dee2aaSAndroid Build Coastguard Worker
565*c8dee2aaSAndroid Build Coastguard Worker if (!fExtensions->hasExtension(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
566*c8dee2aaSAndroid Build Coastguard Worker 2)) {
567*c8dee2aaSAndroid Build Coastguard Worker return false;
568*c8dee2aaSAndroid Build Coastguard Worker }
569*c8dee2aaSAndroid Build Coastguard Worker if (!fExtensions->hasExtension(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, 1)) {
570*c8dee2aaSAndroid Build Coastguard Worker return false;
571*c8dee2aaSAndroid Build Coastguard Worker }
572*c8dee2aaSAndroid Build Coastguard Worker if (!fExtensions->hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)) {
573*c8dee2aaSAndroid Build Coastguard Worker return false;
574*c8dee2aaSAndroid Build Coastguard Worker }
575*c8dee2aaSAndroid Build Coastguard Worker if (!fExtensions->hasExtension(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, 1)) {
576*c8dee2aaSAndroid Build Coastguard Worker // return false;
577*c8dee2aaSAndroid Build Coastguard Worker }
578*c8dee2aaSAndroid Build Coastguard Worker
579*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_INST_VK_PROC(GetPhysicalDeviceMemoryProperties2);
580*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_INST_VK_PROC(GetPhysicalDeviceImageFormatProperties2);
581*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_INST_VK_PROC(GetPhysicalDeviceExternalSemaphoreProperties);
582*c8dee2aaSAndroid Build Coastguard Worker
583*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(GetAndroidHardwareBufferPropertiesANDROID);
584*c8dee2aaSAndroid Build Coastguard Worker
585*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(CreateImage);
586*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(GetImageMemoryRequirements2);
587*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(DestroyImage);
588*c8dee2aaSAndroid Build Coastguard Worker
589*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(AllocateMemory);
590*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(BindImageMemory2);
591*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(FreeMemory);
592*c8dee2aaSAndroid Build Coastguard Worker
593*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(CreateSemaphore);
594*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(GetSemaphoreFdKHR);
595*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(ImportSemaphoreFdKHR);
596*c8dee2aaSAndroid Build Coastguard Worker ACQUIRE_DEVICE_VK_PROC(DestroySemaphore);
597*c8dee2aaSAndroid Build Coastguard Worker
598*c8dee2aaSAndroid Build Coastguard Worker fDirectContext = GrDirectContexts::MakeVulkan(fBackendContext);
599*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, fDirectContext.get());
600*c8dee2aaSAndroid Build Coastguard Worker if (!fDirectContext) {
601*c8dee2aaSAndroid Build Coastguard Worker return false;
602*c8dee2aaSAndroid Build Coastguard Worker }
603*c8dee2aaSAndroid Build Coastguard Worker
604*c8dee2aaSAndroid Build Coastguard Worker return this->checkOptimalHardwareBuffer(reporter);
605*c8dee2aaSAndroid Build Coastguard Worker }
606*c8dee2aaSAndroid Build Coastguard Worker
checkOptimalHardwareBuffer(skiatest::Reporter * reporter)607*c8dee2aaSAndroid Build Coastguard Worker bool VulkanTestHelper::checkOptimalHardwareBuffer(skiatest::Reporter* reporter) {
608*c8dee2aaSAndroid Build Coastguard Worker VkResult err;
609*c8dee2aaSAndroid Build Coastguard Worker
610*c8dee2aaSAndroid Build Coastguard Worker VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo;
611*c8dee2aaSAndroid Build Coastguard Worker externalImageFormatInfo.sType =
612*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO;
613*c8dee2aaSAndroid Build Coastguard Worker externalImageFormatInfo.pNext = nullptr;
614*c8dee2aaSAndroid Build Coastguard Worker externalImageFormatInfo.handleType =
615*c8dee2aaSAndroid Build Coastguard Worker VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
616*c8dee2aaSAndroid Build Coastguard Worker //externalImageFormatInfo.handType = 0x80;
617*c8dee2aaSAndroid Build Coastguard Worker
618*c8dee2aaSAndroid Build Coastguard Worker // We will create the hardware buffer with gpu sampled so these usages should all be valid
619*c8dee2aaSAndroid Build Coastguard Worker VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT |
620*c8dee2aaSAndroid Build Coastguard Worker VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
621*c8dee2aaSAndroid Build Coastguard Worker VK_IMAGE_USAGE_TRANSFER_DST_BIT;
622*c8dee2aaSAndroid Build Coastguard Worker VkPhysicalDeviceImageFormatInfo2 imageFormatInfo;
623*c8dee2aaSAndroid Build Coastguard Worker imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
624*c8dee2aaSAndroid Build Coastguard Worker imageFormatInfo.pNext = &externalImageFormatInfo;
625*c8dee2aaSAndroid Build Coastguard Worker imageFormatInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
626*c8dee2aaSAndroid Build Coastguard Worker imageFormatInfo.type = VK_IMAGE_TYPE_2D;
627*c8dee2aaSAndroid Build Coastguard Worker imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
628*c8dee2aaSAndroid Build Coastguard Worker imageFormatInfo.usage = usageFlags;
629*c8dee2aaSAndroid Build Coastguard Worker imageFormatInfo.flags = 0;
630*c8dee2aaSAndroid Build Coastguard Worker
631*c8dee2aaSAndroid Build Coastguard Worker VkAndroidHardwareBufferUsageANDROID hwbUsage;
632*c8dee2aaSAndroid Build Coastguard Worker hwbUsage.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
633*c8dee2aaSAndroid Build Coastguard Worker hwbUsage.pNext = nullptr;
634*c8dee2aaSAndroid Build Coastguard Worker
635*c8dee2aaSAndroid Build Coastguard Worker VkExternalImageFormatProperties externalImgFormatProps;
636*c8dee2aaSAndroid Build Coastguard Worker externalImgFormatProps.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES;
637*c8dee2aaSAndroid Build Coastguard Worker externalImgFormatProps.pNext = &hwbUsage;
638*c8dee2aaSAndroid Build Coastguard Worker
639*c8dee2aaSAndroid Build Coastguard Worker VkImageFormatProperties2 imgFormProps;
640*c8dee2aaSAndroid Build Coastguard Worker imgFormProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
641*c8dee2aaSAndroid Build Coastguard Worker imgFormProps.pNext = &externalImgFormatProps;
642*c8dee2aaSAndroid Build Coastguard Worker
643*c8dee2aaSAndroid Build Coastguard Worker err = fVkGetPhysicalDeviceImageFormatProperties2(fBackendContext.fPhysicalDevice,
644*c8dee2aaSAndroid Build Coastguard Worker &imageFormatInfo, &imgFormProps);
645*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
646*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "vkGetPhysicalDeviceImageFormatProperites failed, err: %d", err);
647*c8dee2aaSAndroid Build Coastguard Worker return false;
648*c8dee2aaSAndroid Build Coastguard Worker }
649*c8dee2aaSAndroid Build Coastguard Worker
650*c8dee2aaSAndroid Build Coastguard Worker const VkImageFormatProperties& imageFormatProperties = imgFormProps.imageFormatProperties;
651*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, DEV_W <= imageFormatProperties.maxExtent.width);
652*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, DEV_H <= imageFormatProperties.maxExtent.height);
653*c8dee2aaSAndroid Build Coastguard Worker
654*c8dee2aaSAndroid Build Coastguard Worker const VkExternalMemoryProperties& externalImageFormatProps =
655*c8dee2aaSAndroid Build Coastguard Worker externalImgFormatProps.externalMemoryProperties;
656*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkToBool(VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT &
657*c8dee2aaSAndroid Build Coastguard Worker externalImageFormatProps.externalMemoryFeatures));
658*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkToBool(VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT &
659*c8dee2aaSAndroid Build Coastguard Worker externalImageFormatProps.externalMemoryFeatures));
660*c8dee2aaSAndroid Build Coastguard Worker
661*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, SkToBool(AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE &
662*c8dee2aaSAndroid Build Coastguard Worker hwbUsage.androidHardwareBufferUsage));
663*c8dee2aaSAndroid Build Coastguard Worker
664*c8dee2aaSAndroid Build Coastguard Worker return true;
665*c8dee2aaSAndroid Build Coastguard Worker }
666*c8dee2aaSAndroid Build Coastguard Worker
importHardwareBuffer(skiatest::Reporter * reporter,AHardwareBuffer * buffer,bool forWrite,GrVkImageInfo * outImageInfo)667*c8dee2aaSAndroid Build Coastguard Worker bool VulkanTestHelper::importHardwareBuffer(skiatest::Reporter* reporter,
668*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer,
669*c8dee2aaSAndroid Build Coastguard Worker bool forWrite,
670*c8dee2aaSAndroid Build Coastguard Worker GrVkImageInfo* outImageInfo) {
671*c8dee2aaSAndroid Build Coastguard Worker VkResult err;
672*c8dee2aaSAndroid Build Coastguard Worker
673*c8dee2aaSAndroid Build Coastguard Worker VkAndroidHardwareBufferFormatPropertiesANDROID hwbFormatProps;
674*c8dee2aaSAndroid Build Coastguard Worker hwbFormatProps.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
675*c8dee2aaSAndroid Build Coastguard Worker hwbFormatProps.pNext = nullptr;
676*c8dee2aaSAndroid Build Coastguard Worker
677*c8dee2aaSAndroid Build Coastguard Worker VkAndroidHardwareBufferPropertiesANDROID hwbProps;
678*c8dee2aaSAndroid Build Coastguard Worker hwbProps.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
679*c8dee2aaSAndroid Build Coastguard Worker hwbProps.pNext = &hwbFormatProps;
680*c8dee2aaSAndroid Build Coastguard Worker
681*c8dee2aaSAndroid Build Coastguard Worker err = fVkGetAndroidHardwareBufferPropertiesANDROID(fDevice, buffer, &hwbProps);
682*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
683*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "GetAndroidHardwareBufferPropertiesAndroid failed, err: %d", err);
684*c8dee2aaSAndroid Build Coastguard Worker return false;
685*c8dee2aaSAndroid Build Coastguard Worker }
686*c8dee2aaSAndroid Build Coastguard Worker
687*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, VK_FORMAT_R8G8B8A8_UNORM == hwbFormatProps.format);
688*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
689*c8dee2aaSAndroid Build Coastguard Worker SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & hwbFormatProps.formatFeatures) &&
690*c8dee2aaSAndroid Build Coastguard Worker SkToBool(VK_FORMAT_FEATURE_TRANSFER_SRC_BIT & hwbFormatProps.formatFeatures) &&
691*c8dee2aaSAndroid Build Coastguard Worker SkToBool(VK_FORMAT_FEATURE_TRANSFER_DST_BIT & hwbFormatProps.formatFeatures));
692*c8dee2aaSAndroid Build Coastguard Worker if (forWrite) {
693*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter,
694*c8dee2aaSAndroid Build Coastguard Worker SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT & hwbFormatProps.formatFeatures));
695*c8dee2aaSAndroid Build Coastguard Worker
696*c8dee2aaSAndroid Build Coastguard Worker }
697*c8dee2aaSAndroid Build Coastguard Worker
698*c8dee2aaSAndroid Build Coastguard Worker bool useExternalFormat = VK_FORMAT_UNDEFINED == hwbFormatProps.format;
699*c8dee2aaSAndroid Build Coastguard Worker const VkExternalFormatANDROID externalFormatInfo {
700*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID, // sType
701*c8dee2aaSAndroid Build Coastguard Worker nullptr, // pNext
702*c8dee2aaSAndroid Build Coastguard Worker useExternalFormat ? hwbFormatProps.externalFormat : 0, // externalFormat
703*c8dee2aaSAndroid Build Coastguard Worker };
704*c8dee2aaSAndroid Build Coastguard Worker
705*c8dee2aaSAndroid Build Coastguard Worker const VkExternalMemoryImageCreateInfo externalMemoryImageInfo {
706*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, // sType
707*c8dee2aaSAndroid Build Coastguard Worker &externalFormatInfo, // pNext
708*c8dee2aaSAndroid Build Coastguard Worker VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, // handleTypes
709*c8dee2aaSAndroid Build Coastguard Worker };
710*c8dee2aaSAndroid Build Coastguard Worker
711*c8dee2aaSAndroid Build Coastguard Worker VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT |
712*c8dee2aaSAndroid Build Coastguard Worker VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
713*c8dee2aaSAndroid Build Coastguard Worker VK_IMAGE_USAGE_TRANSFER_DST_BIT;
714*c8dee2aaSAndroid Build Coastguard Worker if (forWrite) {
715*c8dee2aaSAndroid Build Coastguard Worker usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
716*c8dee2aaSAndroid Build Coastguard Worker }
717*c8dee2aaSAndroid Build Coastguard Worker
718*c8dee2aaSAndroid Build Coastguard Worker const VkImageCreateInfo imageCreateInfo = {
719*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
720*c8dee2aaSAndroid Build Coastguard Worker &externalMemoryImageInfo, // pNext
721*c8dee2aaSAndroid Build Coastguard Worker 0, // VkImageCreateFlags
722*c8dee2aaSAndroid Build Coastguard Worker VK_IMAGE_TYPE_2D, // VkImageType
723*c8dee2aaSAndroid Build Coastguard Worker hwbFormatProps.format, // VkFormat
724*c8dee2aaSAndroid Build Coastguard Worker { DEV_W, DEV_H, 1 }, // VkExtent3D
725*c8dee2aaSAndroid Build Coastguard Worker 1, // mipLevels
726*c8dee2aaSAndroid Build Coastguard Worker 1, // arrayLayers
727*c8dee2aaSAndroid Build Coastguard Worker VK_SAMPLE_COUNT_1_BIT, // samples
728*c8dee2aaSAndroid Build Coastguard Worker VK_IMAGE_TILING_OPTIMAL, // VkImageTiling
729*c8dee2aaSAndroid Build Coastguard Worker usageFlags, // VkImageUsageFlags
730*c8dee2aaSAndroid Build Coastguard Worker VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode
731*c8dee2aaSAndroid Build Coastguard Worker 0, // queueFamilyCount
732*c8dee2aaSAndroid Build Coastguard Worker 0, // pQueueFamilyIndices
733*c8dee2aaSAndroid Build Coastguard Worker VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
734*c8dee2aaSAndroid Build Coastguard Worker };
735*c8dee2aaSAndroid Build Coastguard Worker
736*c8dee2aaSAndroid Build Coastguard Worker err = fVkCreateImage(fDevice, &imageCreateInfo, nullptr, &fImage);
737*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
738*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Create Image failed, err: %d", err);
739*c8dee2aaSAndroid Build Coastguard Worker return false;
740*c8dee2aaSAndroid Build Coastguard Worker }
741*c8dee2aaSAndroid Build Coastguard Worker
742*c8dee2aaSAndroid Build Coastguard Worker VkPhysicalDeviceMemoryProperties2 phyDevMemProps;
743*c8dee2aaSAndroid Build Coastguard Worker phyDevMemProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
744*c8dee2aaSAndroid Build Coastguard Worker phyDevMemProps.pNext = nullptr;
745*c8dee2aaSAndroid Build Coastguard Worker
746*c8dee2aaSAndroid Build Coastguard Worker uint32_t typeIndex = 0;
747*c8dee2aaSAndroid Build Coastguard Worker uint32_t heapIndex = 0;
748*c8dee2aaSAndroid Build Coastguard Worker bool foundHeap = false;
749*c8dee2aaSAndroid Build Coastguard Worker fVkGetPhysicalDeviceMemoryProperties2(fBackendContext.fPhysicalDevice, &phyDevMemProps);
750*c8dee2aaSAndroid Build Coastguard Worker uint32_t memTypeCnt = phyDevMemProps.memoryProperties.memoryTypeCount;
751*c8dee2aaSAndroid Build Coastguard Worker for (uint32_t i = 0; i < memTypeCnt && !foundHeap; ++i) {
752*c8dee2aaSAndroid Build Coastguard Worker if (hwbProps.memoryTypeBits & (1 << i)) {
753*c8dee2aaSAndroid Build Coastguard Worker const VkPhysicalDeviceMemoryProperties& pdmp = phyDevMemProps.memoryProperties;
754*c8dee2aaSAndroid Build Coastguard Worker uint32_t supportedFlags = pdmp.memoryTypes[i].propertyFlags &
755*c8dee2aaSAndroid Build Coastguard Worker VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
756*c8dee2aaSAndroid Build Coastguard Worker if (supportedFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
757*c8dee2aaSAndroid Build Coastguard Worker typeIndex = i;
758*c8dee2aaSAndroid Build Coastguard Worker heapIndex = pdmp.memoryTypes[i].heapIndex;
759*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, heapIndex < pdmp.memoryHeapCount);
760*c8dee2aaSAndroid Build Coastguard Worker foundHeap = true;
761*c8dee2aaSAndroid Build Coastguard Worker }
762*c8dee2aaSAndroid Build Coastguard Worker }
763*c8dee2aaSAndroid Build Coastguard Worker }
764*c8dee2aaSAndroid Build Coastguard Worker
765*c8dee2aaSAndroid Build Coastguard Worker // Fallback to align with GrAHardwareBufferUtils
766*c8dee2aaSAndroid Build Coastguard Worker if (!foundHeap && hwbProps.memoryTypeBits) {
767*c8dee2aaSAndroid Build Coastguard Worker typeIndex = ffs(hwbProps.memoryTypeBits) - 1;
768*c8dee2aaSAndroid Build Coastguard Worker foundHeap = true;
769*c8dee2aaSAndroid Build Coastguard Worker }
770*c8dee2aaSAndroid Build Coastguard Worker
771*c8dee2aaSAndroid Build Coastguard Worker if (!foundHeap) {
772*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to find valid heap for imported memory");
773*c8dee2aaSAndroid Build Coastguard Worker return false;
774*c8dee2aaSAndroid Build Coastguard Worker }
775*c8dee2aaSAndroid Build Coastguard Worker
776*c8dee2aaSAndroid Build Coastguard Worker VkImportAndroidHardwareBufferInfoANDROID hwbImportInfo;
777*c8dee2aaSAndroid Build Coastguard Worker hwbImportInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
778*c8dee2aaSAndroid Build Coastguard Worker hwbImportInfo.pNext = nullptr;
779*c8dee2aaSAndroid Build Coastguard Worker hwbImportInfo.buffer = buffer;
780*c8dee2aaSAndroid Build Coastguard Worker
781*c8dee2aaSAndroid Build Coastguard Worker VkMemoryDedicatedAllocateInfo dedicatedAllocInfo;
782*c8dee2aaSAndroid Build Coastguard Worker dedicatedAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
783*c8dee2aaSAndroid Build Coastguard Worker dedicatedAllocInfo.pNext = &hwbImportInfo;
784*c8dee2aaSAndroid Build Coastguard Worker dedicatedAllocInfo.image = fImage;
785*c8dee2aaSAndroid Build Coastguard Worker dedicatedAllocInfo.buffer = VK_NULL_HANDLE;
786*c8dee2aaSAndroid Build Coastguard Worker
787*c8dee2aaSAndroid Build Coastguard Worker VkMemoryAllocateInfo allocInfo = {
788*c8dee2aaSAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
789*c8dee2aaSAndroid Build Coastguard Worker &dedicatedAllocInfo, // pNext
790*c8dee2aaSAndroid Build Coastguard Worker hwbProps.allocationSize, // allocationSize
791*c8dee2aaSAndroid Build Coastguard Worker typeIndex, // memoryTypeIndex
792*c8dee2aaSAndroid Build Coastguard Worker };
793*c8dee2aaSAndroid Build Coastguard Worker
794*c8dee2aaSAndroid Build Coastguard Worker err = fVkAllocateMemory(fDevice, &allocInfo, nullptr, &fMemory);
795*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
796*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "AllocateMemory failed for imported buffer, err: %d", err);
797*c8dee2aaSAndroid Build Coastguard Worker return false;
798*c8dee2aaSAndroid Build Coastguard Worker }
799*c8dee2aaSAndroid Build Coastguard Worker
800*c8dee2aaSAndroid Build Coastguard Worker VkBindImageMemoryInfo bindImageInfo;
801*c8dee2aaSAndroid Build Coastguard Worker bindImageInfo.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
802*c8dee2aaSAndroid Build Coastguard Worker bindImageInfo.pNext = nullptr;
803*c8dee2aaSAndroid Build Coastguard Worker bindImageInfo.image = fImage;
804*c8dee2aaSAndroid Build Coastguard Worker bindImageInfo.memory = fMemory;
805*c8dee2aaSAndroid Build Coastguard Worker bindImageInfo.memoryOffset = 0;
806*c8dee2aaSAndroid Build Coastguard Worker
807*c8dee2aaSAndroid Build Coastguard Worker err = fVkBindImageMemory2(fDevice, 1, &bindImageInfo);
808*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
809*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "BindImageMemory failed for imported buffer, err: %d", err);
810*c8dee2aaSAndroid Build Coastguard Worker return false;
811*c8dee2aaSAndroid Build Coastguard Worker }
812*c8dee2aaSAndroid Build Coastguard Worker
813*c8dee2aaSAndroid Build Coastguard Worker skgpu::VulkanAlloc alloc;
814*c8dee2aaSAndroid Build Coastguard Worker alloc.fMemory = fMemory;
815*c8dee2aaSAndroid Build Coastguard Worker alloc.fOffset = 0;
816*c8dee2aaSAndroid Build Coastguard Worker alloc.fSize = hwbProps.allocationSize;
817*c8dee2aaSAndroid Build Coastguard Worker alloc.fFlags = 0;
818*c8dee2aaSAndroid Build Coastguard Worker
819*c8dee2aaSAndroid Build Coastguard Worker outImageInfo->fImage = fImage;
820*c8dee2aaSAndroid Build Coastguard Worker outImageInfo->fAlloc = alloc;
821*c8dee2aaSAndroid Build Coastguard Worker outImageInfo->fImageTiling = VK_IMAGE_TILING_OPTIMAL;
822*c8dee2aaSAndroid Build Coastguard Worker outImageInfo->fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
823*c8dee2aaSAndroid Build Coastguard Worker outImageInfo->fFormat = VK_FORMAT_R8G8B8A8_UNORM;
824*c8dee2aaSAndroid Build Coastguard Worker outImageInfo->fImageUsageFlags = usageFlags;
825*c8dee2aaSAndroid Build Coastguard Worker outImageInfo->fLevelCount = 1;
826*c8dee2aaSAndroid Build Coastguard Worker outImageInfo->fCurrentQueueFamily = VK_QUEUE_FAMILY_EXTERNAL;
827*c8dee2aaSAndroid Build Coastguard Worker return true;
828*c8dee2aaSAndroid Build Coastguard Worker }
829*c8dee2aaSAndroid Build Coastguard Worker
importHardwareBufferForRead(skiatest::Reporter * reporter,AHardwareBuffer * buffer)830*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> VulkanTestHelper::importHardwareBufferForRead(skiatest::Reporter* reporter,
831*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) {
832*c8dee2aaSAndroid Build Coastguard Worker GrVkImageInfo imageInfo;
833*c8dee2aaSAndroid Build Coastguard Worker if (!this->importHardwareBuffer(reporter, buffer, false, &imageInfo)) {
834*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
835*c8dee2aaSAndroid Build Coastguard Worker }
836*c8dee2aaSAndroid Build Coastguard Worker
837*c8dee2aaSAndroid Build Coastguard Worker auto backendTex = GrBackendTextures::MakeVk(DEV_W, DEV_H, imageInfo);
838*c8dee2aaSAndroid Build Coastguard Worker
839*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> wrappedImage = SkImages::BorrowTextureFrom(fDirectContext.get(),
840*c8dee2aaSAndroid Build Coastguard Worker backendTex,
841*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
842*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
843*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType,
844*c8dee2aaSAndroid Build Coastguard Worker nullptr);
845*c8dee2aaSAndroid Build Coastguard Worker
846*c8dee2aaSAndroid Build Coastguard Worker if (!wrappedImage.get()) {
847*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to create wrapped Vulkan SkImage");
848*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
849*c8dee2aaSAndroid Build Coastguard Worker }
850*c8dee2aaSAndroid Build Coastguard Worker
851*c8dee2aaSAndroid Build Coastguard Worker return wrappedImage;
852*c8dee2aaSAndroid Build Coastguard Worker }
853*c8dee2aaSAndroid Build Coastguard Worker
flushSurfaceAndSignalSemaphore(skiatest::Reporter * reporter,sk_sp<SkSurface> surface)854*c8dee2aaSAndroid Build Coastguard Worker bool VulkanTestHelper::flushSurfaceAndSignalSemaphore(skiatest::Reporter* reporter,
855*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface) {
856*c8dee2aaSAndroid Build Coastguard Worker this->releaseSurfaceToExternal(surface.get());
857*c8dee2aaSAndroid Build Coastguard Worker surface.reset();
858*c8dee2aaSAndroid Build Coastguard Worker GrBackendSemaphore semaphore;
859*c8dee2aaSAndroid Build Coastguard Worker if (!this->setupSemaphoreForSignaling(reporter, &semaphore)) {
860*c8dee2aaSAndroid Build Coastguard Worker return false;
861*c8dee2aaSAndroid Build Coastguard Worker }
862*c8dee2aaSAndroid Build Coastguard Worker GrFlushInfo info;
863*c8dee2aaSAndroid Build Coastguard Worker info.fNumSemaphores = 1;
864*c8dee2aaSAndroid Build Coastguard Worker info.fSignalSemaphores = &semaphore;
865*c8dee2aaSAndroid Build Coastguard Worker GrSemaphoresSubmitted submitted = fDirectContext->flush(info);
866*c8dee2aaSAndroid Build Coastguard Worker fDirectContext->submit();
867*c8dee2aaSAndroid Build Coastguard Worker if (GrSemaphoresSubmitted::kNo == submitted) {
868*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failing call to flush on GrDirectContext");
869*c8dee2aaSAndroid Build Coastguard Worker return false;
870*c8dee2aaSAndroid Build Coastguard Worker }
871*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(semaphore.isInitialized());
872*c8dee2aaSAndroid Build Coastguard Worker if (!this->exportSemaphore(reporter, semaphore)) {
873*c8dee2aaSAndroid Build Coastguard Worker return false;
874*c8dee2aaSAndroid Build Coastguard Worker }
875*c8dee2aaSAndroid Build Coastguard Worker return true;
876*c8dee2aaSAndroid Build Coastguard Worker }
877*c8dee2aaSAndroid Build Coastguard Worker
setupSemaphoreForSignaling(skiatest::Reporter * reporter,GrBackendSemaphore * beSemaphore)878*c8dee2aaSAndroid Build Coastguard Worker bool VulkanTestHelper::setupSemaphoreForSignaling(skiatest::Reporter* reporter,
879*c8dee2aaSAndroid Build Coastguard Worker GrBackendSemaphore* beSemaphore) {
880*c8dee2aaSAndroid Build Coastguard Worker // Query supported info
881*c8dee2aaSAndroid Build Coastguard Worker VkPhysicalDeviceExternalSemaphoreInfo exSemInfo;
882*c8dee2aaSAndroid Build Coastguard Worker exSemInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO;
883*c8dee2aaSAndroid Build Coastguard Worker exSemInfo.pNext = nullptr;
884*c8dee2aaSAndroid Build Coastguard Worker exSemInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
885*c8dee2aaSAndroid Build Coastguard Worker
886*c8dee2aaSAndroid Build Coastguard Worker VkExternalSemaphoreProperties exSemProps;
887*c8dee2aaSAndroid Build Coastguard Worker exSemProps.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;
888*c8dee2aaSAndroid Build Coastguard Worker exSemProps.pNext = nullptr;
889*c8dee2aaSAndroid Build Coastguard Worker
890*c8dee2aaSAndroid Build Coastguard Worker fVkGetPhysicalDeviceExternalSemaphoreProperties(fBackendContext.fPhysicalDevice, &exSemInfo,
891*c8dee2aaSAndroid Build Coastguard Worker &exSemProps);
892*c8dee2aaSAndroid Build Coastguard Worker
893*c8dee2aaSAndroid Build Coastguard Worker if (!SkToBool(exSemProps.exportFromImportedHandleTypes &
894*c8dee2aaSAndroid Build Coastguard Worker VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)) {
895*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "HANDLE_TYPE_SYNC_FD not listed as exportFromImportedHandleTypes");
896*c8dee2aaSAndroid Build Coastguard Worker return false;
897*c8dee2aaSAndroid Build Coastguard Worker }
898*c8dee2aaSAndroid Build Coastguard Worker if (!SkToBool(exSemProps.compatibleHandleTypes &
899*c8dee2aaSAndroid Build Coastguard Worker VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)) {
900*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "HANDLE_TYPE_SYNC_FD not listed as compatibleHandleTypes");
901*c8dee2aaSAndroid Build Coastguard Worker return false;
902*c8dee2aaSAndroid Build Coastguard Worker }
903*c8dee2aaSAndroid Build Coastguard Worker if (!SkToBool(exSemProps.externalSemaphoreFeatures &
904*c8dee2aaSAndroid Build Coastguard Worker VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) ||
905*c8dee2aaSAndroid Build Coastguard Worker !SkToBool(exSemProps.externalSemaphoreFeatures &
906*c8dee2aaSAndroid Build Coastguard Worker VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT)) {
907*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "HANDLE_TYPE_SYNC_FD doesn't support export and import feature");
908*c8dee2aaSAndroid Build Coastguard Worker return false;
909*c8dee2aaSAndroid Build Coastguard Worker }
910*c8dee2aaSAndroid Build Coastguard Worker
911*c8dee2aaSAndroid Build Coastguard Worker VkExportSemaphoreCreateInfo exportInfo;
912*c8dee2aaSAndroid Build Coastguard Worker exportInfo.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO;
913*c8dee2aaSAndroid Build Coastguard Worker exportInfo.pNext = nullptr;
914*c8dee2aaSAndroid Build Coastguard Worker exportInfo.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
915*c8dee2aaSAndroid Build Coastguard Worker
916*c8dee2aaSAndroid Build Coastguard Worker VkSemaphoreCreateInfo semaphoreInfo;
917*c8dee2aaSAndroid Build Coastguard Worker semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
918*c8dee2aaSAndroid Build Coastguard Worker semaphoreInfo.pNext = &exportInfo;
919*c8dee2aaSAndroid Build Coastguard Worker semaphoreInfo.flags = 0;
920*c8dee2aaSAndroid Build Coastguard Worker
921*c8dee2aaSAndroid Build Coastguard Worker VkSemaphore semaphore;
922*c8dee2aaSAndroid Build Coastguard Worker VkResult err = fVkCreateSemaphore(fDevice, &semaphoreInfo, nullptr, &semaphore);
923*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
924*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to create signal semaphore, err: %d", err);
925*c8dee2aaSAndroid Build Coastguard Worker return false;
926*c8dee2aaSAndroid Build Coastguard Worker }
927*c8dee2aaSAndroid Build Coastguard Worker *beSemaphore = GrBackendSemaphores::MakeVk(semaphore);
928*c8dee2aaSAndroid Build Coastguard Worker return true;
929*c8dee2aaSAndroid Build Coastguard Worker }
930*c8dee2aaSAndroid Build Coastguard Worker
exportSemaphore(skiatest::Reporter * reporter,const GrBackendSemaphore & beSemaphore)931*c8dee2aaSAndroid Build Coastguard Worker bool VulkanTestHelper::exportSemaphore(skiatest::Reporter* reporter,
932*c8dee2aaSAndroid Build Coastguard Worker const GrBackendSemaphore& beSemaphore) {
933*c8dee2aaSAndroid Build Coastguard Worker VkSemaphore semaphore = GrBackendSemaphores::GetVkSemaphore(beSemaphore);
934*c8dee2aaSAndroid Build Coastguard Worker if (VK_NULL_HANDLE == semaphore) {
935*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Invalid vulkan handle in export call");
936*c8dee2aaSAndroid Build Coastguard Worker return false;
937*c8dee2aaSAndroid Build Coastguard Worker }
938*c8dee2aaSAndroid Build Coastguard Worker
939*c8dee2aaSAndroid Build Coastguard Worker VkSemaphoreGetFdInfoKHR getFdInfo;
940*c8dee2aaSAndroid Build Coastguard Worker getFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR;
941*c8dee2aaSAndroid Build Coastguard Worker getFdInfo.pNext = nullptr;
942*c8dee2aaSAndroid Build Coastguard Worker getFdInfo.semaphore = semaphore;
943*c8dee2aaSAndroid Build Coastguard Worker getFdInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
944*c8dee2aaSAndroid Build Coastguard Worker
945*c8dee2aaSAndroid Build Coastguard Worker VkResult err = fVkGetSemaphoreFdKHR(fDevice, &getFdInfo, &fFdHandle);
946*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
947*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to export signal semaphore, err: %d", err);
948*c8dee2aaSAndroid Build Coastguard Worker return false;
949*c8dee2aaSAndroid Build Coastguard Worker }
950*c8dee2aaSAndroid Build Coastguard Worker fSignalSemaphore = semaphore;
951*c8dee2aaSAndroid Build Coastguard Worker return true;
952*c8dee2aaSAndroid Build Coastguard Worker }
953*c8dee2aaSAndroid Build Coastguard Worker
importAndWaitOnSemaphore(skiatest::Reporter * reporter,int fdHandle,sk_sp<SkSurface> surface)954*c8dee2aaSAndroid Build Coastguard Worker bool VulkanTestHelper::importAndWaitOnSemaphore(skiatest::Reporter* reporter, int fdHandle,
955*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface) {
956*c8dee2aaSAndroid Build Coastguard Worker VkSemaphoreCreateInfo semaphoreInfo;
957*c8dee2aaSAndroid Build Coastguard Worker semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
958*c8dee2aaSAndroid Build Coastguard Worker semaphoreInfo.pNext = nullptr;
959*c8dee2aaSAndroid Build Coastguard Worker semaphoreInfo.flags = 0;
960*c8dee2aaSAndroid Build Coastguard Worker
961*c8dee2aaSAndroid Build Coastguard Worker VkSemaphore semaphore;
962*c8dee2aaSAndroid Build Coastguard Worker VkResult err = fVkCreateSemaphore(fDevice, &semaphoreInfo, nullptr, &semaphore);
963*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
964*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to create import semaphore, err: %d", err);
965*c8dee2aaSAndroid Build Coastguard Worker return false;
966*c8dee2aaSAndroid Build Coastguard Worker }
967*c8dee2aaSAndroid Build Coastguard Worker
968*c8dee2aaSAndroid Build Coastguard Worker VkImportSemaphoreFdInfoKHR importInfo;
969*c8dee2aaSAndroid Build Coastguard Worker importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
970*c8dee2aaSAndroid Build Coastguard Worker importInfo.pNext = nullptr;
971*c8dee2aaSAndroid Build Coastguard Worker importInfo.semaphore = semaphore;
972*c8dee2aaSAndroid Build Coastguard Worker importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT;
973*c8dee2aaSAndroid Build Coastguard Worker importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
974*c8dee2aaSAndroid Build Coastguard Worker importInfo.fd = fdHandle;
975*c8dee2aaSAndroid Build Coastguard Worker
976*c8dee2aaSAndroid Build Coastguard Worker err = fVkImportSemaphoreFdKHR(fDevice, &importInfo);
977*c8dee2aaSAndroid Build Coastguard Worker if (VK_SUCCESS != err) {
978*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to import semaphore, err: %d", err);
979*c8dee2aaSAndroid Build Coastguard Worker return false;
980*c8dee2aaSAndroid Build Coastguard Worker }
981*c8dee2aaSAndroid Build Coastguard Worker
982*c8dee2aaSAndroid Build Coastguard Worker GrBackendSemaphore beSemaphore = GrBackendSemaphores::MakeVk(semaphore);
983*c8dee2aaSAndroid Build Coastguard Worker if (!surface->wait(1, &beSemaphore)) {
984*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to add wait semaphore to surface");
985*c8dee2aaSAndroid Build Coastguard Worker fVkDestroySemaphore(fDevice, semaphore, nullptr);
986*c8dee2aaSAndroid Build Coastguard Worker return false;
987*c8dee2aaSAndroid Build Coastguard Worker }
988*c8dee2aaSAndroid Build Coastguard Worker return true;
989*c8dee2aaSAndroid Build Coastguard Worker }
990*c8dee2aaSAndroid Build Coastguard Worker
importHardwareBufferForWrite(skiatest::Reporter * reporter,AHardwareBuffer * buffer)991*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> VulkanTestHelper::importHardwareBufferForWrite(skiatest::Reporter* reporter,
992*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) {
993*c8dee2aaSAndroid Build Coastguard Worker GrVkImageInfo imageInfo;
994*c8dee2aaSAndroid Build Coastguard Worker if (!this->importHardwareBuffer(reporter, buffer, true, &imageInfo)) {
995*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
996*c8dee2aaSAndroid Build Coastguard Worker }
997*c8dee2aaSAndroid Build Coastguard Worker
998*c8dee2aaSAndroid Build Coastguard Worker auto backendTex = GrBackendTextures::MakeVk(DEV_W, DEV_H, imageInfo);
999*c8dee2aaSAndroid Build Coastguard Worker
1000*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface = SkSurfaces::WrapBackendTexture(fDirectContext.get(),
1001*c8dee2aaSAndroid Build Coastguard Worker backendTex,
1002*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
1003*c8dee2aaSAndroid Build Coastguard Worker 0,
1004*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
1005*c8dee2aaSAndroid Build Coastguard Worker nullptr,
1006*c8dee2aaSAndroid Build Coastguard Worker nullptr);
1007*c8dee2aaSAndroid Build Coastguard Worker
1008*c8dee2aaSAndroid Build Coastguard Worker if (!surface.get()) {
1009*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to create wrapped Vulkan SkSurface");
1010*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
1011*c8dee2aaSAndroid Build Coastguard Worker }
1012*c8dee2aaSAndroid Build Coastguard Worker
1013*c8dee2aaSAndroid Build Coastguard Worker return surface;
1014*c8dee2aaSAndroid Build Coastguard Worker }
1015*c8dee2aaSAndroid Build Coastguard Worker
get_src_color(int x,int y)1016*c8dee2aaSAndroid Build Coastguard Worker static SkPMColor get_src_color(int x, int y) {
1017*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(x >= 0 && x < DEV_W);
1018*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(y >= 0 && y < DEV_H);
1019*c8dee2aaSAndroid Build Coastguard Worker
1020*c8dee2aaSAndroid Build Coastguard Worker U8CPU r = x;
1021*c8dee2aaSAndroid Build Coastguard Worker U8CPU g = y;
1022*c8dee2aaSAndroid Build Coastguard Worker U8CPU b = 0xc;
1023*c8dee2aaSAndroid Build Coastguard Worker
1024*c8dee2aaSAndroid Build Coastguard Worker U8CPU a = 0xff;
1025*c8dee2aaSAndroid Build Coastguard Worker switch ((x+y) % 5) {
1026*c8dee2aaSAndroid Build Coastguard Worker case 0:
1027*c8dee2aaSAndroid Build Coastguard Worker a = 0xff;
1028*c8dee2aaSAndroid Build Coastguard Worker break;
1029*c8dee2aaSAndroid Build Coastguard Worker case 1:
1030*c8dee2aaSAndroid Build Coastguard Worker a = 0x80;
1031*c8dee2aaSAndroid Build Coastguard Worker break;
1032*c8dee2aaSAndroid Build Coastguard Worker case 2:
1033*c8dee2aaSAndroid Build Coastguard Worker a = 0xCC;
1034*c8dee2aaSAndroid Build Coastguard Worker break;
1035*c8dee2aaSAndroid Build Coastguard Worker case 4:
1036*c8dee2aaSAndroid Build Coastguard Worker a = 0x01;
1037*c8dee2aaSAndroid Build Coastguard Worker break;
1038*c8dee2aaSAndroid Build Coastguard Worker case 3:
1039*c8dee2aaSAndroid Build Coastguard Worker a = 0x00;
1040*c8dee2aaSAndroid Build Coastguard Worker break;
1041*c8dee2aaSAndroid Build Coastguard Worker }
1042*c8dee2aaSAndroid Build Coastguard Worker a = 0xff;
1043*c8dee2aaSAndroid Build Coastguard Worker return SkPremultiplyARGBInline(a, r, g, b);
1044*c8dee2aaSAndroid Build Coastguard Worker }
1045*c8dee2aaSAndroid Build Coastguard Worker
make_src_bitmap()1046*c8dee2aaSAndroid Build Coastguard Worker static SkBitmap make_src_bitmap() {
1047*c8dee2aaSAndroid Build Coastguard Worker static SkBitmap bmp;
1048*c8dee2aaSAndroid Build Coastguard Worker if (bmp.isNull()) {
1049*c8dee2aaSAndroid Build Coastguard Worker bmp.allocN32Pixels(DEV_W, DEV_H);
1050*c8dee2aaSAndroid Build Coastguard Worker intptr_t pixels = reinterpret_cast<intptr_t>(bmp.getPixels());
1051*c8dee2aaSAndroid Build Coastguard Worker for (int y = 0; y < DEV_H; ++y) {
1052*c8dee2aaSAndroid Build Coastguard Worker for (int x = 0; x < DEV_W; ++x) {
1053*c8dee2aaSAndroid Build Coastguard Worker SkPMColor* pixel = reinterpret_cast<SkPMColor*>(
1054*c8dee2aaSAndroid Build Coastguard Worker pixels + y * bmp.rowBytes() + x * bmp.bytesPerPixel());
1055*c8dee2aaSAndroid Build Coastguard Worker *pixel = get_src_color(x, y);
1056*c8dee2aaSAndroid Build Coastguard Worker }
1057*c8dee2aaSAndroid Build Coastguard Worker }
1058*c8dee2aaSAndroid Build Coastguard Worker }
1059*c8dee2aaSAndroid Build Coastguard Worker return bmp;
1060*c8dee2aaSAndroid Build Coastguard Worker }
1061*c8dee2aaSAndroid Build Coastguard Worker
check_read(skiatest::Reporter * reporter,const SkBitmap & srcBitmap,const SkBitmap & dstBitmap)1062*c8dee2aaSAndroid Build Coastguard Worker static bool check_read(skiatest::Reporter* reporter, const SkBitmap& srcBitmap,
1063*c8dee2aaSAndroid Build Coastguard Worker const SkBitmap& dstBitmap) {
1064*c8dee2aaSAndroid Build Coastguard Worker bool result = true;
1065*c8dee2aaSAndroid Build Coastguard Worker for (int y = 0; y < DEV_H && result; ++y) {
1066*c8dee2aaSAndroid Build Coastguard Worker for (int x = 0; x < DEV_W && result; ++x) {
1067*c8dee2aaSAndroid Build Coastguard Worker const uint32_t srcPixel = *srcBitmap.getAddr32(x, y);
1068*c8dee2aaSAndroid Build Coastguard Worker const uint32_t dstPixel = *dstBitmap.getAddr32(x, y);
1069*c8dee2aaSAndroid Build Coastguard Worker if (srcPixel != dstPixel) {
1070*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Expected readback pixel (%d, %d) value 0x%08x, got 0x%08x.",
1071*c8dee2aaSAndroid Build Coastguard Worker x, y, srcPixel, dstPixel);
1072*c8dee2aaSAndroid Build Coastguard Worker result = false;
1073*c8dee2aaSAndroid Build Coastguard Worker } /*else {
1074*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Got good readback pixel (%d, %d) value 0x%08x, got 0x%08x.",
1075*c8dee2aaSAndroid Build Coastguard Worker x, y, srcPixel, dstPixel);
1076*c8dee2aaSAndroid Build Coastguard Worker
1077*c8dee2aaSAndroid Build Coastguard Worker }*/
1078*c8dee2aaSAndroid Build Coastguard Worker }
1079*c8dee2aaSAndroid Build Coastguard Worker }
1080*c8dee2aaSAndroid Build Coastguard Worker return result;
1081*c8dee2aaSAndroid Build Coastguard Worker }
1082*c8dee2aaSAndroid Build Coastguard Worker
cleanup_resources(BaseTestHelper * srcHelper,BaseTestHelper * dstHelper,AHardwareBuffer * buffer)1083*c8dee2aaSAndroid Build Coastguard Worker static void cleanup_resources(BaseTestHelper* srcHelper, BaseTestHelper* dstHelper,
1084*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer) {
1085*c8dee2aaSAndroid Build Coastguard Worker if (srcHelper) {
1086*c8dee2aaSAndroid Build Coastguard Worker srcHelper->cleanup();
1087*c8dee2aaSAndroid Build Coastguard Worker }
1088*c8dee2aaSAndroid Build Coastguard Worker if (dstHelper) {
1089*c8dee2aaSAndroid Build Coastguard Worker dstHelper->cleanup();
1090*c8dee2aaSAndroid Build Coastguard Worker }
1091*c8dee2aaSAndroid Build Coastguard Worker if (buffer) {
1092*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer_release(buffer);
1093*c8dee2aaSAndroid Build Coastguard Worker }
1094*c8dee2aaSAndroid Build Coastguard Worker }
1095*c8dee2aaSAndroid Build Coastguard Worker
1096*c8dee2aaSAndroid Build Coastguard Worker enum class SrcType {
1097*c8dee2aaSAndroid Build Coastguard Worker kCPU,
1098*c8dee2aaSAndroid Build Coastguard Worker kEGL,
1099*c8dee2aaSAndroid Build Coastguard Worker kVulkan,
1100*c8dee2aaSAndroid Build Coastguard Worker };
1101*c8dee2aaSAndroid Build Coastguard Worker
1102*c8dee2aaSAndroid Build Coastguard Worker enum class DstType {
1103*c8dee2aaSAndroid Build Coastguard Worker kEGL,
1104*c8dee2aaSAndroid Build Coastguard Worker kVulkan,
1105*c8dee2aaSAndroid Build Coastguard Worker };
1106*c8dee2aaSAndroid Build Coastguard Worker
run_test(skiatest::Reporter * reporter,const GrContextOptions & options,SrcType srcType,DstType dstType,bool shareSyncs)1107*c8dee2aaSAndroid Build Coastguard Worker void run_test(skiatest::Reporter* reporter, const GrContextOptions& options,
1108*c8dee2aaSAndroid Build Coastguard Worker SrcType srcType, DstType dstType, bool shareSyncs) {
1109*c8dee2aaSAndroid Build Coastguard Worker if (SrcType::kCPU == srcType && shareSyncs) {
1110*c8dee2aaSAndroid Build Coastguard Worker // We don't currently test this since we don't do any syncs in this case.
1111*c8dee2aaSAndroid Build Coastguard Worker return;
1112*c8dee2aaSAndroid Build Coastguard Worker }
1113*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<BaseTestHelper> srcHelper;
1114*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<BaseTestHelper> dstHelper;
1115*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer* buffer = nullptr;
1116*c8dee2aaSAndroid Build Coastguard Worker if (SrcType::kVulkan == srcType) {
1117*c8dee2aaSAndroid Build Coastguard Worker srcHelper.reset(new VulkanTestHelper());
1118*c8dee2aaSAndroid Build Coastguard Worker } else if (SrcType::kEGL == srcType) {
1119*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
1120*c8dee2aaSAndroid Build Coastguard Worker srcHelper.reset(new EGLTestHelper(options));
1121*c8dee2aaSAndroid Build Coastguard Worker #else
1122*c8dee2aaSAndroid Build Coastguard Worker SkASSERTF(false, "SrcType::kEGL used without OpenGL support.");
1123*c8dee2aaSAndroid Build Coastguard Worker #endif
1124*c8dee2aaSAndroid Build Coastguard Worker }
1125*c8dee2aaSAndroid Build Coastguard Worker if (srcHelper) {
1126*c8dee2aaSAndroid Build Coastguard Worker if (!srcHelper->init(reporter)) {
1127*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1128*c8dee2aaSAndroid Build Coastguard Worker return;
1129*c8dee2aaSAndroid Build Coastguard Worker }
1130*c8dee2aaSAndroid Build Coastguard Worker }
1131*c8dee2aaSAndroid Build Coastguard Worker
1132*c8dee2aaSAndroid Build Coastguard Worker if (DstType::kVulkan == dstType) {
1133*c8dee2aaSAndroid Build Coastguard Worker dstHelper.reset(new VulkanTestHelper());
1134*c8dee2aaSAndroid Build Coastguard Worker } else {
1135*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
1136*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(DstType::kEGL == dstType);
1137*c8dee2aaSAndroid Build Coastguard Worker dstHelper.reset(new EGLTestHelper(options));
1138*c8dee2aaSAndroid Build Coastguard Worker #else
1139*c8dee2aaSAndroid Build Coastguard Worker SkASSERTF(false, "DstType::kEGL used without OpenGL support.");
1140*c8dee2aaSAndroid Build Coastguard Worker #endif
1141*c8dee2aaSAndroid Build Coastguard Worker }
1142*c8dee2aaSAndroid Build Coastguard Worker if (dstHelper) {
1143*c8dee2aaSAndroid Build Coastguard Worker if (!dstHelper->init(reporter)) {
1144*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1145*c8dee2aaSAndroid Build Coastguard Worker return;
1146*c8dee2aaSAndroid Build Coastguard Worker }
1147*c8dee2aaSAndroid Build Coastguard Worker }
1148*c8dee2aaSAndroid Build Coastguard Worker
1149*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////
1150*c8dee2aaSAndroid Build Coastguard Worker // Setup SkBitmaps
1151*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////
1152*c8dee2aaSAndroid Build Coastguard Worker
1153*c8dee2aaSAndroid Build Coastguard Worker SkBitmap srcBitmap = make_src_bitmap();
1154*c8dee2aaSAndroid Build Coastguard Worker SkBitmap dstBitmapSurface;
1155*c8dee2aaSAndroid Build Coastguard Worker dstBitmapSurface.allocN32Pixels(DEV_W, DEV_H);
1156*c8dee2aaSAndroid Build Coastguard Worker SkBitmap dstBitmapFinal;
1157*c8dee2aaSAndroid Build Coastguard Worker dstBitmapFinal.allocN32Pixels(DEV_W, DEV_H);
1158*c8dee2aaSAndroid Build Coastguard Worker
1159*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////
1160*c8dee2aaSAndroid Build Coastguard Worker // Setup AHardwareBuffer
1161*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////
1162*c8dee2aaSAndroid Build Coastguard Worker
1163*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer_Desc hwbDesc;
1164*c8dee2aaSAndroid Build Coastguard Worker hwbDesc.width = DEV_W;
1165*c8dee2aaSAndroid Build Coastguard Worker hwbDesc.height = DEV_H;
1166*c8dee2aaSAndroid Build Coastguard Worker hwbDesc.layers = 1;
1167*c8dee2aaSAndroid Build Coastguard Worker if (SrcType::kCPU == srcType) {
1168*c8dee2aaSAndroid Build Coastguard Worker hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
1169*c8dee2aaSAndroid Build Coastguard Worker AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
1170*c8dee2aaSAndroid Build Coastguard Worker AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1171*c8dee2aaSAndroid Build Coastguard Worker } else {
1172*c8dee2aaSAndroid Build Coastguard Worker hwbDesc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
1173*c8dee2aaSAndroid Build Coastguard Worker AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
1174*c8dee2aaSAndroid Build Coastguard Worker AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
1175*c8dee2aaSAndroid Build Coastguard Worker AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
1176*c8dee2aaSAndroid Build Coastguard Worker }
1177*c8dee2aaSAndroid Build Coastguard Worker hwbDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
1178*c8dee2aaSAndroid Build Coastguard Worker // The following three are not used in the allocate
1179*c8dee2aaSAndroid Build Coastguard Worker hwbDesc.stride = 0;
1180*c8dee2aaSAndroid Build Coastguard Worker hwbDesc.rfu0= 0;
1181*c8dee2aaSAndroid Build Coastguard Worker hwbDesc.rfu1= 0;
1182*c8dee2aaSAndroid Build Coastguard Worker
1183*c8dee2aaSAndroid Build Coastguard Worker if (int error = AHardwareBuffer_allocate(&hwbDesc, &buffer)) {
1184*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to allocated hardware buffer, error: %d", error);
1185*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1186*c8dee2aaSAndroid Build Coastguard Worker return;
1187*c8dee2aaSAndroid Build Coastguard Worker }
1188*c8dee2aaSAndroid Build Coastguard Worker
1189*c8dee2aaSAndroid Build Coastguard Worker if (SrcType::kCPU == srcType) {
1190*c8dee2aaSAndroid Build Coastguard Worker // Get actual desc for allocated buffer so we know the stride for uploading cpu data.
1191*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer_describe(buffer, &hwbDesc);
1192*c8dee2aaSAndroid Build Coastguard Worker
1193*c8dee2aaSAndroid Build Coastguard Worker uint32_t* bufferAddr;
1194*c8dee2aaSAndroid Build Coastguard Worker if (AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, nullptr,
1195*c8dee2aaSAndroid Build Coastguard Worker reinterpret_cast<void**>(&bufferAddr))) {
1196*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to lock hardware buffer");
1197*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1198*c8dee2aaSAndroid Build Coastguard Worker return;
1199*c8dee2aaSAndroid Build Coastguard Worker }
1200*c8dee2aaSAndroid Build Coastguard Worker
1201*c8dee2aaSAndroid Build Coastguard Worker int bbp = srcBitmap.bytesPerPixel();
1202*c8dee2aaSAndroid Build Coastguard Worker uint32_t* src = (uint32_t*)srcBitmap.getPixels();
1203*c8dee2aaSAndroid Build Coastguard Worker uint32_t* dst = bufferAddr;
1204*c8dee2aaSAndroid Build Coastguard Worker for (int y = 0; y < DEV_H; ++y) {
1205*c8dee2aaSAndroid Build Coastguard Worker memcpy(dst, src, DEV_W * bbp);
1206*c8dee2aaSAndroid Build Coastguard Worker src += DEV_W;
1207*c8dee2aaSAndroid Build Coastguard Worker dst += hwbDesc.stride;
1208*c8dee2aaSAndroid Build Coastguard Worker }
1209*c8dee2aaSAndroid Build Coastguard Worker
1210*c8dee2aaSAndroid Build Coastguard Worker for (int y = 0; y < DEV_H; ++y) {
1211*c8dee2aaSAndroid Build Coastguard Worker for (int x = 0; x < DEV_W; ++x) {
1212*c8dee2aaSAndroid Build Coastguard Worker const uint32_t srcPixel = *srcBitmap.getAddr32(x, y);
1213*c8dee2aaSAndroid Build Coastguard Worker uint32_t dstPixel = bufferAddr[y * hwbDesc.stride + x];
1214*c8dee2aaSAndroid Build Coastguard Worker if (srcPixel != dstPixel) {
1215*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "CPU HWB Expected readpix (%d, %d) value 0x%08x, got 0x%08x.",
1216*c8dee2aaSAndroid Build Coastguard Worker x, y, srcPixel, dstPixel);
1217*c8dee2aaSAndroid Build Coastguard Worker }
1218*c8dee2aaSAndroid Build Coastguard Worker }
1219*c8dee2aaSAndroid Build Coastguard Worker }
1220*c8dee2aaSAndroid Build Coastguard Worker
1221*c8dee2aaSAndroid Build Coastguard Worker AHardwareBuffer_unlock(buffer, nullptr);
1222*c8dee2aaSAndroid Build Coastguard Worker
1223*c8dee2aaSAndroid Build Coastguard Worker } else {
1224*c8dee2aaSAndroid Build Coastguard Worker srcHelper->makeCurrent();
1225*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface = srcHelper->importHardwareBufferForWrite(reporter, buffer);
1226*c8dee2aaSAndroid Build Coastguard Worker
1227*c8dee2aaSAndroid Build Coastguard Worker if (!surface) {
1228*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1229*c8dee2aaSAndroid Build Coastguard Worker return;
1230*c8dee2aaSAndroid Build Coastguard Worker }
1231*c8dee2aaSAndroid Build Coastguard Worker
1232*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> srcBmpImage = SkImages::RasterFromBitmap(srcBitmap);
1233*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->drawImage(srcBmpImage, 0, 0);
1234*c8dee2aaSAndroid Build Coastguard Worker
1235*c8dee2aaSAndroid Build Coastguard Worker // If we are testing sharing of syncs, don't do a read here since it forces sychronization
1236*c8dee2aaSAndroid Build Coastguard Worker // to occur.
1237*c8dee2aaSAndroid Build Coastguard Worker if (!shareSyncs) {
1238*c8dee2aaSAndroid Build Coastguard Worker bool readResult = surface->readPixels(dstBitmapSurface, 0, 0);
1239*c8dee2aaSAndroid Build Coastguard Worker if (!readResult) {
1240*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Read Pixels on surface failed");
1241*c8dee2aaSAndroid Build Coastguard Worker surface.reset();
1242*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1243*c8dee2aaSAndroid Build Coastguard Worker return;
1244*c8dee2aaSAndroid Build Coastguard Worker }
1245*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_read(reporter, srcBitmap, dstBitmapSurface));
1246*c8dee2aaSAndroid Build Coastguard Worker }
1247*c8dee2aaSAndroid Build Coastguard Worker
1248*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////
1249*c8dee2aaSAndroid Build Coastguard Worker // Cleanup GL/EGL and add syncs
1250*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////
1251*c8dee2aaSAndroid Build Coastguard Worker
1252*c8dee2aaSAndroid Build Coastguard Worker if (shareSyncs) {
1253*c8dee2aaSAndroid Build Coastguard Worker if (!srcHelper->flushSurfaceAndSignalSemaphore(reporter, std::move(surface))) {
1254*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1255*c8dee2aaSAndroid Build Coastguard Worker return;
1256*c8dee2aaSAndroid Build Coastguard Worker }
1257*c8dee2aaSAndroid Build Coastguard Worker } else {
1258*c8dee2aaSAndroid Build Coastguard Worker srcHelper->releaseSurfaceToExternal(surface.get());
1259*c8dee2aaSAndroid Build Coastguard Worker srcHelper->doClientSync();
1260*c8dee2aaSAndroid Build Coastguard Worker surface.reset();
1261*c8dee2aaSAndroid Build Coastguard Worker srcHelper->releaseImage();
1262*c8dee2aaSAndroid Build Coastguard Worker }
1263*c8dee2aaSAndroid Build Coastguard Worker }
1264*c8dee2aaSAndroid Build Coastguard Worker
1265*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////
1266*c8dee2aaSAndroid Build Coastguard Worker // Import the HWB into backend and draw it to a surface
1267*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////
1268*c8dee2aaSAndroid Build Coastguard Worker
1269*c8dee2aaSAndroid Build Coastguard Worker dstHelper->makeCurrent();
1270*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> wrappedImage = dstHelper->importHardwareBufferForRead(reporter, buffer);
1271*c8dee2aaSAndroid Build Coastguard Worker
1272*c8dee2aaSAndroid Build Coastguard Worker if (!wrappedImage) {
1273*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1274*c8dee2aaSAndroid Build Coastguard Worker return;
1275*c8dee2aaSAndroid Build Coastguard Worker }
1276*c8dee2aaSAndroid Build Coastguard Worker
1277*c8dee2aaSAndroid Build Coastguard Worker auto direct = dstHelper->directContext();
1278*c8dee2aaSAndroid Build Coastguard Worker
1279*c8dee2aaSAndroid Build Coastguard Worker // Make SkSurface to render wrapped HWB into.
1280*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo imageInfo = SkImageInfo::Make(DEV_W, DEV_H, kRGBA_8888_SkColorType,
1281*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType, nullptr);
1282*c8dee2aaSAndroid Build Coastguard Worker
1283*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> dstSurf = SkSurfaces::RenderTarget(
1284*c8dee2aaSAndroid Build Coastguard Worker direct, skgpu::Budgeted::kNo, imageInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr, false);
1285*c8dee2aaSAndroid Build Coastguard Worker if (!dstSurf.get()) {
1286*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Failed to create destination SkSurface");
1287*c8dee2aaSAndroid Build Coastguard Worker wrappedImage.reset();
1288*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1289*c8dee2aaSAndroid Build Coastguard Worker return;
1290*c8dee2aaSAndroid Build Coastguard Worker }
1291*c8dee2aaSAndroid Build Coastguard Worker
1292*c8dee2aaSAndroid Build Coastguard Worker if (shareSyncs) {
1293*c8dee2aaSAndroid Build Coastguard Worker if (!dstHelper->importAndWaitOnSemaphore(reporter, srcHelper->getFdHandle(), dstSurf)) {
1294*c8dee2aaSAndroid Build Coastguard Worker wrappedImage.reset();
1295*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1296*c8dee2aaSAndroid Build Coastguard Worker return;
1297*c8dee2aaSAndroid Build Coastguard Worker }
1298*c8dee2aaSAndroid Build Coastguard Worker }
1299*c8dee2aaSAndroid Build Coastguard Worker dstSurf->getCanvas()->drawImage(wrappedImage, 0, 0);
1300*c8dee2aaSAndroid Build Coastguard Worker
1301*c8dee2aaSAndroid Build Coastguard Worker bool readResult = dstSurf->readPixels(dstBitmapFinal, 0, 0);
1302*c8dee2aaSAndroid Build Coastguard Worker if (!readResult) {
1303*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Read Pixels failed");
1304*c8dee2aaSAndroid Build Coastguard Worker wrappedImage.reset();
1305*c8dee2aaSAndroid Build Coastguard Worker dstSurf.reset();
1306*c8dee2aaSAndroid Build Coastguard Worker dstHelper->doClientSync();
1307*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1308*c8dee2aaSAndroid Build Coastguard Worker return;
1309*c8dee2aaSAndroid Build Coastguard Worker }
1310*c8dee2aaSAndroid Build Coastguard Worker
1311*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_read(reporter, srcBitmap, dstBitmapFinal));
1312*c8dee2aaSAndroid Build Coastguard Worker
1313*c8dee2aaSAndroid Build Coastguard Worker dstSurf.reset();
1314*c8dee2aaSAndroid Build Coastguard Worker wrappedImage.reset();
1315*c8dee2aaSAndroid Build Coastguard Worker dstHelper->doClientSync();
1316*c8dee2aaSAndroid Build Coastguard Worker cleanup_resources(srcHelper.get(), dstHelper.get(), buffer);
1317*c8dee2aaSAndroid Build Coastguard Worker }
1318*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(VulkanHardwareBuffer_CPU_Vulkan,reporter,options,CtsEnforcement::kApiLevel_T)1319*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_CPU_Vulkan, reporter, options, CtsEnforcement::kApiLevel_T) {
1320*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kCPU, DstType::kVulkan, false);
1321*c8dee2aaSAndroid Build Coastguard Worker }
1322*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(VulkanHardwareBuffer_Vulkan_Vulkan,reporter,options,CtsEnforcement::kApiLevel_T)1323*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_Vulkan_Vulkan,
1324*c8dee2aaSAndroid Build Coastguard Worker reporter,
1325*c8dee2aaSAndroid Build Coastguard Worker options,
1326*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
1327*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kVulkan, DstType::kVulkan, false);
1328*c8dee2aaSAndroid Build Coastguard Worker }
1329*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(VulkanHardwareBuffer_Vulkan_Vulkan_Syncs,reporter,options,CtsEnforcement::kApiLevel_T)1330*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_Vulkan_Vulkan_Syncs,
1331*c8dee2aaSAndroid Build Coastguard Worker reporter,
1332*c8dee2aaSAndroid Build Coastguard Worker options,
1333*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
1334*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kVulkan, DstType::kVulkan, true);
1335*c8dee2aaSAndroid Build Coastguard Worker }
1336*c8dee2aaSAndroid Build Coastguard Worker
1337*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GL)
DEF_GANESH_TEST(VulkanHardwareBuffer_EGL_Vulkan,reporter,options,CtsEnforcement::kApiLevel_T)1338*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_EGL_Vulkan, reporter, options, CtsEnforcement::kApiLevel_T) {
1339*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kEGL, DstType::kVulkan, false);
1340*c8dee2aaSAndroid Build Coastguard Worker }
1341*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(VulkanHardwareBuffer_CPU_EGL,reporter,options,CtsEnforcement::kApiLevel_T)1342*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_CPU_EGL, reporter, options, CtsEnforcement::kApiLevel_T) {
1343*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kCPU, DstType::kEGL, false);
1344*c8dee2aaSAndroid Build Coastguard Worker }
1345*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(VulkanHardwareBuffer_EGL_EGL,reporter,options,CtsEnforcement::kApiLevel_T)1346*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_EGL_EGL, reporter, options, CtsEnforcement::kApiLevel_T) {
1347*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kEGL, DstType::kEGL, false);
1348*c8dee2aaSAndroid Build Coastguard Worker }
1349*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(VulkanHardwareBuffer_Vulkan_EGL,reporter,options,CtsEnforcement::kApiLevel_T)1350*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_Vulkan_EGL, reporter, options, CtsEnforcement::kApiLevel_T) {
1351*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kVulkan, DstType::kEGL, false);
1352*c8dee2aaSAndroid Build Coastguard Worker }
1353*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(VulkanHardwareBuffer_EGL_EGL_Syncs,reporter,options,CtsEnforcement::kApiLevel_T)1354*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_EGL_EGL_Syncs,
1355*c8dee2aaSAndroid Build Coastguard Worker reporter,
1356*c8dee2aaSAndroid Build Coastguard Worker options,
1357*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
1358*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kEGL, DstType::kEGL, true);
1359*c8dee2aaSAndroid Build Coastguard Worker }
1360*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(VulkanHardwareBuffer_Vulkan_EGL_Syncs,reporter,options,CtsEnforcement::kApiLevel_T)1361*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_Vulkan_EGL_Syncs,
1362*c8dee2aaSAndroid Build Coastguard Worker reporter,
1363*c8dee2aaSAndroid Build Coastguard Worker options,
1364*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
1365*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kVulkan, DstType::kEGL, true);
1366*c8dee2aaSAndroid Build Coastguard Worker }
1367*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST(VulkanHardwareBuffer_EGL_Vulkan_Syncs,reporter,options,CtsEnforcement::kApiLevel_T)1368*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(VulkanHardwareBuffer_EGL_Vulkan_Syncs,
1369*c8dee2aaSAndroid Build Coastguard Worker reporter,
1370*c8dee2aaSAndroid Build Coastguard Worker options,
1371*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
1372*c8dee2aaSAndroid Build Coastguard Worker run_test(reporter, options, SrcType::kEGL, DstType::kVulkan, true);
1373*c8dee2aaSAndroid Build Coastguard Worker }
1374*c8dee2aaSAndroid Build Coastguard Worker #endif
1375*c8dee2aaSAndroid Build Coastguard Worker
1376*c8dee2aaSAndroid Build Coastguard Worker #endif // defined(SK_GANESH) && defined(SK_BUILD_FOR_ANDROID) &&
1377*c8dee2aaSAndroid Build Coastguard Worker // __ANDROID_API__ >= 26 && defined(SK_VULKAN)
1378*c8dee2aaSAndroid Build Coastguard Worker
1379