mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-09 07:15:11 -04:00
gpu budget cleanup - made the vram bitblt budget and energy cost far more reasonable and logical
note: dirty page bitblts to a screen are increasinly expensive for larger buffers bitblts to vram are "free" (no budget, no energy) note that any direct component call has a minimum .001 budget cost
This commit is contained in:
parent
efe6cbc1e7
commit
fabe7bac43
@ -70,7 +70,7 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI
|
||||
final val setCosts = Array(1.0 / 64, 1.0 / 128, 1.0 / 256)
|
||||
final val copyCosts = Array(1.0 / 16, 1.0 / 32, 1.0 / 64)
|
||||
final val fillCosts = Array(1.0 / 32, 1.0 / 64, 1.0 / 128)
|
||||
final val bitbltCosts = Array(2.0, 1.0, 1.0 / 2.0)
|
||||
final val bitbltCosts = Array(32, 16, 8)
|
||||
final val totalVRAM: Int = (maxResolution._1 * maxResolution._2) * Settings.get.vramSizes(0 max tier min Settings.get.vramSizes.length)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -189,6 +189,29 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI
|
||||
screen(idx, s => result(s.getWidth, s.getHeight))
|
||||
}
|
||||
|
||||
private def determineBitbltBudgetCost(dst: api.internal.TextBuffer, src: api.internal.TextBuffer): Double = {
|
||||
// large dirty buffers need throttling so their budget cost is more
|
||||
// clean buffers have no budget cost.
|
||||
src match {
|
||||
case page: GpuTextBuffer if page.dirty => dst match {
|
||||
case _: GpuTextBuffer => 0.0 // no cost to write to ram
|
||||
case _ => // screen target will need the new buffer
|
||||
// small buffers are cheap, so increase with size of buffer source
|
||||
bitbltCosts(tier) * (src.getWidth * src.getHeight) / (maxResolution._1 * maxResolution._2)
|
||||
}
|
||||
case _ => 0.0 // from screen or from clean buffer is free
|
||||
}
|
||||
}
|
||||
|
||||
private def determineBitbltEnergyCost(dst: api.internal.TextBuffer): Double = {
|
||||
// memory to memory copies are extremely energy efficient
|
||||
// rasterizing to the screen has the same cost as copy (in fact, screen-to-screen blt _is_ a copy
|
||||
dst match {
|
||||
case _: GpuTextBuffer => 0
|
||||
case _ => Settings.get.gpuCopyCost / (maxResolution._1 * maxResolution._2)
|
||||
}
|
||||
}
|
||||
|
||||
@Callback(direct = true, doc = """function([dst: number, col: number, row: number, width: number, height: number, src: number, fromCol: number, fromRow: number]):boolean -- bitblt from buffer to screen. All parameters are optional. Writes to `dst` page in rectangle `x, y, width, height`, defaults to the bound screen and its viewport. Reads data from `src` page at `fx, fy`, default is the active page from position 1, 1""")
|
||||
def bitblt(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val dstIdx = args.optInteger(0, RESERVED_SCREEN_INDEX)
|
||||
@ -201,13 +224,11 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI
|
||||
screen(srcIdx, src => {
|
||||
val fromCol = args.optInteger(6, 1)
|
||||
val fromRow = args.optInteger(7, 1)
|
||||
// if src is vram and dirty, bltbit cost is large
|
||||
val dirtyPage = src match {
|
||||
case vram: GpuTextBuffer => vram.dirty
|
||||
case _ => false
|
||||
}
|
||||
|
||||
if (consumeViewportPower(dst, context, if (dirtyPage) bitbltCosts(tier) else setCosts(tier), w * h, Settings.get.gpuCopyCost)) {
|
||||
val budgetCost: Double = determineBitbltBudgetCost(dst, src)
|
||||
val energyCost: Double = determineBitbltEnergyCost(dst)
|
||||
|
||||
if (consumeViewportPower(dst, context, budgetCost, w * h, energyCost)) {
|
||||
if (dstIdx == srcIdx) {
|
||||
val tx = col - fromCol
|
||||
val ty = row - fromRow
|
||||
|
Loading…
x
Reference in New Issue
Block a user