1bf215546Sopenharmony_ci-- Parse cmdstream dump and check for common errors
2bf215546Sopenharmony_ci--  1) Check for overflowing HLSQ_xS_CNTL.CONSTLEN
3bf215546Sopenharmony_ci--  2) Check for constant uploades that overwrite each other.  The
4bf215546Sopenharmony_ci--     range checking is reset on  each draw, since it is a valid
5bf215546Sopenharmony_ci--     use-case to do partial constant upload.  But if we see two
6bf215546Sopenharmony_ci--     CP_LOAD_STATE* that overwrite the same range of constants
7bf215546Sopenharmony_ci--     within the same draw, that is almost certainly unintentional.
8bf215546Sopenharmony_ci--
9bf215546Sopenharmony_ci-- TODO add more checks
10bf215546Sopenharmony_ci-- TODO maybe some parts could be shared across
11bf215546Sopenharmony_ci--      different generations
12bf215546Sopenharmony_ci
13bf215546Sopenharmony_ci--local posix = require "posix"
14bf215546Sopenharmony_ci
15bf215546Sopenharmony_cifunction printf(fmt, ...)
16bf215546Sopenharmony_ci	return io.write(string.format(fmt, ...))
17bf215546Sopenharmony_ciend
18bf215546Sopenharmony_ci
19bf215546Sopenharmony_cifunction dbg(fmt, ...)
20bf215546Sopenharmony_ci	--printf(fmt, ...)
21bf215546Sopenharmony_ciend
22bf215546Sopenharmony_ci
23bf215546Sopenharmony_cistages = {
24bf215546Sopenharmony_ci	"SB6_VS_SHADER",
25bf215546Sopenharmony_ci	"SB6_HS_SHADER",
26bf215546Sopenharmony_ci	"SB6_DS_SHADER",
27bf215546Sopenharmony_ci	"SB6_GS_SHADER",
28bf215546Sopenharmony_ci	"SB6_FS_SHADER",
29bf215546Sopenharmony_ci	"SB6_CS_SHADER",
30bf215546Sopenharmony_ci}
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci-- maps shader stage to HLSQ_xS_CNTL register name:
33bf215546Sopenharmony_cicntl_regs = {
34bf215546Sopenharmony_ci	["SB6_VS_SHADER"] = "HLSQ_VS_CNTL",
35bf215546Sopenharmony_ci	["SB6_HS_SHADER"] = "HLSQ_HS_CNTL",
36bf215546Sopenharmony_ci	["SB6_DS_SHADER"] = "HLSQ_DS_CNTL",
37bf215546Sopenharmony_ci	["SB6_GS_SHADER"] = "HLSQ_GS_CNTL",
38bf215546Sopenharmony_ci	["SB6_FS_SHADER"] = "HLSQ_FS_CNTL",
39bf215546Sopenharmony_ci	["SB6_CS_SHADER"] = "HLSQ_CS_CNTL",
40bf215546Sopenharmony_ci}
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci-- initialize constant updated ranges:
43bf215546Sopenharmony_ci--   constranges[stagename] -> table of offsets that have been uploaded
44bf215546Sopenharmony_ciconstranges = {}
45bf215546Sopenharmony_cifunction reset_constranges()
46bf215546Sopenharmony_ci	for i,stage in ipairs(stages) do
47bf215546Sopenharmony_ci		constranges[stage] = {}
48bf215546Sopenharmony_ci	end
49bf215546Sopenharmony_ciend
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_cireset_constranges()
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ciprintf("Checking cmdstream...\n")
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_cilocal r = rnn.init("a630")
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_cifunction draw(primtype, nindx)
58bf215546Sopenharmony_ci	printf("draw!\n")
59bf215546Sopenharmony_ci	-- reset ranges of uploaded consts on each draw:
60bf215546Sopenharmony_ci	reset_constranges()
61bf215546Sopenharmony_ciend
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_cifunction CP_LOAD_STATE6(pkt, size)
64bf215546Sopenharmony_ci	if tostring(pkt[0].STATE_TYPE) ~= "ST6_CONSTANTS" then
65bf215546Sopenharmony_ci		return
66bf215546Sopenharmony_ci	end
67bf215546Sopenharmony_ci	dbg("got CP_LOAD_STATE6\n")
68bf215546Sopenharmony_ci	stage = tostring(pkt[0].STATE_BLOCK)
69bf215546Sopenharmony_ci	max = pkt[0].DST_OFF + pkt[0].NUM_UNIT
70bf215546Sopenharmony_ci	cntl_reg = cntl_regs[stage]
71bf215546Sopenharmony_ci	dbg("looking for %s.. max=%d vs %d\n", cntl_reg, max, r[cntl_reg].CONSTLEN)
72bf215546Sopenharmony_ci	if max > r[cntl_reg].CONSTLEN then
73bf215546Sopenharmony_ci		printf("ERROR: invalid max constant offset for stage %s: %d vs %d\n", stage, max, r[cntl_reg].CONSTLEN)
74bf215546Sopenharmony_ci	end
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ciend
77