static #cpuBuffer: GPUBuffer
static #uboBuffer: GPUBuffer
static #uboView: DataView
+ static #resultView: DataView
static #bindGroupLayout: GPUBindGroupLayout
static #searchPipeline: GPUComputePipeline
static #validatePipeline: GPUComputePipeline
console.table(averages)
}
- static async #dispatch (pipeline: GPUComputePipeline, seed: bigint, hash: string, difficulty: bigint, passes: number): Promise<DataView> {
+ static async #dispatch (pipeline: GPUComputePipeline, seed: bigint, hash: string, difficulty: bigint, passes: number): Promise<void> {
if (this.#device == null) throw new Error(`WebGPU device failed to load.`)
// Set up uniform buffer object
// Note: u32 size is 4, but total alignment must be multiple of 16
this.#device.queue.submit([commandEncoder.finish()])
// Read results back to Javascript and then unmap buffer after reading
- let data = null
try {
await this.#cpuBuffer.mapAsync(GPUMapMode.READ)
await this.#device.queue.onSubmittedWorkDone()
- data = new DataView(this.#cpuBuffer.getMappedRange().slice(0))
+ this.#resultView = new DataView(this.#cpuBuffer.getMappedRange().slice(0))
this.#cpuBuffer.unmap()
} catch (err) {
console.warn(`Error getting data from GPU. ${err}`)
this.#cpuBuffer.unmap()
this.reset()
}
- if (this.#debug) console.log('gpuBuffer data', data)
- if (data == null) throw new Error(`Failed to get data from buffer.`)
- return data
+ if (this.#debug) console.log('gpuBuffer data', this.#resultView)
+ if (this.#resultView == null) throw new Error(`Failed to get data from buffer.`)
}
/**
const random1 = Math.floor(Math.random() * 0xffffffff)
const seed = (BigInt(random0) << 32n) | BigInt(random1)
if (this.#debug) console.log('seed', seed.toString(16).padStart(16, '0'))
- const data = await this.#dispatch(this.#searchPipeline, seed, hash, difficulty, effort)
- const found = !!data.getUint32(0)
- nonce = data.getBigUint64(8, true)
- result = data.getBigUint64(16, true)
+ await this.#dispatch(this.#searchPipeline, seed, hash, difficulty, effort)
+ const found = !!this.#resultView.getUint32(0)
+ nonce = this.#resultView.getBigUint64(8, true)
+ result = this.#resultView.getBigUint64(16, true)
this.#busy = !found
times.push(performance.now() - start)
} while (this.#busy)
const seed = BigInt(`0x${work}`)
if (this.#debug) console.log('work', work)
- const data = await this.#dispatch(this.#validatePipeline, seed, hash, difficulty, 1)
- nonce = data.getBigUint64(8, true)
- result = data.getBigUint64(16, true)
+ await this.#dispatch(this.#validatePipeline, seed, hash, difficulty, 1)
+ nonce = this.#resultView.getBigUint64(8, true)
+ result = this.#resultView.getBigUint64(16, true)
this.#busy = false
if (this.#debug) console.log('nonce', nonce, nonce.toString(16).padStart(16, '0'))
if (this.#debug) console.log('result', result, result.toString(16).padStart(16, '0'))