nCine::RHI::RSX::RsxShaderProgram class

Shader program of the RSX backend (aliased as RHI::ShaderProgram).

Carries the offline ShaderCompiler reflection (set with SetReflection() like the OpenGL backend) from which it imports uniforms, uniform blocks and attributes, and gets its two stage binaries from the identity SetProgramIdentity() plumbs in - the generated RsxGeneratedShaders.h table.

Everything about this class follows from there being no shader compiler on the console.** The Vita backend this otherwise mirrors ships Cg source and compiles it at link time through SceShaccCg; the PS3 has no such thing, so the same Cg is compiled to NV40 microcode offline by cgcomp and embedded as a rsxVertexProgram / rsxFragmentProgram blob. Linking is therefore not a compile at all - it looks the pair up, copies the fragment half where the hardware can fetch it, and resolves names.

A consequence worth stating plainly: a shader whose Cg exceeded what the vp40/fp40 profiles can express has no entry in that table, and Link() fails for it at load time with a message naming the variant. That is a build-time fact rather than a runtime one - it cannot change on the console - so it is reported once and the program stays unlinked rather than being retried.

There is also far less caching here than the sceGxm backend needs. sceGxm bakes the vertex layout into a patched vertex program and the blend state into a patched fragment program, so it keeps a cache of each; the RSX takes both as ordinary state - attributes through rsxBindVertexArrayAttrib() at draw time, blending through rsxSetBlendFunc() - so one program object serves every layout and every blend configuration.

Fragment constants are the one genuinely awkward part.** The RSX patches a fragment program's constants into its microcode rather than into a register file, which is why rsxSetFragmentProgramParameter() needs the microcode's address and location, and why each program owns a private copy of its fragment microcode in local memory (_fragmentUcode) rather than pointing at the shared blob in the executable. Two programs sharing one blob would overwrite each other's constants.

Public types

struct RsxBlockUpload
Where one uniform block's bytes go among a stage's constants.
struct RsxInstanceField
One field of a batched instance element, and where it sits on each side.
struct RsxInstanceArray
The batched instance array of a stage, if it has one.
struct RsxSamplerBinding
Where one of a stage's samplers takes its texture from.
enum class Introspection { Enabled, NoUniformsInBlocks, Disabled }
enum class Status { NotLinked, CompilationFailed, LinkingFailed, Linked, LinkedWithDeferredQueries, LinkedWithIntrospection }
enum class QueryPhase { Immediate, Deferred }

Public static variables

static std::int32_t DefaultBatchSize constexpr
Default batch size, indicating the shader is not batched.

Constructors, destructors, conversion operators

RsxShaderProgram()
RsxShaderProgram(QueryPhase queryPhase) explicit
RsxShaderProgram(StringView vertexFile, StringView fragmentFile, Introspection introspection, QueryPhase queryPhase)
RsxShaderProgram(StringView vertexFile, StringView fragmentFile, Introspection introspection)
RsxShaderProgram(StringView vertexFile, StringView fragmentFile)
~RsxShaderProgram()
RsxShaderProgram(const RsxShaderProgram&) deleted

Public functions

