Skip to main content

Crate d3d9_reader

Crate d3d9_reader 

Source
Expand description

A reader of Direct3D 9 shader bytecode: the token stream a Direct3D 9 compiler or assembler writes for a vertex or pixel program of Shader Model 1.x, 2.x or 3.0, from its version token to END, with no container around it.

read decodes the stream into typed records in stream order (Program::items): every comment, every declaration (dcl), every literal definition (def, defi, defb) and every instruction with its opcode, control bits, co-issue and predicate, destination (register, write mask, saturate, partial precision, centroid, the pixel 1.x result shift) and sources (register, swizzle, modifier, relative address). The CTAB comment D3DX writes is decoded as well (ConstantTable), and so is the DBUG comment of a /Zi build (DebugInfo). frame reads the first program of a buffer that holds more after it.

It reads and checks bytes and never interprets them for an API: registers are Direct3D’s register types and numbers, modifiers and usages Direct3D’s own values. Whatever the format does not define (an opcode outside the instruction set of the program’s version, a register type it has no name for, a reserved bit set, an instruction whose length disagrees with its operands) is an Error naming the 32-bit word where it is; it never panics on untrusted input.

// ps_2_0: dcl t0.xy; dcl_2d s0; texld r0, t0, s0; mov oC0, r0; end
let words: [u32; 14] = [
    0xffff_0200,
    0x0200_001f, 0x8000_0000, 0xb003_0000,
    0x0200_001f, 0x9000_0000, 0xa00f_0800,
    0x0300_0042, 0x800f_0000, 0xb0e4_0000, 0xa0e4_0800,
    0x0200_0001, 0x800f_0800, 0x80e4_0000,
];
let bytes: Vec<u8> = words.iter().chain(&[0xffff]).flat_map(|w| w.to_le_bytes()).collect();
let program = d3d9_reader::read(&bytes)?;
assert_eq!(program.version.to_string(), "ps_2_0");
assert_eq!(program.declarations().count(), 2);
let names: Vec<_> = program.instructions().map(|i| i.opcode.name()).collect();
assert_eq!(names, ["tex", "mov"]);

Structs§

Comment
A comment: its words, without its token. The constant table is one, its first word the FourCC CTAB.
Constant
A named allocation, including the original type even when optimization shortened its register range.
ConstantTable
The constant table (CTAB comment) of a program: who compiled it, for which target, and the named register allocations.
DebugInfo
The DBUG comment decoded.
Declaration
A dcl: the declaration token and the register declared.
Definition
A def, defi or defb: a constant register and the literal it holds.
Destination
A destination operand.
Error
Something the reader can’t read: the 32-bit word of the token stream where it is (the version token is word 0), and what was expected there or found instead.
Instruction
An instruction: everything but declarations, definitions, comments and END.
Location
Where an instruction writes a variable: the variable’s components in its four destination lanes.
Options
What the listing writes, as the D3D_DISASM_* flags of Microsoft’s disassembler choose it.
Program
A program read: its version, its records in stream order, its constant table and its debug information.
Records
A program’s records in stream order: see records.
Register
A register: its type and number.
Relative
The index register of a relatively addressed operand (c[a0.x + 4], v[aL]).
Source
A source operand.
SourceLine
The source line of one declaration, definition or instruction.
Type
A CTAB type. Numeric class/type values are D3DXPARAMETER_CLASS/TYPE, kept alongside their dimensions.
TypeMember
One member of a struct type.
Variable
A variable: a parameter, a local, the function’s return value or a constant.
Version
A program’s version token: the stage, and the major and minor version in its low 16 bits.

Enums§

Comparison
The comparison of if_comp, break_comp and setp_comp (D3DSHADER_COMPARISON), bits 16 to 18 of the instruction token.
Declared
What a declaration token declares.
Item
One record of the stream.
Literal
The literal of a definition.
Modifier
A source modifier (D3DSHADER_PARAM_SRCMOD_TYPE, D3DSPSM_*), bits 24 to 27 of a source token.
Opcode
An instruction opcode: the low 16 bits of an instruction token. The variants carry the token value (Opcode::code) and the assembler’s name (Opcode::name); declarations (dcl), definitions (def, defi, defb), comments and end are opcodes of the stream as well but are read into their own records.
RegisterType
A register type (D3DSHADER_PARAM_REGISTER_TYPE, D3DSPR_*). Type 3 is the address register in a vertex program and a texture register in a pixel program; type 6 is a vertex program’s texture-coordinate output (oTN) before 3.0 and its output oN in 3.0.
Stage
The stage a program is for: the high 16 bits of its version token, 0xfffe vertex and 0xffff pixel.
TextureType
A sampler’s texture type (D3DSAMPLER_TEXTURE_TYPE), bits 27 to 30 of its declaration token.

Functions§

disassemble
The listing of a Direct3D 9 program (its version token to END, no container) as Microsoft’s disassembler writes it with no flags, its lines ending in \n (the disassembler’s blob also ends in a zero byte, which is not part of the text). Refuses what read refuses.
disassemble_with
The listing disassemble writes, with what options choose.
frame
Read the first program of bytes, which may hold more after it (a container’s other records, say), and return it with its exact bytes, version token to END. END is found by reading every record, never by searching for it inside operands or comments.
read
Read a complete program: version token to END, with nothing after it. The bytes are little-endian words.
records
The records of a complete program, one at a time in stream order, for a caller that stops at the first record it cannot use, before the reader has read further (and refused, maybe, something later). The version is read first; a refusal ends the iteration, as does END, after which words left over are a refusal. read is these records collected.

Type Aliases§

Result
The reader’s result: an Error naming the word where reading failed.