diff options
| author | 2018-09-19 19:53:11 +0800 | |
|---|---|---|
| committer | 2018-09-19 19:53:11 +0800 | |
| commit | c8f9bbbf859c0e38cf691b64c67761382fcebfc2 (patch) | |
| tree | 99529c2277a6b740a6e278985c5147fa649c5497 /src/video_core/engines | |
| parent | Add 1D sampler for TLDS - TexelFetch (Mario Rabbids) (diff) | |
| parent | Merge pull request #1348 from ogniK5377/GetImageSize (diff) | |
| download | yuzu-c8f9bbbf859c0e38cf691b64c67761382fcebfc2.tar.gz yuzu-c8f9bbbf859c0e38cf691b64c67761382fcebfc2.tar.xz yuzu-c8f9bbbf859c0e38cf691b64c67761382fcebfc2.zip | |
Merge branch 'master' into tlds
Diffstat (limited to 'src/video_core/engines')
| -rw-r--r-- | src/video_core/engines/fermi_2d.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 28 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_dma.h | 2 | ||||
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 213 | ||||
| -rw-r--r-- | src/video_core/engines/shader_header.h | 103 |
7 files changed, 330 insertions, 33 deletions
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index dcf9ef8b9..021b83eaa 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -26,7 +26,7 @@ public: | |||
| 26 | void WriteReg(u32 method, u32 value); | 26 | void WriteReg(u32 method, u32 value); |
| 27 | 27 | ||
| 28 | struct Regs { | 28 | struct Regs { |
| 29 | static constexpr size_t NUM_REGS = 0x258; | 29 | static constexpr std::size_t NUM_REGS = 0x258; |
| 30 | 30 | ||
| 31 | struct Surface { | 31 | struct Surface { |
| 32 | RenderTargetFormat format; | 32 | RenderTargetFormat format; |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 329079ddd..8afd26fe9 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -248,8 +248,8 @@ void Maxwell3D::DrawArrays() { | |||
| 248 | 248 | ||
| 249 | void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { | 249 | void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) { |
| 250 | // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. | 250 | // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. |
| 251 | auto& shader = state.shader_stages[static_cast<size_t>(stage)]; | 251 | auto& shader = state.shader_stages[static_cast<std::size_t>(stage)]; |
| 252 | auto& bind_data = regs.cb_bind[static_cast<size_t>(stage)]; | 252 | auto& bind_data = regs.cb_bind[static_cast<std::size_t>(stage)]; |
| 253 | 253 | ||
| 254 | auto& buffer = shader.const_buffers[bind_data.index]; | 254 | auto& buffer = shader.const_buffers[bind_data.index]; |
| 255 | 255 | ||
| @@ -316,14 +316,14 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { | |||
| 316 | std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderStage stage) const { | 316 | std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderStage stage) const { |
| 317 | std::vector<Texture::FullTextureInfo> textures; | 317 | std::vector<Texture::FullTextureInfo> textures; |
| 318 | 318 | ||
| 319 | auto& fragment_shader = state.shader_stages[static_cast<size_t>(stage)]; | 319 | auto& fragment_shader = state.shader_stages[static_cast<std::size_t>(stage)]; |
| 320 | auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; | 320 | auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; |
| 321 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); | 321 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); |
| 322 | 322 | ||
| 323 | GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; | 323 | GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; |
| 324 | 324 | ||
| 325 | // Offset into the texture constbuffer where the texture info begins. | 325 | // Offset into the texture constbuffer where the texture info begins. |
| 326 | static constexpr size_t TextureInfoOffset = 0x20; | 326 | static constexpr std::size_t TextureInfoOffset = 0x20; |
| 327 | 327 | ||
| 328 | for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset; | 328 | for (GPUVAddr current_texture = tex_info_buffer.address + TextureInfoOffset; |
| 329 | current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { | 329 | current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { |
| @@ -360,8 +360,9 @@ std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderSt | |||
| 360 | return textures; | 360 | return textures; |
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage, size_t offset) const { | 363 | Texture::FullTextureInfo Maxwell3D::GetStageTexture(Regs::ShaderStage stage, |
| 364 | auto& shader = state.shader_stages[static_cast<size_t>(stage)]; | 364 | std::size_t offset) const { |
| 365 | auto& shader = state.shader_stages[static_cast<std::size_t>(stage)]; | ||
| 365 | auto& tex_info_buffer = shader.const_buffers[regs.tex_cb_index]; | 366 | auto& tex_info_buffer = shader.const_buffers[regs.tex_cb_index]; |
| 366 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); | 367 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); |
| 367 | 368 | ||
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index d3be900a4..b81b0723d 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -34,17 +34,17 @@ public: | |||
| 34 | /// Register structure of the Maxwell3D engine. | 34 | /// Register structure of the Maxwell3D engine. |
| 35 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. | 35 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. |
| 36 | struct Regs { | 36 | struct Regs { |
| 37 | static constexpr size_t NUM_REGS = 0xE00; | 37 | static constexpr std::size_t NUM_REGS = 0xE00; |
| 38 | 38 | ||
| 39 | static constexpr size_t NumRenderTargets = 8; | 39 | static constexpr std::size_t NumRenderTargets = 8; |
| 40 | static constexpr size_t NumViewports = 16; | 40 | static constexpr std::size_t NumViewports = 16; |
| 41 | static constexpr size_t NumCBData = 16; | 41 | static constexpr std::size_t NumCBData = 16; |
| 42 | static constexpr size_t NumVertexArrays = 32; | 42 | static constexpr std::size_t NumVertexArrays = 32; |
| 43 | static constexpr size_t NumVertexAttributes = 32; | 43 | static constexpr std::size_t NumVertexAttributes = 32; |
| 44 | static constexpr size_t MaxShaderProgram = 6; | 44 | static constexpr std::size_t MaxShaderProgram = 6; |
| 45 | static constexpr size_t MaxShaderStage = 5; | 45 | static constexpr std::size_t MaxShaderStage = 5; |
| 46 | // Maximum number of const buffers per shader stage. | 46 | // Maximum number of const buffers per shader stage. |
| 47 | static constexpr size_t MaxConstBuffers = 18; | 47 | static constexpr std::size_t MaxConstBuffers = 18; |
| 48 | 48 | ||
| 49 | enum class QueryMode : u32 { | 49 | enum class QueryMode : u32 { |
| 50 | Write = 0, | 50 | Write = 0, |
| @@ -443,9 +443,9 @@ public: | |||
| 443 | } | 443 | } |
| 444 | }; | 444 | }; |
| 445 | 445 | ||
| 446 | bool IsShaderConfigEnabled(size_t index) const { | 446 | bool IsShaderConfigEnabled(std::size_t index) const { |
| 447 | // The VertexB is always enabled. | 447 | // The VertexB is always enabled. |
| 448 | if (index == static_cast<size_t>(Regs::ShaderProgram::VertexB)) { | 448 | if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) { |
| 449 | return true; | 449 | return true; |
| 450 | } | 450 | } |
| 451 | return shader_config[index].enable != 0; | 451 | return shader_config[index].enable != 0; |
| @@ -571,7 +571,7 @@ public: | |||
| 571 | BitField<25, 3, u32> map_7; | 571 | BitField<25, 3, u32> map_7; |
| 572 | }; | 572 | }; |
| 573 | 573 | ||
| 574 | u32 GetMap(size_t index) const { | 574 | u32 GetMap(std::size_t index) const { |
| 575 | const std::array<u32, NumRenderTargets> maps{map_0, map_1, map_2, map_3, | 575 | const std::array<u32, NumRenderTargets> maps{map_0, map_1, map_2, map_3, |
| 576 | map_4, map_5, map_6, map_7}; | 576 | map_4, map_5, map_6, map_7}; |
| 577 | ASSERT(index < maps.size()); | 577 | ASSERT(index < maps.size()); |
| @@ -925,7 +925,7 @@ public: | |||
| 925 | std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; | 925 | std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; |
| 926 | 926 | ||
| 927 | /// Returns the texture information for a specific texture in a specific shader stage. | 927 | /// Returns the texture information for a specific texture in a specific shader stage. |
| 928 | Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const; | 928 | Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, std::size_t offset) const; |
| 929 | 929 | ||
| 930 | private: | 930 | private: |
| 931 | VideoCore::RasterizerInterface& rasterizer; | 931 | VideoCore::RasterizerInterface& rasterizer; |
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index c24d33d5c..aa7481b8c 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -50,7 +50,7 @@ void MaxwellDMA::HandleCopy() { | |||
| 50 | ASSERT(regs.dst_params.pos_y == 0); | 50 | ASSERT(regs.dst_params.pos_y == 0); |
| 51 | 51 | ||
| 52 | if (regs.exec.is_dst_linear == regs.exec.is_src_linear) { | 52 | if (regs.exec.is_dst_linear == regs.exec.is_src_linear) { |
| 53 | size_t copy_size = regs.x_count; | 53 | std::size_t copy_size = regs.x_count; |
| 54 | 54 | ||
| 55 | // When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D | 55 | // When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D |
| 56 | // buffer of length `x_count`, otherwise we copy a 2D buffer of size (x_count, y_count). | 56 | // buffer of length `x_count`, otherwise we copy a 2D buffer of size (x_count, y_count). |
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index 7882f16e0..311ccb616 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h | |||
| @@ -23,7 +23,7 @@ public: | |||
| 23 | void WriteReg(u32 method, u32 value); | 23 | void WriteReg(u32 method, u32 value); |
| 24 | 24 | ||
| 25 | struct Regs { | 25 | struct Regs { |
| 26 | static constexpr size_t NUM_REGS = 0x1D6; | 26 | static constexpr std::size_t NUM_REGS = 0x1D6; |
| 27 | 27 | ||
| 28 | struct Parameters { | 28 | struct Parameters { |
| 29 | union { | 29 | union { |
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index d6e2397f2..7e1de0fa1 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -20,10 +20,10 @@ namespace Tegra::Shader { | |||
| 20 | 20 | ||
| 21 | struct Register { | 21 | struct Register { |
| 22 | /// Number of registers | 22 | /// Number of registers |
| 23 | static constexpr size_t NumRegisters = 256; | 23 | static constexpr std::size_t NumRegisters = 256; |
| 24 | 24 | ||
| 25 | /// Register 255 is special cased to always be 0 | 25 | /// Register 255 is special cased to always be 0 |
| 26 | static constexpr size_t ZeroIndex = 255; | 26 | static constexpr std::size_t ZeroIndex = 255; |
| 27 | 27 | ||
| 28 | enum class Size : u64 { | 28 | enum class Size : u64 { |
| 29 | Byte = 0, | 29 | Byte = 0, |
| @@ -240,6 +240,41 @@ enum class FlowCondition : u64 { | |||
| 240 | Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? | 240 | Fcsm_Tr = 0x1C, // TODO(bunnei): What is this used for? |
| 241 | }; | 241 | }; |
| 242 | 242 | ||
| 243 | enum class ControlCode : u64 { | ||
| 244 | F = 0, | ||
| 245 | LT = 1, | ||
| 246 | EQ = 2, | ||
| 247 | LE = 3, | ||
| 248 | GT = 4, | ||
| 249 | NE = 5, | ||
| 250 | GE = 6, | ||
| 251 | Num = 7, | ||
| 252 | Nan = 8, | ||
| 253 | LTU = 9, | ||
| 254 | EQU = 10, | ||
| 255 | LEU = 11, | ||
| 256 | GTU = 12, | ||
| 257 | NEU = 13, | ||
| 258 | GEU = 14, | ||
| 259 | // | ||
| 260 | OFF = 16, | ||
| 261 | LO = 17, | ||
| 262 | SFF = 18, | ||
| 263 | LS = 19, | ||
| 264 | HI = 20, | ||
| 265 | SFT = 21, | ||
| 266 | HS = 22, | ||
| 267 | OFT = 23, | ||
| 268 | CSM_TA = 24, | ||
| 269 | CSM_TR = 25, | ||
| 270 | CSM_MX = 26, | ||
| 271 | FCSM_TA = 27, | ||
| 272 | FCSM_TR = 28, | ||
| 273 | FCSM_MX = 29, | ||
| 274 | RLE = 30, | ||
| 275 | RGT = 31, | ||
| 276 | }; | ||
| 277 | |||
| 243 | enum class PredicateResultMode : u64 { | 278 | enum class PredicateResultMode : u64 { |
| 244 | None = 0x0, | 279 | None = 0x0, |
| 245 | NotZero = 0x3, | 280 | NotZero = 0x3, |
| @@ -271,6 +306,15 @@ enum class TextureProcessMode : u64 { | |||
| 271 | LLA = 7 // Load LOD. The A is unknown, does not appear to differ with LL | 306 | LLA = 7 // Load LOD. The A is unknown, does not appear to differ with LL |
| 272 | }; | 307 | }; |
| 273 | 308 | ||
| 309 | enum class TextureMiscMode : u64 { | ||
| 310 | DC, | ||
| 311 | AOFFI, // Uses Offset | ||
| 312 | NDV, | ||
| 313 | NODEP, | ||
| 314 | MZ, | ||
| 315 | PTP, | ||
| 316 | }; | ||
| 317 | |||
| 274 | enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; | 318 | enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 }; |
| 275 | enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; | 319 | enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 }; |
| 276 | 320 | ||
| @@ -546,6 +590,15 @@ union Instruction { | |||
| 546 | } pset; | 590 | } pset; |
| 547 | 591 | ||
| 548 | union { | 592 | union { |
| 593 | BitField<0, 3, u64> pred0; | ||
| 594 | BitField<3, 3, u64> pred3; | ||
| 595 | BitField<8, 5, ControlCode> cc; // flag in cc | ||
| 596 | BitField<39, 3, u64> pred39; | ||
| 597 | BitField<42, 1, u64> neg_pred39; | ||
| 598 | BitField<45, 4, PredOperation> op; // op with pred39 | ||
| 599 | } csetp; | ||
| 600 | |||
| 601 | union { | ||
| 549 | BitField<39, 3, u64> pred39; | 602 | BitField<39, 3, u64> pred39; |
| 550 | BitField<42, 1, u64> neg_pred; | 603 | BitField<42, 1, u64> neg_pred; |
| 551 | BitField<43, 1, u64> neg_a; | 604 | BitField<43, 1, u64> neg_a; |
| @@ -590,42 +643,127 @@ union Instruction { | |||
| 590 | BitField<28, 1, u64> array; | 643 | BitField<28, 1, u64> array; |
| 591 | BitField<29, 2, TextureType> texture_type; | 644 | BitField<29, 2, TextureType> texture_type; |
| 592 | BitField<31, 4, u64> component_mask; | 645 | BitField<31, 4, u64> component_mask; |
| 646 | BitField<49, 1, u64> nodep_flag; | ||
| 647 | BitField<50, 1, u64> dc_flag; | ||
| 648 | BitField<54, 1, u64> aoffi_flag; | ||
| 593 | BitField<55, 3, TextureProcessMode> process_mode; | 649 | BitField<55, 3, TextureProcessMode> process_mode; |
| 594 | 650 | ||
| 595 | bool IsComponentEnabled(size_t component) const { | 651 | bool IsComponentEnabled(std::size_t component) const { |
| 596 | return ((1ull << component) & component_mask) != 0; | 652 | return ((1ull << component) & component_mask) != 0; |
| 597 | } | 653 | } |
| 654 | |||
| 655 | TextureProcessMode GetTextureProcessMode() const { | ||
| 656 | return process_mode; | ||
| 657 | } | ||
| 658 | |||
| 659 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 660 | switch (mode) { | ||
| 661 | case TextureMiscMode::DC: | ||
| 662 | return dc_flag != 0; | ||
| 663 | case TextureMiscMode::NODEP: | ||
| 664 | return nodep_flag != 0; | ||
| 665 | case TextureMiscMode::AOFFI: | ||
| 666 | return aoffi_flag != 0; | ||
| 667 | default: | ||
| 668 | break; | ||
| 669 | } | ||
| 670 | return false; | ||
| 671 | } | ||
| 598 | } tex; | 672 | } tex; |
| 599 | 673 | ||
| 600 | union { | 674 | union { |
| 601 | BitField<22, 6, TextureQueryType> query_type; | 675 | BitField<22, 6, TextureQueryType> query_type; |
| 602 | BitField<31, 4, u64> component_mask; | 676 | BitField<31, 4, u64> component_mask; |
| 677 | BitField<49, 1, u64> nodep_flag; | ||
| 678 | |||
| 679 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 680 | switch (mode) { | ||
| 681 | case TextureMiscMode::NODEP: | ||
| 682 | return nodep_flag != 0; | ||
| 683 | default: | ||
| 684 | break; | ||
| 685 | } | ||
| 686 | return false; | ||
| 687 | } | ||
| 603 | } txq; | 688 | } txq; |
| 604 | 689 | ||
| 605 | union { | 690 | union { |
| 606 | BitField<28, 1, u64> array; | 691 | BitField<28, 1, u64> array; |
| 607 | BitField<29, 2, TextureType> texture_type; | 692 | BitField<29, 2, TextureType> texture_type; |
| 608 | BitField<31, 4, u64> component_mask; | 693 | BitField<31, 4, u64> component_mask; |
| 694 | BitField<35, 1, u64> ndv_flag; | ||
| 695 | BitField<49, 1, u64> nodep_flag; | ||
| 609 | 696 | ||
| 610 | bool IsComponentEnabled(size_t component) const { | 697 | bool IsComponentEnabled(std::size_t component) const { |
| 611 | return ((1ull << component) & component_mask) != 0; | 698 | return ((1ull << component) & component_mask) != 0; |
| 612 | } | 699 | } |
| 700 | |||
| 701 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 702 | switch (mode) { | ||
| 703 | case TextureMiscMode::NDV: | ||
| 704 | return (ndv_flag != 0); | ||
| 705 | case TextureMiscMode::NODEP: | ||
| 706 | return (nodep_flag != 0); | ||
| 707 | default: | ||
| 708 | break; | ||
| 709 | } | ||
| 710 | return false; | ||
| 711 | } | ||
| 613 | } tmml; | 712 | } tmml; |
| 614 | 713 | ||
| 615 | union { | 714 | union { |
| 616 | BitField<28, 1, u64> array; | 715 | BitField<28, 1, u64> array; |
| 617 | BitField<29, 2, TextureType> texture_type; | 716 | BitField<29, 2, TextureType> texture_type; |
| 717 | BitField<35, 1, u64> ndv_flag; | ||
| 718 | BitField<49, 1, u64> nodep_flag; | ||
| 719 | BitField<50, 1, u64> dc_flag; | ||
| 720 | BitField<54, 2, u64> info; | ||
| 618 | BitField<56, 2, u64> component; | 721 | BitField<56, 2, u64> component; |
| 722 | |||
| 723 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 724 | switch (mode) { | ||
| 725 | case TextureMiscMode::NDV: | ||
| 726 | return ndv_flag != 0; | ||
| 727 | case TextureMiscMode::NODEP: | ||
| 728 | return nodep_flag != 0; | ||
| 729 | case TextureMiscMode::DC: | ||
| 730 | return dc_flag != 0; | ||
| 731 | case TextureMiscMode::AOFFI: | ||
| 732 | return info == 1; | ||
| 733 | case TextureMiscMode::PTP: | ||
| 734 | return info == 2; | ||
| 735 | default: | ||
| 736 | break; | ||
| 737 | } | ||
| 738 | return false; | ||
| 739 | } | ||
| 619 | } tld4; | 740 | } tld4; |
| 620 | 741 | ||
| 621 | union { | 742 | union { |
| 743 | BitField<49, 1, u64> nodep_flag; | ||
| 744 | BitField<50, 1, u64> dc_flag; | ||
| 745 | BitField<51, 1, u64> aoffi_flag; | ||
| 622 | BitField<52, 2, u64> component; | 746 | BitField<52, 2, u64> component; |
| 747 | |||
| 748 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 749 | switch (mode) { | ||
| 750 | case TextureMiscMode::DC: | ||
| 751 | return dc_flag != 0; | ||
| 752 | case TextureMiscMode::NODEP: | ||
| 753 | return nodep_flag != 0; | ||
| 754 | case TextureMiscMode::AOFFI: | ||
| 755 | return aoffi_flag != 0; | ||
| 756 | default: | ||
| 757 | break; | ||
| 758 | } | ||
| 759 | return false; | ||
| 760 | } | ||
| 623 | } tld4s; | 761 | } tld4s; |
| 624 | 762 | ||
| 625 | union { | 763 | union { |
| 626 | BitField<0, 8, Register> gpr0; | 764 | BitField<0, 8, Register> gpr0; |
| 627 | BitField<28, 8, Register> gpr28; | 765 | BitField<28, 8, Register> gpr28; |
| 628 | BitField<49, 1, u64> nodep; | 766 | BitField<49, 1, u64> nodep_flag; |
| 629 | BitField<50, 3, u64> component_mask_selector; | 767 | BitField<50, 3, u64> component_mask_selector; |
| 630 | BitField<53, 4, u64> texture_info; | 768 | BitField<53, 4, u64> texture_info; |
| 631 | 769 | ||
| @@ -645,6 +783,37 @@ union Instruction { | |||
| 645 | UNREACHABLE(); | 783 | UNREACHABLE(); |
| 646 | } | 784 | } |
| 647 | 785 | ||
| 786 | TextureProcessMode GetTextureProcessMode() const { | ||
| 787 | switch (texture_info) { | ||
| 788 | case 0: | ||
| 789 | case 2: | ||
| 790 | case 6: | ||
| 791 | case 8: | ||
| 792 | case 9: | ||
| 793 | case 11: | ||
| 794 | return TextureProcessMode::LZ; | ||
| 795 | case 3: | ||
| 796 | case 5: | ||
| 797 | case 13: | ||
| 798 | return TextureProcessMode::LL; | ||
| 799 | default: | ||
| 800 | break; | ||
| 801 | } | ||
| 802 | return TextureProcessMode::None; | ||
| 803 | } | ||
| 804 | |||
| 805 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 806 | switch (mode) { | ||
| 807 | case TextureMiscMode::DC: | ||
| 808 | return (texture_info >= 4 && texture_info <= 6) || texture_info == 9; | ||
| 809 | case TextureMiscMode::NODEP: | ||
| 810 | return nodep_flag != 0; | ||
| 811 | default: | ||
| 812 | break; | ||
| 813 | } | ||
| 814 | return false; | ||
| 815 | } | ||
| 816 | |||
| 648 | bool IsArrayTexture() const { | 817 | bool IsArrayTexture() const { |
| 649 | // TEXS only supports Texture2D arrays. | 818 | // TEXS only supports Texture2D arrays. |
| 650 | return texture_info >= 7 && texture_info <= 9; | 819 | return texture_info >= 7 && texture_info <= 9; |
| @@ -654,7 +823,7 @@ union Instruction { | |||
| 654 | return gpr28.Value() != Register::ZeroIndex; | 823 | return gpr28.Value() != Register::ZeroIndex; |
| 655 | } | 824 | } |
| 656 | 825 | ||
| 657 | bool IsComponentEnabled(size_t component) const { | 826 | bool IsComponentEnabled(std::size_t component) const { |
| 658 | static constexpr std::array<std::array<u32, 8>, 4> mask_lut{{ | 827 | static constexpr std::array<std::array<u32, 8>, 4> mask_lut{{ |
| 659 | {}, | 828 | {}, |
| 660 | {0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc}, | 829 | {0x1, 0x2, 0x4, 0x8, 0x3, 0x9, 0xa, 0xc}, |
| @@ -662,7 +831,7 @@ union Instruction { | |||
| 662 | {0x7, 0xb, 0xd, 0xe, 0xf}, | 831 | {0x7, 0xb, 0xd, 0xe, 0xf}, |
| 663 | }}; | 832 | }}; |
| 664 | 833 | ||
| 665 | size_t index{gpr0.Value() != Register::ZeroIndex ? 1U : 0U}; | 834 | std::size_t index{gpr0.Value() != Register::ZeroIndex ? 1U : 0U}; |
| 666 | index |= gpr28.Value() != Register::ZeroIndex ? 2 : 0; | 835 | index |= gpr28.Value() != Register::ZeroIndex ? 2 : 0; |
| 667 | 836 | ||
| 668 | u32 mask = mask_lut[index][component_mask_selector]; | 837 | u32 mask = mask_lut[index][component_mask_selector]; |
| @@ -673,6 +842,7 @@ union Instruction { | |||
| 673 | } texs; | 842 | } texs; |
| 674 | 843 | ||
| 675 | union { | 844 | union { |
| 845 | BitField<49, 1, u64> nodep_flag; | ||
| 676 | BitField<53, 4, u64> texture_info; | 846 | BitField<53, 4, u64> texture_info; |
| 677 | 847 | ||
| 678 | TextureType GetTextureType() const { | 848 | TextureType GetTextureType() const { |
| @@ -693,6 +863,26 @@ union Instruction { | |||
| 693 | UNREACHABLE(); | 863 | UNREACHABLE(); |
| 694 | } | 864 | } |
| 695 | 865 | ||
| 866 | TextureProcessMode GetTextureProcessMode() const { | ||
| 867 | if (texture_info == 1 || texture_info == 5 || texture_info == 12) | ||
| 868 | return TextureProcessMode::LL; | ||
| 869 | return TextureProcessMode::LZ; | ||
| 870 | } | ||
| 871 | |||
| 872 | bool UsesMiscMode(TextureMiscMode mode) const { | ||
| 873 | switch (mode) { | ||
| 874 | case TextureMiscMode::AOFFI: | ||
| 875 | return texture_info == 12 || texture_info == 4; | ||
| 876 | case TextureMiscMode::MZ: | ||
| 877 | return texture_info == 5; | ||
| 878 | case TextureMiscMode::NODEP: | ||
| 879 | return nodep_flag != 0; | ||
| 880 | default: | ||
| 881 | break; | ||
| 882 | } | ||
| 883 | return false; | ||
| 884 | } | ||
| 885 | |||
| 696 | bool IsArrayTexture() const { | 886 | bool IsArrayTexture() const { |
| 697 | // TEXS only supports Texture2D arrays. | 887 | // TEXS only supports Texture2D arrays. |
| 698 | return texture_info == 8; | 888 | return texture_info == 8; |
| @@ -735,6 +925,7 @@ union Instruction { | |||
| 735 | BitField<36, 5, u64> index; | 925 | BitField<36, 5, u64> index; |
| 736 | } cbuf36; | 926 | } cbuf36; |
| 737 | 927 | ||
| 928 | BitField<47, 1, u64> generates_cc; | ||
| 738 | BitField<61, 1, u64> is_b_imm; | 929 | BitField<61, 1, u64> is_b_imm; |
| 739 | BitField<60, 1, u64> is_b_gpr; | 930 | BitField<60, 1, u64> is_b_gpr; |
| 740 | BitField<59, 1, u64> is_c_gpr; | 931 | BitField<59, 1, u64> is_c_gpr; |
| @@ -859,6 +1050,7 @@ public: | |||
| 859 | ISET_IMM, | 1050 | ISET_IMM, |
| 860 | PSETP, | 1051 | PSETP, |
| 861 | PSET, | 1052 | PSET, |
| 1053 | CSETP, | ||
| 862 | XMAD_IMM, | 1054 | XMAD_IMM, |
| 863 | XMAD_CR, | 1055 | XMAD_CR, |
| 864 | XMAD_RC, | 1056 | XMAD_RC, |
| @@ -947,7 +1139,7 @@ public: | |||
| 947 | private: | 1139 | private: |
| 948 | struct Detail { | 1140 | struct Detail { |
| 949 | private: | 1141 | private: |
| 950 | static constexpr size_t opcode_bitsize = 16; | 1142 | static constexpr std::size_t opcode_bitsize = 16; |
| 951 | 1143 | ||
| 952 | /** | 1144 | /** |
| 953 | * Generates the mask and the expected value after masking from a given bitstring. | 1145 | * Generates the mask and the expected value after masking from a given bitstring. |
| @@ -956,8 +1148,8 @@ private: | |||
| 956 | */ | 1148 | */ |
| 957 | static auto GetMaskAndExpect(const char* const bitstring) { | 1149 | static auto GetMaskAndExpect(const char* const bitstring) { |
| 958 | u16 mask = 0, expect = 0; | 1150 | u16 mask = 0, expect = 0; |
| 959 | for (size_t i = 0; i < opcode_bitsize; i++) { | 1151 | for (std::size_t i = 0; i < opcode_bitsize; i++) { |
| 960 | const size_t bit_position = opcode_bitsize - i - 1; | 1152 | const std::size_t bit_position = opcode_bitsize - i - 1; |
| 961 | switch (bitstring[i]) { | 1153 | switch (bitstring[i]) { |
| 962 | case '0': | 1154 | case '0': |
| 963 | mask |= 1 << bit_position; | 1155 | mask |= 1 << bit_position; |
| @@ -1095,6 +1287,7 @@ private: | |||
| 1095 | INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"), | 1287 | INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"), |
| 1096 | INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"), | 1288 | INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"), |
| 1097 | INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), | 1289 | INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"), |
| 1290 | INST("010100001010----", Id::CSETP, Type::PredicateSetPredicate, "CSETP"), | ||
| 1098 | INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), | 1291 | INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"), |
| 1099 | INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), | 1292 | INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"), |
| 1100 | INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"), | 1293 | INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"), |
diff --git a/src/video_core/engines/shader_header.h b/src/video_core/engines/shader_header.h new file mode 100644 index 000000000..a885ee3cf --- /dev/null +++ b/src/video_core/engines/shader_header.h | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/bit_field.h" | ||
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/common_types.h" | ||
| 10 | |||
| 11 | namespace Tegra::Shader { | ||
| 12 | |||
| 13 | enum class OutputTopology : u32 { | ||
| 14 | PointList = 1, | ||
| 15 | LineStrip = 6, | ||
| 16 | TriangleStrip = 7, | ||
| 17 | }; | ||
| 18 | |||
| 19 | // Documentation in: | ||
| 20 | // http://download.nvidia.com/open-gpu-doc/Shader-Program-Header/1/Shader-Program-Header.html#ImapTexture | ||
| 21 | struct Header { | ||
| 22 | union { | ||
| 23 | BitField<0, 5, u32> sph_type; | ||
| 24 | BitField<5, 5, u32> version; | ||
| 25 | BitField<10, 4, u32> shader_type; | ||
| 26 | BitField<14, 1, u32> mrt_enable; | ||
| 27 | BitField<15, 1, u32> kills_pixels; | ||
| 28 | BitField<16, 1, u32> does_global_store; | ||
| 29 | BitField<17, 4, u32> sass_version; | ||
| 30 | BitField<21, 5, u32> reserved; | ||
| 31 | BitField<26, 1, u32> does_load_or_store; | ||
| 32 | BitField<27, 1, u32> does_fp64; | ||
| 33 | BitField<28, 4, u32> stream_out_mask; | ||
| 34 | } common0; | ||
| 35 | |||
| 36 | union { | ||
| 37 | BitField<0, 24, u32> shader_local_memory_low_size; | ||
| 38 | BitField<24, 8, u32> per_patch_attribute_count; | ||
| 39 | } common1; | ||
| 40 | |||
| 41 | union { | ||
| 42 | BitField<0, 24, u32> shader_local_memory_high_size; | ||
| 43 | BitField<24, 8, u32> threads_per_input_primitive; | ||
| 44 | } common2; | ||
| 45 | |||
| 46 | union { | ||
| 47 | BitField<0, 24, u32> shader_local_memory_crs_size; | ||
| 48 | BitField<24, 4, OutputTopology> output_topology; | ||
| 49 | BitField<28, 4, u32> reserved; | ||
| 50 | } common3; | ||
| 51 | |||
| 52 | union { | ||
| 53 | BitField<0, 12, u32> max_output_vertices; | ||
| 54 | BitField<12, 8, u32> store_req_start; // NOTE: not used by geometry shaders. | ||
| 55 | BitField<24, 4, u32> reserved; | ||
| 56 | BitField<12, 8, u32> store_req_end; // NOTE: not used by geometry shaders. | ||
| 57 | } common4; | ||
| 58 | |||
| 59 | union { | ||
| 60 | struct { | ||
| 61 | INSERT_PADDING_BYTES(3); // ImapSystemValuesA | ||
| 62 | INSERT_PADDING_BYTES(1); // ImapSystemValuesB | ||
| 63 | INSERT_PADDING_BYTES(16); // ImapGenericVector[32] | ||
| 64 | INSERT_PADDING_BYTES(2); // ImapColor | ||
| 65 | INSERT_PADDING_BYTES(2); // ImapSystemValuesC | ||
| 66 | INSERT_PADDING_BYTES(5); // ImapFixedFncTexture[10] | ||
| 67 | INSERT_PADDING_BYTES(1); // ImapReserved | ||
| 68 | INSERT_PADDING_BYTES(3); // OmapSystemValuesA | ||
| 69 | INSERT_PADDING_BYTES(1); // OmapSystemValuesB | ||
| 70 | INSERT_PADDING_BYTES(16); // OmapGenericVector[32] | ||
| 71 | INSERT_PADDING_BYTES(2); // OmapColor | ||
| 72 | INSERT_PADDING_BYTES(2); // OmapSystemValuesC | ||
| 73 | INSERT_PADDING_BYTES(5); // OmapFixedFncTexture[10] | ||
| 74 | INSERT_PADDING_BYTES(1); // OmapReserved | ||
| 75 | } vtg; | ||
| 76 | |||
| 77 | struct { | ||
| 78 | INSERT_PADDING_BYTES(3); // ImapSystemValuesA | ||
| 79 | INSERT_PADDING_BYTES(1); // ImapSystemValuesB | ||
| 80 | INSERT_PADDING_BYTES(32); // ImapGenericVector[32] | ||
| 81 | INSERT_PADDING_BYTES(2); // ImapColor | ||
| 82 | INSERT_PADDING_BYTES(2); // ImapSystemValuesC | ||
| 83 | INSERT_PADDING_BYTES(10); // ImapFixedFncTexture[10] | ||
| 84 | INSERT_PADDING_BYTES(2); // ImapReserved | ||
| 85 | struct { | ||
| 86 | u32 target; | ||
| 87 | union { | ||
| 88 | BitField<0, 1, u32> sample_mask; | ||
| 89 | BitField<1, 1, u32> depth; | ||
| 90 | BitField<2, 30, u32> reserved; | ||
| 91 | }; | ||
| 92 | } omap; | ||
| 93 | bool IsColorComponentOutputEnabled(u32 render_target, u32 component) const { | ||
| 94 | const u32 bit = render_target * 4 + component; | ||
| 95 | return omap.target & (1 << bit); | ||
| 96 | } | ||
| 97 | } ps; | ||
| 98 | }; | ||
| 99 | }; | ||
| 100 | |||
| 101 | static_assert(sizeof(Header) == 0x50, "Incorrect structure size"); | ||
| 102 | |||
| 103 | } // namespace Tegra::Shader | ||