OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / _probe_cloud_quality_cost.gd

102 lines · gd ref:
extends SceneTree
## Probe: what each SunshineClouds2 resolution_scale costs with the MOUNTAIN's real
## cloud resource (scenes/maps/mountain_clouds.tres, which leaves resolution_scale at
## the default 1 = Half). Feeds the Low / Medium / High presets (#93 §2): Medium needs
## a cloud tier between "off" and what High ships.
##
## Viewport GPU render time, median + p90 over WINDOW frames per tier, after SETTLE
## frames for the temporal accumulation and buffer rebuild. Needs a display:
##   "$HYPER_TPS_GODOT" --path . --script res://scenes/test/_probe_cloud_quality_cost.gd

const ProbeWindow := preload("res://scenes/test/probe_window.gd")
const SIZE := Vector2i(1600, 900)
const SETTLE := 90
const WINDOW := 150
## [label, enabled, resolution_scale]
const TIERS := [
	["off", false, 1], ["native", true, 0], ["half", true, 1],
	["quarter", true, 2], ["eighth", true, 3], ["half_again", true, 1],
]

var _ws := ""
var _next_i3 := 0
var _ready_frames := 0
var _vp_rid: RID
var _fx: CompositorEffect
var _tier := -1
var _n := 0
var _samples: Array = []
var _results: Array = []


func _initialize() -> void:
	DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
	DisplayServer.window_set_size(SIZE)
	DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
	_ws = ProbeWindow.free_workspace()
	print("PROBE i3 workspace: %s" % (_ws if _ws != "" else "(none)"))
	var env := Environment.new()
	env.background_mode = Environment.BG_SKY
	env.sky = Sky.new()
	env.sky.sky_material = ProceduralSkyMaterial.new()
	var we := WorldEnvironment.new()
	we.environment = env
	we.compositor = Compositor.new()
	_fx = (load("res://scenes/maps/mountain_clouds.tres") as CompositorEffect).duplicate()
	var fx: Array[CompositorEffect] = [_fx]
	we.compositor.compositor_effects = fx
	root.add_child(we)
	var sun := DirectionalLight3D.new()
	sun.rotation_degrees = Vector3(-35, 30, 0)
	root.add_child(sun)
	# Below the deck (floor 650, ceiling 1450), looking up into it: the view a player
	# on the mountain has, and the one that marches the most cloud.
	var cam := Camera3D.new()
	cam.position = Vector3(0, 300, 0)
	cam.rotation_degrees = Vector3(20, 0, 0)
	cam.far = 40000
	root.add_child(cam)
	cam.make_current()
	_vp_rid = root.get_viewport_rid()
	RenderingServer.viewport_set_measure_render_time(_vp_rid, true)


func _set_tier(i: int) -> void:
	_tier = i
	_n = 0
	_samples = []
	_fx.enabled = bool(TIERS[i][1])
	_fx.set("resolution_scale", int(TIERS[i][2]))


func _process(_d: float) -> bool:
	if _ready_frames < 20:
		if _ws != "" and _ready_frames == 0 and Time.get_ticks_msec() >= _next_i3:
			_next_i3 = Time.get_ticks_msec() + 1000
			ProbeWindow.move_to(_ws, SIZE)
		if ProbeWindow.drawing(root):
			_ready_frames += 1
		elif Time.get_ticks_msec() > 30000:
			print("PROBE FAIL window never drew (size %s)" % root.size)
			quit(1)
			return true
		return false
	if _tier < 0:
		_set_tier(0)
		return false
	_n += 1
	if _n > SETTLE:
		_samples.append(RenderingServer.viewport_get_measured_render_time_gpu(_vp_rid))
	if _n >= SETTLE + WINDOW:
		_samples.sort()
		var med: float = _samples[_samples.size() / 2]
		var p90: float = _samples[int(_samples.size() * 0.9)]
		_results.append([TIERS[_tier][0], med, p90])
		print("PROBE clouds %-10s GPU ms median %6.2f p90 %6.2f (n=%d)" % [TIERS[_tier][0], med, p90, _samples.size()])
		if _tier + 1 < TIERS.size():
			_set_tier(_tier + 1)
		else:
			print("PROBE size %s adapter: %s" % [root.size, RenderingServer.get_video_adapter_name()])
			return true
	return false