1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: gr_Shader.h 4 5 Copyright (C)2010 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 25895 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NN_GR_SHADER_H_ 17 #define NN_GR_SHADER_H_ 18 19 #include <nn/gr/CTR/gr_Prefix.h> 20 #include <nn/gr/CTR/gr_BindSymbol.h> 21 22 namespace nn 23 { 24 namespace gr 25 { 26 namespace CTR 27 { 28 29 /*! 30 @brief シェーダーバイナリ設定のためのクラスです。 31 */ 32 class Shader 33 { 34 public : 35 /*! 36 @brief シェーダーバイナリをもとに、コマンド生成用の情報をセットアップします。 37 ※バイナリのコピーはしないので、コマンド生成までバイナリは破棄しないで下さい。 38 指定されたインデクスが有効なシェーダーでない場合、ASSERTです。 39 指定するインデクスは、ctr_VertexShaderLinker32.exeでのリンク時に生成される 40 MAPファイルを参考にして下さい。 41 geo_shader_indexについては、-1を指定することでジオメトリシェーダーを無効化することが出来ます。 42 43 @param [in] shader_binary ctr_VertexShaderLinker32.exeでリンクされたシェーダーバイナリです。 44 @param [in] vtx_shader_index 有効にする頂点シェーダーのインデクスです。 45 @param [in] geo_shader_index 有効にするジオメトリシェーダーシェーダーのインデクスです。 46 */ 47 void SetupBinary( const void* shader_binary, const int vtx_shader_index, const int geo_shader_index ); 48 49 public : 50 /*! 51 @brief 頂点シェーダーにブールレジスタの値を設定します。 52 53 @param [in] symbol 頂点シェーダのブール型のシンボルです。 54 @param [in] isEnable 有効にするときは true、そうでないときは false にします。 55 */ SetUniformBool(const BindSymbolVSBool & symbol,bool isEnable)56 void SetUniformBool( const BindSymbolVSBool& symbol, bool isEnable ) 57 { 58 m_VtxShaderBoolMapUniform = ( m_VtxShaderBoolMapUniform & ~( 1 << symbol.start ) ) | ( ( isEnable ? 1 : 0 ) << symbol.start ); 59 } 60 61 /*! 62 @brief ジオメトリシェーダーにブールレジスタの値を設定します。 63 64 @param [in] symbol ジオメトリシェーダのブール型のシンボルです。 65 @param [in] isEnable 有効にするときは true、そうでないときは false にします。 66 */ SetUniformBool(const BindSymbolGSBool & symbol,bool isEnable)67 void SetUniformBool( const BindSymbolGSBool& symbol, bool isEnable ) 68 { 69 m_GeoShaderBoolMapUniform = ( m_GeoShaderBoolMapUniform & ~( 1 << symbol.start ) ) | ( ( isEnable ? 1 : 0 ) << symbol.start ); 70 } 71 72 /*! 73 @brief 描画モードの設定を行います。 74 デフォルトはGL_TRIANGLESです。 75 PICA_DATA_DRAW_TRIANGLES、PICA_DATA_DRAW_TRIANGLE_STRIP、PICA_DATA_DRAW_TRIANGLE_FANのいずれかを指定します。 76 77 @param[in] draw_mode 設定する描画モード 78 */ SetDrawMode(const PicaDataDrawMode draw_mode)79 void SetDrawMode( const PicaDataDrawMode draw_mode ) 80 { 81 m_DrawMode = draw_mode; 82 } 83 84 public : 85 /*! 86 @brief シェーダー切り替えに必要な全てのコマンドを生成します。 87 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 88 89 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 90 91 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 92 */ 93 u32* MakeFullCommand( u32* command ) const; 94 95 public : 96 /*! 97 @brief 頂点シェーダーのブールレジスタへ値を設定するコマンドを生成します。 98 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 99 100 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 101 102 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 103 */ MakeVtxBoolMapCommand(u32 * command)104 u32* MakeVtxBoolMapCommand( u32* command ) const 105 { 106 *command++ = 0x7fff0000 | m_VtxShaderBoolMapUniform; 107 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_BOOL ); // 0x2b0 108 return command; 109 } 110 111 /*! 112 @brief ジオメトリシェーダーのブールレジスタへ値を設定するコマンドを生成します。 113 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 114 115 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 116 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 117 */ MakeGeoBoolMapCommand(u32 * command)118 u32* MakeGeoBoolMapCommand( u32* command ) const 119 { 120 *command++ = 0x7fff0000 | m_GeoShaderBoolMapUniform; 121 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_BOOL ); // 0x280 122 return command; 123 } 124 125 /*! 126 @brief ジオメトリシェーダー使用設定コマンドを生成します。 127 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 128 ジオメトリシェーダーの有効/無効を設定するときに必要なダミーコマンド、 129 有効、無効の設定コマンドなどが含まれます。 130 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 131 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 132 */ 133 u32* MakePrepareCommand( u32* command ) const; 134 135 /*! 136 @brief 頂点シェーダーについて、プログラムロードのコマンドを生成します。 137 エントリポイントのアドレス、シェーダーバイナリ内の実行コード部分などが含まれます。 138 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 139 140 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 141 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 142 */ 143 u32* MakeVtxProgramCommand( u32* command ) const; 144 145 /*! 146 @brief ジオメトリシェーダーについて、プログラムロードのコマンドを生成します。 147 エントリポイントのアドレス、シェーダーバイナリ内の実行コード部分などが含まれます。 148 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 149 150 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 151 152 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 153 */ 154 u32* MakeGeoProgramCommand( u32* command ) const; 155 156 /*! 157 @brief 頂点シェーダーについて、Swizzleパターンロードのコマンド生成します。 158 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 159 160 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 161 162 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 163 */ MakeVtxSwizzleCommand(u32 * command)164 u32* MakeVtxSwizzleCommand( u32* command ) const 165 { 166 *command++ = 0; 167 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_PROG_SWIZZLE_ADDR ); 168 return MakeLoadCommand_( command, PICA_REG_VS_PROG_SWIZZLE_DATA0, m_Swizzle, m_SwizzleCount ); 169 } 170 171 /*! 172 @brief ジオメトリシェーダーについて、Swizzleパターンロードのコマンド生成します。 173 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 174 175 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 176 177 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 178 */ MakeGeoSwizzleCommand(u32 * command)179 u32* MakeGeoSwizzleCommand( u32* command ) const 180 { 181 *command++ = 0; 182 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_PROG_SWIZZLE_ADDR ); 183 return MakeLoadCommand_( command, PICA_REG_GS_PROG_SWIZZLE_DATA0, m_Swizzle, m_SwizzleCount ); 184 } 185 186 /*! 187 @brief 頂点シェーダーについて、定数レジスタをUniformするコマンド生成します。 188 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 189 190 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 191 192 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 193 */ MakeVtxConstRgCommand(u32 * command)194 u32* MakeVtxConstRgCommand( u32* command ) const 195 { 196 std::memcpy( command, m_CmdCacheVtxConst, m_CmdCacheVtxConstNum * sizeof( u32 ) ); 197 return command + m_CmdCacheVtxConstNum; 198 } 199 200 /*! 201 @brief ジオメトリシェーダーについて、定数レジスタをUniformするコマンド生成します。 202 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 203 204 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 205 206 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 207 */ MakeGeoConstRgCommand(u32 * command)208 u32* MakeGeoConstRgCommand( u32* command ) const 209 { 210 std::memcpy( command, m_CmdCacheGeoConst, m_CmdCacheGeoConstNum * sizeof( u32 ) ); 211 return command + m_CmdCacheGeoConstNum; 212 } 213 214 /*! 215 @brief シェーダーの出力属性を設定するコマンド生成します。 216 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 217 218 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 219 @param[in] is_geometry_shader ジオメトリシェーダーについてのコマンドを生成したい場合、trueを設定します。 220 221 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 222 */ MakeOutAttrCommand(u32 * command)223 u32* MakeOutAttrCommand( u32* command ) const 224 { 225 std::memcpy( command, m_CmdCacheOutAttr, m_CmdCacheOutAttrNum * sizeof( u32 ) ); 226 return command + m_CmdCacheOutAttrNum; 227 } 228 229 public : // バイナリからの情報を取得 230 /*! 231 @brief シンボル名から、シンボル情報への変換をおこないます。 232 「シェーダーコード内で#pragma bind_symbol() で設定したシンボル名」を引数に与えることで、 233 シンボルの型情報とバインドされているレジスタ番号が取得できます。 234 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 235 236 * @param[out] symbol シンボル名によって検索されたシンボルです。 237 * @param[in] name 検索したいシンボル名です。 238 239 * @return 検索対象が見つかった場合、trueを返します。 240 */ 241 bool SearchBindSymbol( 242 BindSymbol* symbol, 243 const char* name ) const; 244 245 /*! 246 @brief 指定された型のシンボルについて、いくつあるか検索します。 247 シェーダーコード内で#pragma bind_symbol() されているもののうち、 248 指定された型のものがいくつあるか検索します。 249 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 250 251 @param[in] shader_type 検索したいシェーダーの種類です。 252 @param[in] symbol_type 検索したい型です。 253 254 @return 見つかったシンボルの数を返します。 255 */ 256 u32 SearchBindSymbolNum( 257 const BindSymbol::ShaderType shader_type, 258 const BindSymbol::SymbolType symbol_type ) const; 259 260 /*! 261 @brief 指定された型のシンボルについて、インデックス(0からシンボル数-1)からシンボル情報への変換を行います。 262 シェーダーコード内で、#pragma bind_symbol() されている順番で、 263 0,1,...シンボル数-1というインデックスが振られます。 264 指定されたインデックスを検索し、見つかったシンボルの情報を取得できます。 265 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 266 267 @param[out] symbol インデックスに対応するシンボルです。 268 @param[in] symbol_index 検索したいインデックスです。 269 270 @return 検索対象が見つかった場合、trueを返します。 271 */ 272 bool SearchBindSymbol( 273 BindSymbol* symbol, 274 const u8 symbol_index ) const; 275 276 public : // 設定の取得 277 /*! 278 @brief シェーダーバイナリに含まれる実行可能シェーダーの数を取得します。 279 280 @return 実行可能シェーダーの数です。 281 */ GetShaderNum()282 u8 GetShaderNum() const 283 { 284 return m_ExeImageInfoNum; 285 } 286 287 /*! 288 @brief ジオメトリシェーダーが有効かどうかを取得します。 289 290 @return EnableGeoShader()によって有効化されていれば、true です。 291 @see EnableGeoShader()、DisableGeoShader() 292 */ IsEnableGeoShader()293 bool IsEnableGeoShader() const 294 { 295 return ( 0 <= GetGeoShaderIndex() ); 296 } 297 298 /*! 299 @brief 有効になっている頂点シェーダーのインデックスを取得します。 300 301 @return EnableVtxShader()によって有効化されているシェーダーインデックスです。 302 @see EnableVtxShader() 303 */ 304 GetVtxShaderIndex()305 int GetVtxShaderIndex() const 306 { 307 return m_VtxShaderIndex; 308 } 309 310 /*! 311 @brief 有効になっている有効になっているジオメトリシェーダーのインデックスを取得します。 312 313 @return EnableGeoShader()によって有効化されているシェーダーインデックス 314 @see EnableGeoShader()、DisableGeoShader() 315 */ GetGeoShaderIndex()316 int GetGeoShaderIndex() const 317 { 318 return m_GeoShaderIndex; 319 } 320 321 /*! 322 @brief 頂点シェーダーに設定されるブールマップを取得します。 323 324 @return ブールマップです。 325 */ GetVtxShaderBoolMapUniform()326 u32 GetVtxShaderBoolMapUniform() const 327 { 328 return m_VtxShaderBoolMapUniform; 329 } 330 331 /*! 332 @brief ジオメトリシェーダーに設定されるブールマップを取得します。 333 334 @return ブールマップです。 335 */ GetGeoShaderBoolMap()336 u32 GetGeoShaderBoolMap() const 337 { 338 return m_GeoShaderBoolMapUniform; 339 } 340 341 private : 342 /*! 343 @brief クラス定数です。 344 */ 345 enum 346 { 347 //! 実行可能シェーダーの最大数です。 348 EXE_IMAGE_MAX = 32, 349 350 //! Swizzleパターンの最大数です。 351 SWIZZLE_PATTERN_MAX = 128, 352 353 //! 0x251に設定するダミーコマンドの数です。 354 DUMMY_DATA_NUM_251 = 10, 355 356 //! 0x200に設定するダミーコマンドの数です。 357 DUMMY_DATA_NUM_200 = 30, 358 359 //! ダミーコマンドなど、パディングにつかう値です。 360 PADDING_DATA = 0xead0fead, 361 362 //! 出力属性のコマンドの最大数です。 363 OUT_ATTR_COMMAND_MAX = 48, 364 365 //! 定数レジスタコマンドの最大数です。 366 CONST_REG_COMMAND_MAX = 96 * 6 + 5 * 2 367 }; 368 369 private: 370 371 /*! 372 @brief 定数レジスタをUniformするコマンド生成します。 373 SetupBinaryでシェーダーバイナリを設定した後に呼ぶようにして下さい。 374 375 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 376 @param[in] is_geometry_shader ジオメトリシェーダーについてのコマンドを生成したい場合、trueを設定します。 377 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 378 */ 379 380 u32* MakeConstRgCommand_( 381 u32* command, 382 const bool is_geometry_shader = false ); 383 384 /*! 385 @brief シェーダーの出力属性を設定するコマンド生成します。 386 387 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 388 @param[in] is_geometry_shader ジオメトリシェーダーについてのコマンドを生成したい場合、trueを設定します。 389 390 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 391 */ 392 u32* MakeOutAttrCommand_( u32* command ); 393 394 /*! 395 @brief ひとまとまりのデータを指定されたレジスタに送信するコマンドを生成します。SEQ、BEには非対応です。 396 397 @param command [out] コマンドを追加するバッファのアドレスです。 398 @param load_reg [in] 送信するレジスタです。 399 @param src_buffer_ptr [in] 送信したいデータのバッファの先頭アドレスです。 400 @param src_data_num [in] 送信したいデータの数です。 401 402 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 403 */ 404 u32* MakeLoadCommand_( u32* command, 405 const u32 load_reg, 406 const u32* src_buffer_ptr, 407 const u32 src_size ) const; 408 409 /*! 410 @brief 指定されたレジスタにダミーコマンドを送信するコマンドを生成します。 411 412 @param command [out] コマンドを追加するバッファのアドレス 413 @param load_reg [in] 送信するレジスタ 414 @param data_num [in] 送信したいデータの数 415 416 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 417 */ 418 u32* MakeDummyCommand_( u32* command, 419 const u32 load_reg, 420 const u32 data_num ) const; 421 422 /*! 423 @brief シェーダーバイナリ内の実行コード部分をあらわす構造体です。 424 */ 425 struct ExeImageInfo 426 { 427 u32 signature; 428 u16 version; 429 u8 isGeoShader; 430 u8 outputMaps; 431 u32 mainAddress; 432 u32 endAddress; 433 u32 maskInputOutput; 434 u8 gsDataMode; 435 u8 gsVertexStartIndex; 436 u8 gsPatchSize; 437 u8 gsVertexNum; 438 u32 setupOffset; 439 u32 setupCount; 440 u32 labelOffset; 441 u32 labelCount; 442 u32 outMapOffset; 443 u32 outMapCount; 444 u32 bindSymbolOffset; 445 u32 bindSymbolCount; 446 u32 stringOffset; 447 u32 stringCount; 448 }; 449 450 /*! 451 @brief 有効になっている頂点シェーダーのインデックスです。 452 */ 453 int m_VtxShaderIndex; 454 455 /*! 456 @brief 有効になっているジオメトリシェーダーのインデックスです。 457 */ 458 int m_GeoShaderIndex; 459 460 /*! 461 @brief シェーダーバイナリ内の、実行可能シェーダーの数です。 462 */ 463 u8 m_ExeImageInfoNum; 464 NN_PADDING3; 465 466 /*! 467 @brief シェーダーバイナリ内の、実行可能シェーダーの情報へのポインタを保持します。 468 */ 469 const ExeImageInfo* m_ExeImageInfo[ EXE_IMAGE_MAX ]; 470 471 /*! 472 @brief シェーダーバイナリ内の、シェーダーの実行コード部分へのポインタです。 473 */ 474 const u32* m_Instruction; 475 476 /*! 477 @brief シェーダーバイナリ内の、シェーダーの実行コード部分のサイズです。 478 */ 479 u32 m_InstructionCount; 480 481 /*! 482 @brief Swizzleパターンをコマンド形式に表現したものです。 483 */ 484 u32 m_Swizzle[ SWIZZLE_PATTERN_MAX ]; 485 486 /*! 487 @brief Swizzleパターンの数です。 488 */ 489 u32 m_SwizzleCount; 490 491 /*! 492 @brief 描画モードをあらわします。デフォルトはPICA_DATA_DRAW_TRIANGLESです。 493 */ 494 PicaDataDrawMode m_DrawMode; 495 NN_PADDING3; 496 497 /*! 498 @brief ユニフォームされる頂点シェーダーのブールマップです。 499 */ 500 u32 m_VtxShaderBoolMapUniform; 501 502 /*! 503 @brief ユニフォームされるジオメトリシェーダーのブールマップです。 504 */ 505 u32 m_GeoShaderBoolMapUniform; 506 507 /*! 508 @brief 出力属性のコマンドキャッシュです。 509 */ 510 u32 m_CmdCacheOutAttr[ OUT_ATTR_COMMAND_MAX ]; 511 512 /*! 513 @brief 出力属性のコマンド数です。 514 */ 515 u32 m_CmdCacheOutAttrNum; 516 517 /*! 518 @brief 頂点シェーダーの定数レジスタのコマンドキャッシュです。 519 */ 520 u32 m_CmdCacheVtxConst[ CONST_REG_COMMAND_MAX ]; 521 522 /*! 523 @brief 頂点シェーダーの定数レジスタのコマンド数です。 524 */ 525 u32 m_CmdCacheVtxConstNum; 526 527 /*! 528 @brief ジオメトリシェーダーの定数レジスタのコマンドキャッシュです。 529 */ 530 u32 m_CmdCacheGeoConst[ CONST_REG_COMMAND_MAX ]; 531 532 /*! 533 @brief ジオメトリシェーダーの定数レジスタのコマンド数です。 534 */ 535 u32 m_CmdCacheGeoConstNum; 536 }; 537 538 } // namespace CTR 539 } // namespace gr 540 } // namespace nn 541 542 #endif // NN_GR_SHADER_H_ 543