mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-03 13:11:33 +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