77 lines
2.0 KiB
Lua
77 lines
2.0 KiB
Lua
-- Parse cmdstream dump and check for common errors
|
|
-- 1) Check for overflowing HLSQ_xS_CNTL.CONSTLEN
|
|
-- 2) Check for constant uploades that overwrite each other. The
|
|
-- range checking is reset on each draw, since it is a valid
|
|
-- use-case to do partial constant upload. But if we see two
|
|
-- CP_LOAD_STATE* that overwrite the same range of constants
|
|
-- within the same draw, that is almost certainly unintentional.
|
|
--
|
|
-- TODO add more checks
|
|
-- TODO maybe some parts could be shared across
|
|
-- different generations
|
|
|
|
--local posix = require "posix"
|
|
|
|
function printf(fmt, ...)
|
|
return io.write(string.format(fmt, ...))
|
|
end
|
|
|
|
function dbg(fmt, ...)
|
|
--printf(fmt, ...)
|
|
end
|
|
|
|
stages = {
|
|
"SB6_VS_SHADER",
|
|
"SB6_HS_SHADER",
|
|
"SB6_DS_SHADER",
|
|
"SB6_GS_SHADER",
|
|
"SB6_FS_SHADER",
|
|
"SB6_CS_SHADER",
|
|
}
|
|
|
|
-- maps shader stage to HLSQ_xS_CNTL register name:
|
|
cntl_regs = {
|
|
["SB6_VS_SHADER"] = "HLSQ_VS_CNTL",
|
|
["SB6_HS_SHADER"] = "HLSQ_HS_CNTL",
|
|
["SB6_DS_SHADER"] = "HLSQ_DS_CNTL",
|
|
["SB6_GS_SHADER"] = "HLSQ_GS_CNTL",
|
|
["SB6_FS_SHADER"] = "HLSQ_FS_CNTL",
|
|
["SB6_CS_SHADER"] = "HLSQ_CS_CNTL",
|
|
}
|
|
|
|
-- initialize constant updated ranges:
|
|
-- constranges[stagename] -> table of offsets that have been uploaded
|
|
constranges = {}
|
|
function reset_constranges()
|
|
for i,stage in ipairs(stages) do
|
|
constranges[stage] = {}
|
|
end
|
|
end
|
|
|
|
reset_constranges()
|
|
|
|
printf("Checking cmdstream...\n")
|
|
|
|
local r = rnn.init("a630")
|
|
|
|
function draw(primtype, nindx)
|
|
printf("draw!\n")
|
|
-- reset ranges of uploaded consts on each draw:
|
|
reset_constranges()
|
|
end
|
|
|
|
function CP_LOAD_STATE6(pkt, size)
|
|
if tostring(pkt[0].STATE_TYPE) ~= "ST6_CONSTANTS" then
|
|
return
|
|
end
|
|
dbg("got CP_LOAD_STATE6\n")
|
|
stage = tostring(pkt[0].STATE_BLOCK)
|
|
max = pkt[0].DST_OFF + pkt[0].NUM_UNIT
|
|
cntl_reg = cntl_regs[stage]
|
|
dbg("looking for %s.. max=%d vs %d\n", cntl_reg, max, r[cntl_reg].CONSTLEN)
|
|
if max > r[cntl_reg].CONSTLEN then
|
|
printf("ERROR: invalid max constant offset for stage %s: %d vs %d\n", stage, max, r[cntl_reg].CONSTLEN)
|
|
end
|
|
|
|
end
|