├── .gitignore
├── LICENSE
├── ManagedPlugin
├── AsyncGPUReadbackPlugin.cs
├── AsyncGPUReadbackPlugin.csproj
└── bin
│ └── Release
│ └── netstandard2.0
│ └── AsyncGPUReadbackPlugin.dll
├── NativePlugin
├── Makefile
├── build
│ ├── .gitkeep
│ └── libAsyncGPUReadbackPlugin.so
└── src
│ ├── AsyncGPUReadbackPlugin.cpp
│ ├── TypeHelpers.hpp
│ └── Unity
│ ├── IUnityGraphics.h
│ ├── IUnityGraphicsD3D11.h
│ ├── IUnityGraphicsD3D12.h
│ ├── IUnityGraphicsD3D9.h
│ ├── IUnityGraphicsMetal.h
│ ├── IUnityGraphicsVulkan.h
│ └── IUnityInterface.h
├── README.md
└── UnityExampleProject
├── .gitignore
├── Assets
├── Plugins.meta
├── Plugins
│ ├── libAsyncGPUReadbackPlugin.so
│ └── libAsyncGPUReadbackPlugin.so.meta
├── Scenes.meta
├── Scenes
│ ├── Scene.unity
│ └── Scene.unity.meta
├── Scripts.meta
├── Scripts
│ ├── AsyncGPUReadbackPlugin.dll
│ ├── AsyncGPUReadbackPlugin.dll.meta
│ ├── UsePlugin.cs
│ └── UsePlugin.cs.meta
├── b.mat
├── b.mat.meta
├── g.mat
├── g.mat.meta
├── r.mat
└── r.mat.meta
├── Packages
└── manifest.json
└── ProjectSettings
├── AudioManager.asset
├── ClusterInputManager.asset
├── DynamicsManager.asset
├── EditorBuildSettings.asset
├── EditorSettings.asset
├── GraphicsSettings.asset
├── InputManager.asset
├── NavMeshAreas.asset
├── NetworkManager.asset
├── Physics2DSettings.asset
├── PresetManager.asset
├── ProjectSettings.asset
├── ProjectVersion.txt
├── QualitySettings.asset
├── TagManager.asset
├── TimeManager.asset
└── UnityConnectSettings.asset
/.gitignore:
--------------------------------------------------------------------------------
1 | ManagedPlugin/obj
2 | ManagedPlugin/bin
3 | UnityExampleProject/test.png
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Aurélien Labate
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/ManagedPlugin/AsyncGPUReadbackPlugin.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 | using System;
4 | using System.Threading;
5 | using System.Runtime.InteropServices;
6 | using UnityEngine.Rendering;
7 | using Unity.Collections;
8 | using Unity.Collections.LowLevel.Unsafe;
9 |
10 | namespace AsyncGPUReadbackPluginNs {
11 |
12 | // Tries to match the official API
13 | public class AsyncGPUReadbackPlugin
14 | {
15 | public static AsyncGPUReadbackPluginRequest Request(Texture src)
16 | {
17 | return new AsyncGPUReadbackPluginRequest(src);
18 | }
19 | }
20 |
21 | public class AsyncGPUReadbackPluginRequest
22 | {
23 |
24 | ///
25 | /// Tell if we are using the plugin api or the official api
26 | ///
27 | private bool usePlugin;
28 |
29 | ///
30 | /// Official api request object used if supported
31 | ///
32 | private AsyncGPUReadbackRequest gpuRequest;
33 |
34 | ///
35 | /// Event Id used to tell what texture is targeted to the render thread
36 | ///
37 | private int eventId;
38 |
39 | ///
40 | /// Is buffer allocated
41 | ///
42 | private bool bufferCreated = false;
43 |
44 | ///
45 | /// Check if the request is done
46 | ///
47 | public bool done
48 | {
49 | get
50 | {
51 | if (usePlugin) {
52 | return isRequestDone(eventId);
53 | }
54 | else {
55 | return gpuRequest.done;
56 | }
57 | }
58 | }
59 |
60 | ///
61 | /// Check if the request has an error
62 | ///
63 | public bool hasError
64 | {
65 | get
66 | {
67 | if (usePlugin) {
68 | return isRequestError(eventId);
69 | }
70 | else {
71 | return gpuRequest.hasError;
72 | }
73 | }
74 | }
75 |
76 | ///
77 | /// Create an AsyncGPUReadbackPluginRequest.
78 | /// Use official AsyncGPUReadback.Request if possible.
79 | /// If not, it tries to use OpenGL specific implementation
80 | /// Warning! Can only be called from render thread yet (not main thread)
81 | ///
82 | ///
83 | ///
84 | public AsyncGPUReadbackPluginRequest(Texture src)
85 | {
86 | if (SystemInfo.supportsAsyncGPUReadback) {
87 | usePlugin = false;
88 | gpuRequest = AsyncGPUReadback.Request(src);
89 | }
90 | else if(isCompatible()) {
91 | usePlugin = true;
92 | int textureId = (int)(src.GetNativeTexturePtr());
93 | this.eventId = makeRequest_mainThread(textureId, 0);
94 | GL.IssuePluginEvent(getfunction_makeRequest_renderThread(), this.eventId);
95 | }
96 | else {
97 | Debug.LogError("AsyncGPUReadback is not supported on your system.");
98 | }
99 | }
100 |
101 | public unsafe byte[] GetRawData()
102 | {
103 | if (usePlugin) {
104 | // Get data from cpp plugin
105 | void* ptr = null;
106 | int length = 0;
107 | getData_mainThread(this.eventId, ref ptr, ref length);
108 |
109 | // Copy data to a buffer that we own and that will not be deleted
110 | byte[] buffer = new byte[length];
111 | Marshal.Copy(new IntPtr(ptr), buffer, 0, length);
112 | bufferCreated = true;
113 |
114 | return buffer;
115 | }
116 | else {
117 | return gpuRequest.GetData().ToArray();
118 | }
119 | }
120 |
121 | ///
122 | /// Has to be called regularly to update request status.
123 | /// Call this from Update() or from a corountine
124 | ///
125 | /// Update is automatic on official api,
126 | /// so we don't call the Update() method except on force mode.
127 | public void Update(bool force = false)
128 | {
129 | if (usePlugin) {
130 | GL.IssuePluginEvent(getfunction_update_renderThread(), this.eventId);
131 | }
132 | else if(force) {
133 | gpuRequest.Update();
134 | }
135 | }
136 |
137 | ///
138 | /// Has to be called to free the allocated buffer after it has been used
139 | ///
140 | public void Dispose()
141 | {
142 | if (usePlugin && bufferCreated) {
143 | dispose(this.eventId);
144 | }
145 | }
146 |
147 |
148 | [DllImport ("AsyncGPUReadbackPlugin")]
149 | private static extern bool isCompatible();
150 | [DllImport ("AsyncGPUReadbackPlugin")]
151 | private static extern int makeRequest_mainThread(int texture, int miplevel);
152 | [DllImport ("AsyncGPUReadbackPlugin")]
153 | private static extern IntPtr getfunction_makeRequest_renderThread();
154 | [DllImport ("AsyncGPUReadbackPlugin")]
155 | private static extern void makeRequest_renderThread(int event_id);
156 | [DllImport ("AsyncGPUReadbackPlugin")]
157 | private static extern IntPtr getfunction_update_renderThread();
158 | [DllImport ("AsyncGPUReadbackPlugin")]
159 | private static extern unsafe void getData_mainThread(int event_id, ref void* buffer, ref int length);
160 | [DllImport ("AsyncGPUReadbackPlugin")]
161 | private static extern bool isRequestError(int event_id);
162 | [DllImport ("AsyncGPUReadbackPlugin")]
163 | private static extern bool isRequestDone(int event_id);
164 | [DllImport ("AsyncGPUReadbackPlugin")]
165 | private static extern void dispose(int event_id);
166 | }
167 | }
--------------------------------------------------------------------------------
/ManagedPlugin/AsyncGPUReadbackPlugin.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | true
6 |
7 |
8 |
9 | /opt/Unity/Editor/Data/Managed/UnityEngine.dll
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ManagedPlugin/bin/Release/netstandard2.0/AsyncGPUReadbackPlugin.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidapu/AsyncGPUReadbackPlugin/e8d5e52a9adba24bc0f652c39076404e4671e367/ManagedPlugin/bin/Release/netstandard2.0/AsyncGPUReadbackPlugin.dll
--------------------------------------------------------------------------------
/NativePlugin/Makefile:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Linux build
4 | linux: build/libAsyncGPUReadbackPlugin.so
5 | build/libAsyncGPUReadbackPlugin.so: src/AsyncGPUReadbackPlugin.cpp
6 | g++ -fPIC -std=c++11 -shared src/AsyncGPUReadbackPlugin.cpp -o build/libAsyncGPUReadbackPlugin.so
7 |
--------------------------------------------------------------------------------
/NativePlugin/build/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidapu/AsyncGPUReadbackPlugin/e8d5e52a9adba24bc0f652c39076404e4671e367/NativePlugin/build/.gitkeep
--------------------------------------------------------------------------------
/NativePlugin/build/libAsyncGPUReadbackPlugin.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kidapu/AsyncGPUReadbackPlugin/e8d5e52a9adba24bc0f652c39076404e4671e367/NativePlugin/build/libAsyncGPUReadbackPlugin.so
--------------------------------------------------------------------------------
/NativePlugin/src/AsyncGPUReadbackPlugin.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include