mirror of
				https://github.com/GayPizzaSpecifications/voxelotl-engine.git
				synced 2025-11-04 10:59:39 +00:00 
			
		
		
		
	use private storage for textures
This commit is contained in:
		@ -123,7 +123,7 @@ class Renderer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Create a default texture
 | 
					    // Create a default texture
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
      self.defaultTexture = try Self.loadTexture(device, image2D: Image2D(Data([
 | 
					      self.defaultTexture = try Self.loadTexture(device, queue, image2D: Image2D(Data([
 | 
				
			||||||
          0xFF, 0x00, 0xFF, 0xFF,  0x00, 0x00, 0x00, 0xFF,
 | 
					          0xFF, 0x00, 0xFF, 0xFF,  0x00, 0x00, 0x00, 0xFF,
 | 
				
			||||||
          0x00, 0x00, 0x00, 0xFF,  0xFF, 0x00, 0xFF, 0xFF
 | 
					          0x00, 0x00, 0x00, 0xFF,  0xFF, 0x00, 0xFF, 0xFF
 | 
				
			||||||
        ]), format: .abgr8888, width: 2, height: 2, stride: 2 * 4))
 | 
					        ]), format: .abgr8888, width: 2, height: 2, stride: 2 * 4))
 | 
				
			||||||
@ -133,7 +133,7 @@ class Renderer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Load texture from a file in the bundle
 | 
					    // Load texture from a file in the bundle
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
      self.cubeTexture = try Self.loadTexture(device, resourcePath: "test.png")
 | 
					      self.cubeTexture = try Self.loadTexture(device, queue, resourcePath: "test.png")
 | 
				
			||||||
    } catch RendererError.loadFailure(let message) {
 | 
					    } catch RendererError.loadFailure(let message) {
 | 
				
			||||||
      printErr("Failed to load texture image: \(message)")
 | 
					      printErr("Failed to load texture image: \(message)")
 | 
				
			||||||
    } catch {
 | 
					    } catch {
 | 
				
			||||||
@ -145,42 +145,65 @@ class Renderer {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static func loadTexture(_ device: MTLDevice, resourcePath path: String) throws -> MTLTexture {
 | 
					  static func loadTexture(_ device: MTLDevice, _ queue: MTLCommandQueue, resourcePath path: String) throws -> MTLTexture {
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
      return try loadTexture(device, url: Bundle.main.getResource(path))
 | 
					      return try loadTexture(device, queue, url: Bundle.main.getResource(path))
 | 
				
			||||||
    } catch ContentError.resourceNotFound(let message) {
 | 
					    } catch ContentError.resourceNotFound(let message) {
 | 
				
			||||||
      throw RendererError.loadFailure(message)
 | 
					      throw RendererError.loadFailure(message)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static func loadTexture(_ device: MTLDevice, url imageUrl: URL) throws -> MTLTexture {
 | 
					  static func loadTexture(_ device: MTLDevice, _ queue: MTLCommandQueue, url imageUrl: URL) throws -> MTLTexture {
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
      return try loadTexture(device, image2D: try NSImageLoader.open(url: imageUrl))
 | 
					      return try loadTexture(device, queue, image2D: try NSImageLoader.open(url: imageUrl))
 | 
				
			||||||
    } catch ImageLoaderError.openFailed(let message) {
 | 
					    } catch ImageLoaderError.openFailed(let message) {
 | 
				
			||||||
      throw RendererError.loadFailure(message)
 | 
					      throw RendererError.loadFailure(message)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static func loadTexture(_ device: MTLDevice, image2D image: Image2D) throws -> MTLTexture {
 | 
					  static func loadTexture(_ device: MTLDevice, _ queue: MTLCommandQueue, image2D image: Image2D) throws -> MTLTexture {
 | 
				
			||||||
    let texDesc = MTLTextureDescriptor()
 | 
					    let texDesc = MTLTextureDescriptor()
 | 
				
			||||||
    texDesc.width  = image.width
 | 
					    texDesc.width  = image.width
 | 
				
			||||||
    texDesc.height = image.height
 | 
					    texDesc.height = image.height
 | 
				
			||||||
    texDesc.pixelFormat = .rgba8Unorm_srgb
 | 
					    texDesc.pixelFormat = .rgba8Unorm_srgb
 | 
				
			||||||
    texDesc.textureType = .type2D
 | 
					    texDesc.textureType = .type2D
 | 
				
			||||||
    texDesc.storageMode = .managed
 | 
					    texDesc.storageMode = .private
 | 
				
			||||||
    texDesc.usage = .shaderRead
 | 
					    texDesc.usage = .shaderRead
 | 
				
			||||||
    guard let newTexture = device.makeTexture(descriptor: texDesc) else {
 | 
					    guard let newTexture = device.makeTexture(descriptor: texDesc) else {
 | 
				
			||||||
      throw RendererError.loadFailure("Failed to create texture descriptor")
 | 
					      throw RendererError.loadFailure("Failed to create texture descriptor")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    image.data.withUnsafeBytes { bytes in
 | 
					
 | 
				
			||||||
      newTexture.replace(
 | 
					    guard let texData = image.data.withUnsafeBytes({ bytes in
 | 
				
			||||||
        region: .init(
 | 
					      device.makeBuffer(bytes: bytes.baseAddress!, length: bytes.count, options: [ .storageModeShared ])
 | 
				
			||||||
          origin: .init(x: 0, y: 0, z: 0),
 | 
					    }) else {
 | 
				
			||||||
          size: .init(width: image.width, height: image.height, depth: 1)),
 | 
					      throw RendererError.loadFailure("Failed to create shared texture data buffer")
 | 
				
			||||||
        mipmapLevel: 0,
 | 
					 | 
				
			||||||
        withBytes: bytes.baseAddress!,
 | 
					 | 
				
			||||||
        bytesPerRow: image.stride)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    guard let cmdBuffer = queue.makeCommandBuffer(),
 | 
				
			||||||
 | 
					      let blitEncoder = cmdBuffer.makeBlitCommandEncoder()
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      throw RendererError.loadFailure("Failed to create blit command encoder")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    blitEncoder.copy(
 | 
				
			||||||
 | 
					      from: texData,
 | 
				
			||||||
 | 
					      sourceOffset: 0,
 | 
				
			||||||
 | 
					      sourceBytesPerRow: image.stride,
 | 
				
			||||||
 | 
					      sourceBytesPerImage: image.stride * image.height,
 | 
				
			||||||
 | 
					      sourceSize: .init(width: image.width, height: image.height, depth: 1),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      to: newTexture,
 | 
				
			||||||
 | 
					      destinationSlice: 0,
 | 
				
			||||||
 | 
					      destinationLevel: 0,
 | 
				
			||||||
 | 
					      destinationOrigin: .init(x: 0, y: 0, z: 0))
 | 
				
			||||||
 | 
					    blitEncoder.endEncoding()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cmdBuffer.addCompletedHandler { _ in
 | 
				
			||||||
 | 
					      //FIXME: look into if this needs to be synchronised
 | 
				
			||||||
 | 
					      //printErr("Texture was added?")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    cmdBuffer.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return newTexture
 | 
					    return newTexture
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user