auto operator=(const RsxShaderProgram&) -> RsxShaderProgram& deleted
auto GetUniqueId() const -> std::uint32_t
Returns a backend-neutral identifier uniquely identifying the program (feeds material sort keys).
auto GetStatus() const -> Status
auto GetIntrospection() const -> Introspection
auto GetQueryPhase() const -> QueryPhase
auto GetBatchSize() const -> std::uint32_t
void SetBatchSize(std::uint32_t value)
auto IsLinked() const -> bool
auto RetrieveInfoLogLength() const -> std::uint32_t
void RetrieveInfoLog(std::string& infoLog) const
auto GetUniformsSize() const -> std::uint32_t
auto GetUniformBlocksSize() const -> std::uint32_t
auto AttachShaderFromFile(ShaderStage stage, StringView filename) -> bool
auto AttachShaderFromString(ShaderStage stage, StringView string) -> bool
auto AttachShaderFromStrings(ShaderStage stage, ArrayView<const StringView> strings) -> bool
auto AttachShaderFromStringsAndFile(ShaderStage stage, ArrayView<const StringView> strings, StringView filename) -> bool
void SetReflection(const ShaderCompiler::ProgramVariant* reflection)
Sets the offline reflection consumed by Link() to import uniforms/blocks/attributes.
void SetProgramIdentity(const char* programName, const char* variantName)
Records the true (program, variant) identity of the loaded shader.
auto GetProgramName() const -> const char*
Returns the generated program's name, or nullptr for one that carries no identity.
auto Link(Introspection introspection) -> bool
void Use()
auto Validate() -> bool
auto FinalizeAfterLinking(Introspection introspection) -> bool
auto GetAttributeCount() const -> std::uint32_t
auto HasAttribute(const char* name) const -> bool
auto IsIntegerAttribute(const char* name) const -> bool
Returns true if the reflection declares name with an integer type (a batch element index).
auto GetAttribute(const char* name) -> RsxVertexFormat::Attribute*
void DefineVertexFormat(const RsxBufferObject* vbo)
void DefineVertexFormat(const RsxBufferObject* vbo, const RsxBufferObject* ibo)
void DefineVertexFormat(const RsxBufferObject* vbo, const RsxBufferObject* ibo, std::uint32_t vboOffset)
void Reset()
void SetObjectLabel(StringView label)
auto GetLogOnErrors() const -> bool
void SetLogOnErrors(bool shouldLogOnErrors)
void SetResolvedUniform(const char* name, const std::uint8_t* data)
Publishes a committed loose-uniform value pointer for the device to upload.
auto ResolveUniform(const char* name) const -> const std::uint8_t*
Returns the last published value pointer of the named loose uniform, or nullptr.
auto GetVertexProgram() const -> const rsxVertexProgram*
Returns the embedded vertex microcode descriptor, or nullptr if the program did not link.
auto GetFragmentProgram() const -> const rsxFragmentProgram*
Returns the embedded fragment microcode descriptor, or nullptr.
auto GetVertexUcode() const -> const void*
Returns the vertex microcode the device hands to rsxLoadVertexProgram().
auto GetFragmentUcodeBlock() const -> const RsxVram::Block&
Returns this program's private copy of the fragment microcode in local memory.
auto GetVertexUniformSlots() const -> const SmallVector<RsxUniformSlot, 0>&
Loose-uniform slots of the vertex stage (resolved once at link time).
auto GetFragmentUniformSlots() const -> const SmallVector<RsxUniformSlot, 0>&
Loose-uniform slots of the fragment stage.
auto GetInstanceArray() const -> const RsxInstanceArray&
The vertex stage's batched instance array (never present on the fragment stage).
auto GetVertexBlockUploads() const -> const SmallVector<RsxBlockUpload, 0>&
Uniform-block member uploads of the vertex stage.
auto GetFragmentBlockUploads() const -> const SmallVector<RsxBlockUpload, 0>&
Uniform-block member uploads of the fragment stage.
auto GetFragmentSamplers() const -> const SmallVector<RsxSamplerBinding, 0>&
Samplers the fragment stage declares (the vertex stage never samples in this engine).
auto GetStageAttributes() const -> const SmallVector<RsxStageAttribute, 0>&
Vertex attributes the compiled stage declares (see RsxStageAttribute).
auto GetStageAttributeRegister(const char* name) const -> std::int32_t
Returns the attribute register of the named compiled attribute, or -1.
auto GetAttributeRegisterForLocation(std::uint32_t location) const -> std::int32_t
Returns the attribute register the compiled stage reads a reflection location from, or -1.
auto GetVertexFormat() -> RsxVertexFormat&
Returns the vertex format the pipeline last defined on this program.

Function documentation

void nCine::RHI::RSX::RsxShaderProgram::SetProgramIdentity(const char* programName, const char* variantName)

Records the true (program, variant) identity of the loaded shader.

This backend resolves its generated microcode from this identity, the same way the fixed-function console backends resolve their generated effect tables from it.

std::int32_t nCine::RHI::RSX::RsxShaderProgram::GetAttributeRegisterForLocation(std::uint32_t location) const

Returns the attribute register the compiled stage reads a reflection location from, or -1.

The pipeline addresses a vertex attribute by its location in the reflection's numbering, but the register the microcode actually fetches is cgcomp's own and need not match. Resolved by name once at link time (see ResolveStageInterface), because binding a stream to the reflection's number leaves the stage reading a register nothing filled - which is a mesh that renders nothing at all.