redo texture uploading

This commit is contained in:
Gregory Wells
2025-08-04 09:46:26 -04:00
parent 14b1dc0fdf
commit 6f536531d0
3 changed files with 63 additions and 10 deletions

View File

@@ -13,6 +13,8 @@ gnReturnCode createMetalOutputDevice(gnInstanceHandle instance, gnOutputDeviceHa
outputDevice->outputDevice->device = deviceInfo.physicalDevice->physicalDevice->device.retain; outputDevice->outputDevice->device = deviceInfo.physicalDevice->physicalDevice->device.retain;
outputDevice->outputDevice->transferQueue = outputDevice->outputDevice->device.newCommandQueue; outputDevice->outputDevice->transferQueue = outputDevice->outputDevice->device.newCommandQueue;
outputDevice->outputDevice->stagingBuffer = [outputDevice->outputDevice->device newBufferWithLength:(128 * 1024 * 1024) options:MTLResourceStorageModeShared];
// create full screen quad // create full screen quad
float verticies[] = { float verticies[] = {
-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f,

View File

@@ -15,6 +15,8 @@ struct gnPlatformOutputDevice_t {
id<MTLCommandBuffer> executingCommandBuffer; id<MTLCommandBuffer> executingCommandBuffer;
id<MTLCommandQueue> transferQueue; id<MTLCommandQueue> transferQueue;
id<MTLBuffer> stagingBuffer;
id<MTLBuffer> fullScreenQuadBuffer; id<MTLBuffer> fullScreenQuadBuffer;
id<MTLLibrary> fullScreenShader; id<MTLLibrary> fullScreenShader;
id<MTLFunction> fullScreenVertex, fullScreenFragment; id<MTLFunction> fullScreenVertex, fullScreenFragment;

View File

@@ -18,7 +18,7 @@ gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnText
MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init]; MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];
textureDescriptor.sampleCount = mtlSampleCount(info.samples); textureDescriptor.sampleCount = mtlSampleCount(info.samples);
textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
textureDescriptor.storageMode = MTLStorageModeShared; // Most efficient for GPU-only textures textureDescriptor.storageMode = MTLStorageModePrivate;
textureDescriptor.depth = info.extent.depth; textureDescriptor.depth = info.extent.depth;
textureDescriptor.width = info.extent.width; textureDescriptor.width = info.extent.width;
textureDescriptor.height = info.extent.height; textureDescriptor.height = info.extent.height;
@@ -45,16 +45,65 @@ gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnText
} }
void metalTextureData(gnTextureHandle texture, void* pixelData) { void metalTextureData(gnTextureHandle texture, void* pixelData) {
MTLRegion region = { NSUInteger fullBytesPerRow = 4 * texture->info.extent.width;
{ 0, 0, 0 }, id<MTLBuffer> stagingBuffer = [texture->device->outputDevice->stagingBuffer retain];
{texture->info.extent.width, texture->info.extent.height, texture->info.extent.depth} NSUInteger maxRowsPerChunk = stagingBuffer.length / fullBytesPerRow;
}; if (maxRowsPerChunk == 0) maxRowsPerChunk = 1;
NSUInteger yOffset = 0;
while (yOffset < texture->info.extent.height) {
NSUInteger rowsThisChunk = MIN(maxRowsPerChunk, texture->info.extent.height - yOffset);
NSUInteger chunkSize = rowsThisChunk * fullBytesPerRow;
// Copy chunk of pixel data into staging buffer
memcpy(stagingBuffer.contents, (uint8_t*)pixelData + yOffset * fullBytesPerRow, chunkSize);
id<MTLCommandBuffer> cmd = [texture->device->outputDevice->transferQueue commandBuffer];
id<MTLBlitCommandEncoder> blitEncoder = [cmd blitCommandEncoder];
MTLOrigin origin = { 0, (NSUInteger)yOffset, 0 };
MTLSize size = { (NSUInteger)texture->info.extent.width, (NSUInteger)rowsThisChunk, 1 };
[blitEncoder copyFromBuffer:stagingBuffer
sourceOffset:0
sourceBytesPerRow:fullBytesPerRow
sourceBytesPerImage:chunkSize
sourceSize:size
toTexture:texture->texture->texture
destinationSlice:0
destinationLevel:0
destinationOrigin:origin];
[blitEncoder endEncoding];
[cmd commit];
yOffset += rowsThisChunk;
}
[stagingBuffer release];
// NSUInteger chunkSize = texture->device->outputDevice->stagingBuffer.length;
// NSUInteger totalSize = texture->info.extent.width * texture->info.extent.height * texture->info.extent.depth * 4;
// NSUInteger offset = 0;
// while (offset < totalSize) {
// NSUInteger sizeToCopy = MIN(chunkSize, totalSize - offset);
// memcpy(texture->device->outputDevice->stagingBuffer.contents, (char*)pixelData + offset, sizeToCopy);
// id<MTLCommandBuffer> transfer = [texture->device->outputDevice->transferQueue commandBuffer];
// id<MTLBlitCommandEncoder> blit = [transfer blitCommandEncoder];
// [blit copyFromBuffer:texture->device->outputDevice->stagingBuffer
// sourceOffset:0
// toTexture:gpuBuffer
// destinationOffset:offset
// size:sizeToCopy];
// [blit endEncoding];
// [transfer commit];
// offset += sizeToCopy;
// }
NSUInteger bytesPerRow = 4 * texture->info.extent.width; // TODO: fix this should not be set to 4
[texture->texture->texture replaceRegion:region
mipmapLevel:0
withBytes:pixelData
bytesPerRow:bytesPerRow];
} }
void metalDestroyTexture(gnTexture texture) { void metalDestroyTexture(gnTexture texture) {