public AsyncTextureReader(RenderTexture texture) { Status = AsyncTextureReaderStatus.Idle; Texture = texture; // WARNING - if you change this, you'll need to update code below Debug.Assert( texture.format == RenderTextureFormat.ARGBFloat || texture.format == RenderTextureFormat.RGFloat || texture.format == RenderTextureFormat.RFloat || texture.format == RenderTextureFormat.ARGB32); Debug.Assert(texture.dimension == TextureDimension.Tex2D); var sync = System.Environment.GetEnvironmentVariable("FORCE_SYNC_GPU_READBACK"); if (sync == null) { if (SystemInfo.supportsAsyncGPUReadback) { int length; Type = ReadType.Native; if (texture.format == RenderTextureFormat.ARGBFloat) { BytesPerPixel = 16; NativeReadFormat = TextureFormat.RGBAFloat; length = Texture.width * Texture.height; } else if (texture.format == RenderTextureFormat.RGFloat) { BytesPerPixel = 8; NativeReadFormat = TextureFormat.RGFloat; length = Texture.width * Texture.height; } else if (texture.format == RenderTextureFormat.RFloat) { BytesPerPixel = 4; NativeReadFormat = TextureFormat.RFloat; length = Texture.width * Texture.height; } else // if (texture.format == RenderTextureFormat.ARGB32) { BytesPerPixel = 3; NativeReadFormat = TextureFormat.RGB24; length = Texture.width * Texture.height * BytesPerPixel; } Data = new NativeArray <T>(length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); return; } if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLCore && SystemInfo.operatingSystemFamily == OperatingSystemFamily.Linux) { var version = SystemInfo.graphicsDeviceVersion; version = version.Split(new char[] { ' ' }, 3)[1]; var parts = version.Split(new char[] { '.' }); int major = int.Parse(parts[0]); int minor = int.Parse(parts[1]); //Debug.Log($"OpenGL version = {major}.{minor}"); if (major > 3 || major == 3 && minor >= 2) // GL_ARB_sync { debug = new DebugDelegate(DebugCallback); AsyncTextureReaderImports.AsyncTextureReaderSetDebug(Marshal.GetFunctionPointerForDelegate(debug)); int length; if (texture.format == RenderTextureFormat.ARGBFloat) { BytesPerPixel = 16; length = Texture.width * Texture.height; } else if (texture.format == RenderTextureFormat.RGFloat) { BytesPerPixel = 8; length = Texture.width * Texture.height; } else if (texture.format == RenderTextureFormat.RFloat) { BytesPerPixel = 4; length = Texture.width * Texture.height; } else // if (texture.format == RenderTextureFormat.ARGB32) { BytesPerPixel = 4; length = Texture.width * Texture.height * BytesPerPixel; } texture.Create(); Data = new NativeArray <T>(length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); LinuxId = AsyncTextureReaderImports.AsyncTextureReaderCreate(texture.GetNativeTexturePtr(), Data.Length); if (LinuxId >= 0) { LinuxUpdate = AsyncTextureReaderImports.AsyncTextureReaderGetUpdate(); GL.IssuePluginEvent(LinuxUpdate, LinuxId); Type = ReadType.LinuxOpenGL; } else { Debug.Log("ERROR: failed to create native AsyncTextureReader"); } return; } } } if (texture.format != RenderTextureFormat.ARGB32) { Debug.Log("ERROR: fallback AsyncTextureReader supports only ARGB32 texture format"); Type = ReadType.None; return; } Type = ReadType.Sync; BytesPerPixel = 3; Data = new NativeArray <T>(texture.width * texture.height * BytesPerPixel, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); ReadTexture = new Texture2D(texture.width, texture.height, TextureFormat.RGB24, false); }
public AsyncTextureReader(RenderTexture texture) { Status = AsyncTextureReaderStatus.Idle; Texture = texture; // WARNING - if you change this, you'll need to update code below Debug.Assert( texture.format == RenderTextureFormat.ARGBFloat || texture.format == RenderTextureFormat.RGFloat || texture.format == RenderTextureFormat.RFloat || texture.format == RenderTextureFormat.ARGB32); Debug.Assert(texture.dimension == TextureDimension.Tex2D); var sync = System.Environment.GetEnvironmentVariable("FORCE_SYNC_GPU_READBACK"); if (sync == null) { if (SystemInfo.supportsAsyncGPUReadback) { Type = ReadType.Native; if (texture.format == RenderTextureFormat.ARGBFloat) { BytesPerPixel = 16; NativeReadFormat = TextureFormat.RGBAFloat; ElementCount = Texture.width * Texture.height; SizeInBytes = ElementCount * BytesPerPixel; } else if (texture.format == RenderTextureFormat.RGFloat) { BytesPerPixel = 8; NativeReadFormat = TextureFormat.RGFloat; ElementCount = Texture.width * Texture.height; SizeInBytes = ElementCount * BytesPerPixel; } else if (texture.format == RenderTextureFormat.RFloat) { BytesPerPixel = 4; NativeReadFormat = TextureFormat.RFloat; ElementCount = Texture.width * Texture.height; SizeInBytes = ElementCount * BytesPerPixel; } else // if (texture.format == RenderTextureFormat.ARGB32) { BytesPerPixel = 3; NativeReadFormat = TextureFormat.RGB24; ElementCount = Texture.width * Texture.height * BytesPerPixel; SizeInBytes = ElementCount; } Data = new T[ElementCount]; return; } if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLCore && SystemInfo.operatingSystemFamily == OperatingSystemFamily.Linux) { var version = SystemInfo.graphicsDeviceVersion; version = version.Split(new char[] { ' ' }, 3)[1]; var parts = version.Split(new char[] { '.' }); int major = int.Parse(parts[0]); int minor = int.Parse(parts[1]); //Debug.Log($"OpenGL version = {major}.{minor}"); // OpenGL extensions required: // ARB_buffer_storage (from 4.4) // ARB_shader_image_load_store (from 4.2) // ARB_sync (from 3.2) if (major > 4 || major == 4 && minor >= 4) { debug = new DebugDelegate(DebugCallback); AsyncTextureReaderImports.AsyncTextureReaderSetDebug(Marshal.GetFunctionPointerForDelegate(debug)); if (texture.format == RenderTextureFormat.ARGBFloat) { BytesPerPixel = 16; ElementCount = Texture.width * Texture.height; SizeInBytes = ElementCount * BytesPerPixel; } else if (texture.format == RenderTextureFormat.RGFloat) { BytesPerPixel = 8; ElementCount = Texture.width * Texture.height; SizeInBytes = ElementCount * BytesPerPixel; } else if (texture.format == RenderTextureFormat.RFloat) { BytesPerPixel = 4; ElementCount = Texture.width * Texture.height; SizeInBytes = ElementCount * BytesPerPixel; } else // if (texture.format == RenderTextureFormat.ARGB32) { BytesPerPixel = 4; ElementCount = Texture.width * Texture.height * BytesPerPixel; SizeInBytes = ElementCount; } Data = new T[ElementCount]; texture.Create(); LinuxId = AsyncTextureReaderImports.AsyncTextureReaderCreate(texture.GetNativeTexturePtr(), SizeInBytes); if (LinuxId >= 0) { LinuxUpdate = AsyncTextureReaderImports.AsyncTextureReaderGetUpdate(); GL.IssuePluginEvent(LinuxUpdate, LinuxId); Type = ReadType.LinuxOpenGL; } else { Debug.Log("ERROR: failed to create native AsyncTextureReader"); } return; } } } if (texture.format != RenderTextureFormat.ARGB32) { Debug.Log("ERROR: fallback AsyncTextureReader supports only ARGB32 texture format"); Type = ReadType.None; return; } Type = ReadType.Sync; BytesPerPixel = 3; ElementCount = Texture.width * Texture.height * BytesPerPixel; SizeInBytes = ElementCount; Data = new T[ElementCount]; ReadTexture = new Texture2D(texture.width, texture.height, TextureFormat.RGB24, false); }