Post marked as unsolved
1.2k
Views
I created two threads in my macOS app, a main thread that dispatches work every 40ms to a worker thread. This worker thread causes a memory leak. After some debugging it seems that the MTLCommandBuffer is the reason for the leak:if let commandBuffer = commandQueue.makeCommandBuffer() {
// some code here
commandBuffer.commit()
}I uncommented every code from the worker thread and there is no memory leak anymore. But when I add these lines above and create only an empty command buffer and commit it to the queue then the CPU memory will increase over time.The app is running on macOS and compiled with Xcode 10.3 (and Xcode 11 beta with the the same effect).Instruments cannot find any leaks. Persistent allocation stays constant over a long time. Only Xcode debugger shows this static memory increase. And only if I create a commandBuffer (with commands encoded or also when empty).Edit: I created a new project in Xcode with the game template and selected metal. Same effect. The debugger memory section has the same memory increase over time (nearly 0.1MB each second).
Post marked as unsolved
964
Views
Hi guys,I am working on a video application that needs realtime performance. First I used GCD but than I saw one WWDC video where the priority decay mechanism was explained.My application is quite simple. I have an external API call that waits for the next incoming video frame. So instead of using GCD I implemented a pthread which opt-out of the priority decay mechanism and set the priority very high as it was shown in the WWDC video.This dispatch thread only waits for the next frame sync and starts several worker threads using conditional flags. All the worker threads also opt-out from priority decay with the same high priority like the dispatcher. They do not much, some are encoding Metal commands, others are reading some UDP data or fetching the new video frame from the hardware board.When I used instruments I saw that all working threads has been scheduled to all available cores and blocking them all for 10ms. The UI gets unresponsive as well.Here is a short version of the code. Maybe I understand something wrong with pthreads. So please apologize if this is a silly mistake I made here in my code. GCD would be much better to use but when I watched the WWDC video it seems that there is no way to opt-out from the priority decay problem.void *dispatcherThread(void *params)
{
while( !forcedExit ) {
waitForNextFrame();
pthread_mutex_lock(&mutex);
needsCaptureFrame = true;
needsProcessFrame = true;
needsPlayoutFrame = true;
pthread_cond_broadcast(&condition);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}void *workerThreadProcessFrame(void *params)
{
while( !forcedExit ) {
pthread_mutex_lock(&mutex);
while (!needsProcessFrame && !forcedExit)
pthread_cond_wait(&condition, &mutex);
needsProcessFrame = false;
pthread_mutex_unlock(&mutex);
if (!forcedExit) {
processFrame();
}
}
pthread_exit(NULL);
}The C function processFrame itself is bound to a Swift function. This works pretty well. Only problem is that all worker threads block every 40ms all cores of the Mac for 10ms even when their Swift function returns in a few mikroseconds.Here is also the code snippet how the pthreads are created.void startThread(void * _Nullable (* _Nonnull start_routine)(void * _Nullable)) {
pthread_t thread;
pthread_attr_t attr;
int returnVal;
// create attributes with the standard values
returnVal = pthread_attr_init(&attr);
assert(!returnVal);
// set the detachstate attribute (because we don't need return values and therefor a pthread_join)
returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
assert(!returnVal);
// set the scheduling policy to round robin to avoid priority decay (this is very important!!!)
pthread_attr_setschedpolicy(&attr, SCHED_RR);
// the thread priority is set to 45 which seems to be a good value on the mac
struct sched_param param = {.sched_priority = 45};
pthread_attr_setschedparam(&attr, ¶m);
int threadError = pthread_create(&thread, &attr, start_routine, NULL);
assert(!threadError);
returnVal = pthread_attr_destroy(&attr);
assert(!returnVal);
}I would be really happy if someone has an idea why this dispath/worker mechanism does not work or if there is also a solution with GCD avoiding the priority decay problem.
Post marked as unsolved
372
Views
Is it possible to initialize the content of a stencil texture within a compute kernel function? In my case I wanted to fill zeros in the even rows and ones in the odd rows of the stencil buffer. When I use .stencil8 as a pixel format for this texture, then Xcode gives me an error that this pixel format .stencil8 has no write access for a compute function even the usage property in the texture descriptor contains the .shaderWrite flag.
Post marked as unsolved
1.3k
Views
I have a third party driver software with a lot of static libraries and a whole lot of headers. My goal is to wrap those libraries and headers into a cocoa framework, use an umbrella for all the headers that I need, and load this framework as a module into my Swift app. What I want to avoid is to copy all the headers into the public header section of the build settings. When I import the C++ headers in the framework header I get a lot of error messages "Inlcude of non-modular headers inside framework module".In the internet they say we can use the targets build settings to allow non-modular headers. But this doesn't worked either.Some background why I want to do this. Sometimes we must switch back to older versions of the driver software. So my goal is to use git branches for each version and use them to build cocoa frameworks that I can use in my Swift app.Has someone managed to build frameworks containing C++ libraries and their headers to use them within Swift projects already? I checked the internet and it seems to be not so easy as I thought.
Post marked as unsolved
378
Views
First of all I want to thank the Apple team for their good WWDC videos about CloudKit. But there is one thing where I still struggle with CloudKit. Maybe someone can give me some good best practices.It was mentioned in the WWDC video that when you send a write/modify CKOperation to the CloudKit server we won't get an updated change token. How does Apple handle the situation when they fetch new data from the server in their apps? That was missing in the WWDC videos.Let me explain it in more detail: You have locally changed objects on your device (may you add an item to a shopping list) and when you fetch the next time data from the CloudKit server (either from a push or an application launch) you will get the same data back together with modified data from other devices. How to you compare this records? I would store my local objects together with the recordIDs and compare them, but maybe there is an simpler solution.It was also mentionied in their example todo list app that they use CoreData for their persistent store. Is CoreData the way to go for caching local data from CloudKit or are codeable objects also as easy to use?
Post marked as unsolved
484
Views
I have serval depencies (frameworks) consisting of either pure Swift or C code. With CocoaPods I can create frameworks that my main apps can link to. My main apps are macOS Cocoa Xcode workspaces containing the executable project and a playground for testing.Is it possible to switch to Swift package manager when you have such existing Xcode workspaces and load/update the depencies which were build with the swift package manager?I found many articles in the internet but all seems to be based on server side applications. The question is, is it possible to use an existing Cocoa project (workspace) and link dependencies as swift package mananager modules to it?Sorry if this questions is maybe ******, but I really havent found a good tutorial in the internet yet. I know CocoaPods (and also Carthage) right well but have no idea how to switch to Swift Package Manager or if this is even possible for Cocoa apps when the directory structure (Xcode->New Project) already exists.
Post marked as unsolved
430
Views
Is it possible to have several .metal files in you Xcode project that includes not only the standard libraries but also custom include files with C++ functions or common definitions that are used by your shaders? I have some inline functions that I don't want to copy to all the other .metal files that needs them also.
Post marked as unsolved
878
Views
The setTexture() method of a MTLComputeCommandEncoder allows us to use nil as a parameter.How can I check in the kernel function if the texture parameter is nil or not?In the documentation I see there is a function called 'is_null_texture'. But the compiler does not know this function. I included already all the header files like <metal_stdlib>, <metal_texture>, <metal_relational>, <metal_common> hoping this would solve the problem.Is this function maybe wrong in the documentation and has another syntax or does it not exist?
Post marked as unsolved
329
Views
We are working with interlaced HD video. The metal color attachment I use for rendering has the dimensions of one field (1920*540 RGBA).When I want to copy the two rendered fields into a MTLBuffer that has the size of 1920*1080*4 = 8294400 bytes I use the following code... let commandBuffer = commandQueue.makeCommandBuffer()
let blitEncoder = commandBuffer.makeBlitCommandEncoder()
blitEncoder.copy(from: attachmentTexture,
sourceSlice: 0,
sourceLevel: 0,
sourceOrigin: MTLOriginMake(0, 0, 0),
sourceSize: MTLSizeMake(attachmentTexture.width, attachmentTexture.height, 1),
to: destinationBuffer,
destinationOffset: 1920*4,
destinationBytesPerRow: 1920*4*2,
destinationBytesPerImage: destinationBuffer.length)
blitEncoder.endEncoding()
commandBuffer.commit()For the first field where the destination offset is zero the function works well. The destination buffer is filled for every second row.But when I want to write the second field with the same code into the buffer only with the destinationOffset set to 1920*4 like you see above (to start with the second row in the buffer) then I get an assertion like this:-[MTLDebugBlitCommandEncoder validateCopyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toBuffer:destinationOffset:destinationBytesPerRow:destinationBytesPerImage:options:]:677: failed assertion `totalBytesUsed(8302080) must be <= [destinationBuffer length](8294400).'The totalBytesUsed are exactly the destination buffer length in bytes plus the offset. So every offset I use in this function will result in this assertion error.Can someone explain me what I am doing wrong with this function?
Post marked as unsolved
398
Views
Lets assume you want to convert a simple rgb texture into a b/w texture. This should be only an example so please ignore the fact that there are of cause other techniques for this simple task.method 1: render encoderYou can render two triangles with texture mapping and implement the fragment shader so that it converts the pixel values to b/w and write it to another render buffer. That works well.method 2: compute encodersHere I use the same function like in the previous fragment shader as a kernel function and read/write the pixel values directly from one texture to another. This works also.I was surprised that the compute encoder is much slower in my tests than the render encoder. I thought that because there is no vertex computation and rasterization involved the compute encoder should provide better performance.For an simple image manipulation task like above that doesn't need the information of the surrounding pixels, is it here better to use fragment shaders instead of kernel functions?
Post marked as unsolved
232
Views
I know that OS X is not a realtime OS. But if I measure the execution time of a block of OpenGL commands between two glFinish commands I would expect that the time is nearly the same.glFinishstart = current timesome OpenGL commands that are not CPU boundglFinishend = current timeexecution time = end - startOn our current hardware platform this give a good time measurement. On the Mac I have mostly the same execution times (e.g. 1ms) but then some peaks (up to 15ms). The code is running on a own dispatch queue with qos level set to user-interactive.Can someone explain me why we get these strange performance peaks. There are no disk operations or other time critical things in the OpenGL block.
Post marked as unsolved
204
Views
Is there a way to set the process and GPU priority to a maximum value to avoid side effects from other processes? We developed an live image video processing application for tv video streams on linux PCs and our goal is to use the new Mac Pro for the next version. The processing time is should not be larger than 12-14ms. At the moment I see a lot of variations in the execution time even the code for the CPU or GPU does the same (e.g. clearing the background with OpenGL or modifying pixels for the whole screen with the same comand).
Post marked as unsolved
403
Views
I have a strange behaviour with the NSOpenGLView reshape method. Maybe someone can help me.As you can see I draw a simple rectangle without a matrix directly in the -1..1, -1..1 coordinate system. The fragment shader only sets the color white and the vertex shader the position without any modifications.When I resize the window I adjust the viewport in the reshape method as you can see below. In the second screenshot you see that the viewport changes are now succesfull but there is a clipping at the right edge even clipping is not enabled. It becomes more strange when I resize the window in the vertical direction (3rd screenshot). Here the triangle changes its size in the correct way but the whole viewport seems to shift in the vertical position and does not start at window coordinate (0,0) anymore. override func reshape() {
glViewport(0, 0, GLsizei(frame.size.width), GLsizei(frame.size.height))
}The NSOpenGLView has been positioned in the window with edge constraints. The frame dimension changes are correct. Also clearing the background works for the whole screen area (black background).http://i.imgur.com/cG3Cljk.pnghttp://i.imgur.com/ljUOy2c.pnghttp://i.imgur.com/MKyak53.png