diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/memory.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/command_processor.cpp | 27 | ||||
| -rw-r--r-- | src/video_core/engines/fermi_2d.cpp | 61 | ||||
| -rw-r--r-- | src/video_core/engines/fermi_2d.h | 89 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 21 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 10 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.h | 4 |
10 files changed, 203 insertions, 52 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index d7c0080fa..2afa0916d 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -659,6 +659,10 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, | |||
| 659 | } | 659 | } |
| 660 | } | 660 | } |
| 661 | 661 | ||
| 662 | void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) { | ||
| 663 | CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size); | ||
| 664 | } | ||
| 665 | |||
| 662 | boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) { | 666 | boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) { |
| 663 | if (addr == 0) { | 667 | if (addr == 0) { |
| 664 | return 0; | 668 | return 0; |
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index f6a88f031..2eaece298 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -24,10 +24,7 @@ namespace Tegra { | |||
| 24 | 24 | ||
| 25 | enum class BufferMethods { | 25 | enum class BufferMethods { |
| 26 | BindObject = 0, | 26 | BindObject = 0, |
| 27 | SetGraphMacroCode = 0x45, | 27 | CountBufferMethods = 0x40, |
| 28 | SetGraphMacroCodeArg = 0x46, | ||
| 29 | SetGraphMacroEntry = 0x47, | ||
| 30 | CountBufferMethods = 0x100, | ||
| 31 | }; | 28 | }; |
| 32 | 29 | ||
| 33 | void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { | 30 | void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) { |
| @@ -36,28 +33,6 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) | |||
| 36 | "{:08X} remaining params {}", | 33 | "{:08X} remaining params {}", |
| 37 | method, subchannel, value, remaining_params); | 34 | method, subchannel, value, remaining_params); |
| 38 | 35 | ||
| 39 | if (method == static_cast<u32>(BufferMethods::SetGraphMacroEntry)) { | ||
| 40 | // Prepare to upload a new macro, reset the upload counter. | ||
| 41 | NGLOG_DEBUG(HW_GPU, "Uploading GPU macro {:08X}", value); | ||
| 42 | current_macro_entry = value; | ||
| 43 | current_macro_code.clear(); | ||
| 44 | return; | ||
| 45 | } | ||
| 46 | |||
| 47 | if (method == static_cast<u32>(BufferMethods::SetGraphMacroCodeArg)) { | ||
| 48 | // Append a new code word to the current macro. | ||
| 49 | current_macro_code.push_back(value); | ||
| 50 | |||
| 51 | // There are no more params remaining, submit the code to the 3D engine. | ||
| 52 | if (remaining_params == 0) { | ||
| 53 | maxwell_3d->SubmitMacroCode(current_macro_entry, std::move(current_macro_code)); | ||
| 54 | current_macro_entry = InvalidGraphMacroEntry; | ||
| 55 | current_macro_code.clear(); | ||
| 56 | } | ||
| 57 | |||
| 58 | return; | ||
| 59 | } | ||
| 60 | |||
| 61 | if (method == static_cast<u32>(BufferMethods::BindObject)) { | 36 | if (method == static_cast<u32>(BufferMethods::BindObject)) { |
| 62 | // Bind the current subchannel to the desired engine id. | 37 | // Bind the current subchannel to the desired engine id. |
| 63 | NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); | 38 | NGLOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", subchannel, value); |
diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 7aab163dc..9019f2504 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp | |||
| @@ -2,12 +2,71 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/memory.h" | ||
| 5 | #include "video_core/engines/fermi_2d.h" | 6 | #include "video_core/engines/fermi_2d.h" |
| 7 | #include "video_core/textures/decoders.h" | ||
| 6 | 8 | ||
| 7 | namespace Tegra { | 9 | namespace Tegra { |
| 8 | namespace Engines { | 10 | namespace Engines { |
| 9 | 11 | ||
| 10 | void Fermi2D::WriteReg(u32 method, u32 value) {} | 12 | Fermi2D::Fermi2D(MemoryManager& memory_manager) : memory_manager(memory_manager) {} |
| 13 | |||
| 14 | void Fermi2D::WriteReg(u32 method, u32 value) { | ||
| 15 | ASSERT_MSG(method < Regs::NUM_REGS, | ||
| 16 | "Invalid Fermi2D register, increase the size of the Regs structure"); | ||
| 17 | |||
| 18 | regs.reg_array[method] = value; | ||
| 19 | |||
| 20 | switch (method) { | ||
| 21 | case FERMI2D_REG_INDEX(trigger): { | ||
| 22 | HandleSurfaceCopy(); | ||
| 23 | break; | ||
| 24 | } | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | void Fermi2D::HandleSurfaceCopy() { | ||
| 29 | NGLOG_WARNING(HW_GPU, "Requested a surface copy with operation {}", | ||
| 30 | static_cast<u32>(regs.operation)); | ||
| 31 | |||
| 32 | const GPUVAddr source = regs.src.Address(); | ||
| 33 | const GPUVAddr dest = regs.dst.Address(); | ||
| 34 | |||
| 35 | // TODO(Subv): Only same-format and same-size copies are allowed for now. | ||
| 36 | ASSERT(regs.src.format == regs.dst.format); | ||
| 37 | ASSERT(regs.src.width * regs.src.height == regs.dst.width * regs.dst.height); | ||
| 38 | |||
| 39 | // TODO(Subv): Only raw copies are implemented. | ||
| 40 | ASSERT(regs.operation == Regs::Operation::SrcCopy); | ||
| 41 | |||
| 42 | const VAddr source_cpu = *memory_manager.GpuToCpuAddress(source); | ||
| 43 | const VAddr dest_cpu = *memory_manager.GpuToCpuAddress(dest); | ||
| 44 | |||
| 45 | u32 src_bytes_per_pixel = RenderTargetBytesPerPixel(regs.src.format); | ||
| 46 | u32 dst_bytes_per_pixel = RenderTargetBytesPerPixel(regs.dst.format); | ||
| 47 | |||
| 48 | if (regs.src.linear == regs.dst.linear) { | ||
| 49 | // If the input layout and the output layout are the same, just perform a raw copy. | ||
| 50 | Memory::CopyBlock(dest_cpu, source_cpu, | ||
| 51 | src_bytes_per_pixel * regs.dst.width * regs.dst.height); | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | |||
| 55 | u8* src_buffer = Memory::GetPointer(source_cpu); | ||
| 56 | u8* dst_buffer = Memory::GetPointer(dest_cpu); | ||
| 57 | |||
| 58 | if (!regs.src.linear && regs.dst.linear) { | ||
| 59 | // If the input is tiled and the output is linear, deswizzle the input and copy it over. | ||
| 60 | Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel, | ||
| 61 | dst_bytes_per_pixel, src_buffer, dst_buffer, true, | ||
| 62 | regs.src.block_height); | ||
| 63 | } else { | ||
| 64 | // If the input is linear and the output is tiled, swizzle the input and copy it over. | ||
| 65 | Texture::CopySwizzledData(regs.src.width, regs.src.height, src_bytes_per_pixel, | ||
| 66 | dst_bytes_per_pixel, dst_buffer, src_buffer, false, | ||
| 67 | regs.dst.block_height); | ||
| 68 | } | ||
| 69 | } | ||
| 11 | 70 | ||
| 12 | } // namespace Engines | 71 | } // namespace Engines |
| 13 | } // namespace Tegra | 72 | } // namespace Tegra |
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 8967ddede..0c5b413cc 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h | |||
| @@ -4,19 +4,106 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 8 | #include "common/assert.h" | ||
| 9 | #include "common/bit_field.h" | ||
| 10 | #include "common/common_funcs.h" | ||
| 7 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "video_core/gpu.h" | ||
| 13 | #include "video_core/memory_manager.h" | ||
| 8 | 14 | ||
| 9 | namespace Tegra { | 15 | namespace Tegra { |
| 10 | namespace Engines { | 16 | namespace Engines { |
| 11 | 17 | ||
| 18 | #define FERMI2D_REG_INDEX(field_name) \ | ||
| 19 | (offsetof(Tegra::Engines::Fermi2D::Regs, field_name) / sizeof(u32)) | ||
| 20 | |||
| 12 | class Fermi2D final { | 21 | class Fermi2D final { |
| 13 | public: | 22 | public: |
| 14 | Fermi2D() = default; | 23 | explicit Fermi2D(MemoryManager& memory_manager); |
| 15 | ~Fermi2D() = default; | 24 | ~Fermi2D() = default; |
| 16 | 25 | ||
| 17 | /// Write the value to the register identified by method. | 26 | /// Write the value to the register identified by method. |
| 18 | void WriteReg(u32 method, u32 value); | 27 | void WriteReg(u32 method, u32 value); |
| 28 | |||
| 29 | struct Regs { | ||
| 30 | static constexpr size_t NUM_REGS = 0x258; | ||
| 31 | |||
| 32 | struct Surface { | ||
| 33 | RenderTargetFormat format; | ||
| 34 | BitField<0, 1, u32> linear; | ||
| 35 | union { | ||
| 36 | BitField<0, 4, u32> block_depth; | ||
| 37 | BitField<4, 4, u32> block_height; | ||
| 38 | BitField<8, 4, u32> block_width; | ||
| 39 | }; | ||
| 40 | u32 depth; | ||
| 41 | u32 layer; | ||
| 42 | u32 pitch; | ||
| 43 | u32 width; | ||
| 44 | u32 height; | ||
| 45 | u32 address_high; | ||
| 46 | u32 address_low; | ||
| 47 | |||
| 48 | GPUVAddr Address() const { | ||
| 49 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||
| 50 | address_low); | ||
| 51 | } | ||
| 52 | }; | ||
| 53 | static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size"); | ||
| 54 | |||
| 55 | enum class Operation : u32 { | ||
| 56 | SrcCopyAnd = 0, | ||
| 57 | ROPAnd = 1, | ||
| 58 | Blend = 2, | ||
| 59 | SrcCopy = 3, | ||
| 60 | ROP = 4, | ||
| 61 | SrcCopyPremult = 5, | ||
| 62 | BlendPremult = 6, | ||
| 63 | }; | ||
| 64 | |||
| 65 | union { | ||
| 66 | struct { | ||
| 67 | INSERT_PADDING_WORDS(0x80); | ||
| 68 | |||
| 69 | Surface dst; | ||
| 70 | |||
| 71 | INSERT_PADDING_WORDS(2); | ||
| 72 | |||
| 73 | Surface src; | ||
| 74 | |||
| 75 | INSERT_PADDING_WORDS(0x15); | ||
| 76 | |||
| 77 | Operation operation; | ||
| 78 | |||
| 79 | INSERT_PADDING_WORDS(0x9); | ||
| 80 | |||
| 81 | // TODO(Subv): This is only a guess. | ||
| 82 | u32 trigger; | ||
| 83 | |||
| 84 | INSERT_PADDING_WORDS(0x1A3); | ||
| 85 | }; | ||
| 86 | std::array<u32, NUM_REGS> reg_array; | ||
| 87 | }; | ||
| 88 | } regs{}; | ||
| 89 | |||
| 90 | MemoryManager& memory_manager; | ||
| 91 | |||
| 92 | private: | ||
| 93 | /// Performs the copy from the source surface to the destination surface as configured in the | ||
| 94 | /// registers. | ||
| 95 | void HandleSurfaceCopy(); | ||
| 19 | }; | 96 | }; |
| 20 | 97 | ||
| 98 | #define ASSERT_REG_POSITION(field_name, position) \ | ||
| 99 | static_assert(offsetof(Fermi2D::Regs, field_name) == position * 4, \ | ||
| 100 | "Field " #field_name " has invalid position") | ||
| 101 | |||
| 102 | ASSERT_REG_POSITION(dst, 0x80); | ||
| 103 | ASSERT_REG_POSITION(src, 0x8C); | ||
| 104 | ASSERT_REG_POSITION(operation, 0xAB); | ||
| 105 | ASSERT_REG_POSITION(trigger, 0xB5); | ||
| 106 | #undef ASSERT_REG_POSITION | ||
| 107 | |||
| 21 | } // namespace Engines | 108 | } // namespace Engines |
| 22 | } // namespace Tegra | 109 | } // namespace Tegra |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2acbb9cd6..4306b894f 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -22,10 +22,6 @@ constexpr u32 MacroRegistersStart = 0xE00; | |||
| 22 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) | 22 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) |
| 23 | : memory_manager(memory_manager), macro_interpreter(*this) {} | 23 | : memory_manager(memory_manager), macro_interpreter(*this) {} |
| 24 | 24 | ||
| 25 | void Maxwell3D::SubmitMacroCode(u32 entry, std::vector<u32> code) { | ||
| 26 | uploaded_macros[entry * 2 + MacroRegistersStart] = std::move(code); | ||
| 27 | } | ||
| 28 | |||
| 29 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { | 25 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { |
| 30 | auto macro_code = uploaded_macros.find(method); | 26 | auto macro_code = uploaded_macros.find(method); |
| 31 | // The requested macro must have been uploaded already. | 27 | // The requested macro must have been uploaded already. |
| @@ -37,9 +33,6 @@ void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { | |||
| 37 | } | 33 | } |
| 38 | 34 | ||
| 39 | void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | 35 | void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { |
| 40 | ASSERT_MSG(method < Regs::NUM_REGS, | ||
| 41 | "Invalid Maxwell3D register, increase the size of the Regs structure"); | ||
| 42 | |||
| 43 | auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); | 36 | auto debug_context = Core::System::GetInstance().GetGPUDebugContext(); |
| 44 | 37 | ||
| 45 | // It is an error to write to a register other than the current macro's ARG register before it | 38 | // It is an error to write to a register other than the current macro's ARG register before it |
| @@ -68,6 +61,9 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 68 | return; | 61 | return; |
| 69 | } | 62 | } |
| 70 | 63 | ||
| 64 | ASSERT_MSG(method < Regs::NUM_REGS, | ||
| 65 | "Invalid Maxwell3D register, increase the size of the Regs structure"); | ||
| 66 | |||
| 71 | if (debug_context) { | 67 | if (debug_context) { |
| 72 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); | 68 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); |
| 73 | } | 69 | } |
| @@ -75,6 +71,10 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 75 | regs.reg_array[method] = value; | 71 | regs.reg_array[method] = value; |
| 76 | 72 | ||
| 77 | switch (method) { | 73 | switch (method) { |
| 74 | case MAXWELL3D_REG_INDEX(macros.data): { | ||
| 75 | ProcessMacroUpload(value); | ||
| 76 | break; | ||
| 77 | } | ||
| 78 | case MAXWELL3D_REG_INDEX(code_address.code_address_high): | 78 | case MAXWELL3D_REG_INDEX(code_address.code_address_high): |
| 79 | case MAXWELL3D_REG_INDEX(code_address.code_address_low): { | 79 | case MAXWELL3D_REG_INDEX(code_address.code_address_low): { |
| 80 | // Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS | 80 | // Note: For some reason games (like Puyo Puyo Tetris) seem to write 0 to the CODE_ADDRESS |
| @@ -141,6 +141,12 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | void Maxwell3D::ProcessMacroUpload(u32 data) { | ||
| 145 | // Store the uploaded macro code to interpret them when they're called. | ||
| 146 | auto& macro = uploaded_macros[regs.macros.entry * 2 + MacroRegistersStart]; | ||
| 147 | macro.push_back(data); | ||
| 148 | } | ||
| 149 | |||
| 144 | void Maxwell3D::ProcessQueryGet() { | 150 | void Maxwell3D::ProcessQueryGet() { |
| 145 | GPUVAddr sequence_address = regs.query.QueryAddress(); | 151 | GPUVAddr sequence_address = regs.query.QueryAddress(); |
| 146 | // Since the sequence address is given as a GPU VAddr, we have to convert it to an application | 152 | // Since the sequence address is given as a GPU VAddr, we have to convert it to an application |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index a022665eb..5cf62fb01 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -31,7 +31,7 @@ public: | |||
| 31 | /// Register structure of the Maxwell3D engine. | 31 | /// Register structure of the Maxwell3D engine. |
| 32 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. | 32 | /// TODO(Subv): This structure will need to be made bigger as more registers are discovered. |
| 33 | struct Regs { | 33 | struct Regs { |
| 34 | static constexpr size_t NUM_REGS = 0xE36; | 34 | static constexpr size_t NUM_REGS = 0xE00; |
| 35 | 35 | ||
| 36 | static constexpr size_t NumRenderTargets = 8; | 36 | static constexpr size_t NumRenderTargets = 8; |
| 37 | static constexpr size_t NumViewports = 16; | 37 | static constexpr size_t NumViewports = 16; |
| @@ -322,7 +322,15 @@ public: | |||
| 322 | 322 | ||
| 323 | union { | 323 | union { |
| 324 | struct { | 324 | struct { |
| 325 | INSERT_PADDING_WORDS(0x200); | 325 | INSERT_PADDING_WORDS(0x45); |
| 326 | |||
| 327 | struct { | ||
| 328 | INSERT_PADDING_WORDS(1); | ||
| 329 | u32 data; | ||
| 330 | u32 entry; | ||
| 331 | } macros; | ||
| 332 | |||
| 333 | INSERT_PADDING_WORDS(0x1B8); | ||
| 326 | 334 | ||
| 327 | struct { | 335 | struct { |
| 328 | u32 address_high; | 336 | u32 address_high; |
| @@ -605,7 +613,7 @@ public: | |||
| 605 | u32 size[MaxShaderStage]; | 613 | u32 size[MaxShaderStage]; |
| 606 | } tex_info_buffers; | 614 | } tex_info_buffers; |
| 607 | 615 | ||
| 608 | INSERT_PADDING_WORDS(0x102); | 616 | INSERT_PADDING_WORDS(0xCC); |
| 609 | }; | 617 | }; |
| 610 | std::array<u32, NUM_REGS> reg_array; | 618 | std::array<u32, NUM_REGS> reg_array; |
| 611 | }; | 619 | }; |
| @@ -637,9 +645,6 @@ public: | |||
| 637 | /// Write the value to the register identified by method. | 645 | /// Write the value to the register identified by method. |
| 638 | void WriteReg(u32 method, u32 value, u32 remaining_params); | 646 | void WriteReg(u32 method, u32 value, u32 remaining_params); |
| 639 | 647 | ||
| 640 | /// Uploads the code for a GPU macro program associated with the specified entry. | ||
| 641 | void SubmitMacroCode(u32 entry, std::vector<u32> code); | ||
| 642 | |||
| 643 | /// Returns a list of enabled textures for the specified shader stage. | 648 | /// Returns a list of enabled textures for the specified shader stage. |
| 644 | std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; | 649 | std::vector<Texture::FullTextureInfo> GetStageTextures(Regs::ShaderStage stage) const; |
| 645 | 650 | ||
| @@ -670,6 +675,9 @@ private: | |||
| 670 | */ | 675 | */ |
| 671 | void CallMacroMethod(u32 method, std::vector<u32> parameters); | 676 | void CallMacroMethod(u32 method, std::vector<u32> parameters); |
| 672 | 677 | ||
| 678 | /// Handles writes to the macro uploading registers. | ||
| 679 | void ProcessMacroUpload(u32 data); | ||
| 680 | |||
| 673 | /// Handles a write to the QUERY_GET register. | 681 | /// Handles a write to the QUERY_GET register. |
| 674 | void ProcessQueryGet(); | 682 | void ProcessQueryGet(); |
| 675 | 683 | ||
| @@ -687,6 +695,7 @@ private: | |||
| 687 | static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ | 695 | static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ |
| 688 | "Field " #field_name " has invalid position") | 696 | "Field " #field_name " has invalid position") |
| 689 | 697 | ||
| 698 | ASSERT_REG_POSITION(macros, 0x45); | ||
| 690 | ASSERT_REG_POSITION(rt, 0x200); | 699 | ASSERT_REG_POSITION(rt, 0x200); |
| 691 | ASSERT_REG_POSITION(viewport_transform[0], 0x280); | 700 | ASSERT_REG_POSITION(viewport_transform[0], 0x280); |
| 692 | ASSERT_REG_POSITION(viewport, 0x300); | 701 | ASSERT_REG_POSITION(viewport, 0x300); |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 9463cd5d6..9eb143918 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -12,7 +12,7 @@ namespace Tegra { | |||
| 12 | GPU::GPU() { | 12 | GPU::GPU() { |
| 13 | memory_manager = std::make_unique<MemoryManager>(); | 13 | memory_manager = std::make_unique<MemoryManager>(); |
| 14 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager); | 14 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager); |
| 15 | fermi_2d = std::make_unique<Engines::Fermi2D>(); | 15 | fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); |
| 16 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); | 16 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| @@ -22,4 +22,16 @@ const Tegra::Engines::Maxwell3D& GPU::Get3DEngine() const { | |||
| 22 | return *maxwell_3d; | 22 | return *maxwell_3d; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { | ||
| 26 | ASSERT(format != RenderTargetFormat::NONE); | ||
| 27 | |||
| 28 | switch (format) { | ||
| 29 | case RenderTargetFormat::RGBA8_UNORM: | ||
| 30 | case RenderTargetFormat::RGB10_A2_UNORM: | ||
| 31 | return 4; | ||
| 32 | default: | ||
| 33 | UNIMPLEMENTED_MSG("Unimplemented render target format %u", static_cast<u32>(format)); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 25 | } // namespace Tegra | 37 | } // namespace Tegra |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 2888daedc..f168a5171 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -21,6 +21,9 @@ enum class RenderTargetFormat : u32 { | |||
| 21 | RGBA8_SRGB = 0xD6, | 21 | RGBA8_SRGB = 0xD6, |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | /// Returns the number of bytes per pixel of each rendertarget format. | ||
| 25 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format); | ||
| 26 | |||
| 24 | class DebugContext; | 27 | class DebugContext; |
| 25 | 28 | ||
| 26 | /** | 29 | /** |
| @@ -86,8 +89,6 @@ public: | |||
| 86 | } | 89 | } |
| 87 | 90 | ||
| 88 | private: | 91 | private: |
| 89 | static constexpr u32 InvalidGraphMacroEntry = 0xFFFFFFFF; | ||
| 90 | |||
| 91 | /// Writes a single register in the engine bound to the specified subchannel | 92 | /// Writes a single register in the engine bound to the specified subchannel |
| 92 | void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params); | 93 | void WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params); |
| 93 | 94 | ||
| @@ -100,11 +101,6 @@ private: | |||
| 100 | std::unique_ptr<Engines::Fermi2D> fermi_2d; | 101 | std::unique_ptr<Engines::Fermi2D> fermi_2d; |
| 101 | /// Compute engine | 102 | /// Compute engine |
| 102 | std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; | 103 | std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; |
| 103 | |||
| 104 | /// Entry of the macro that is currently being uploaded | ||
| 105 | u32 current_macro_entry = InvalidGraphMacroEntry; | ||
| 106 | /// Code being uploaded for the current macro | ||
| 107 | std::vector<u32> current_macro_code; | ||
| 108 | }; | 104 | }; |
| 109 | 105 | ||
| 110 | } // namespace Tegra | 106 | } // namespace Tegra |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 9c3ae875c..8b39b2bdf 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -27,9 +27,8 @@ static u32 GetSwizzleOffset(u32 x, u32 y, u32 image_width, u32 bytes_per_pixel, | |||
| 27 | return address; | 27 | return address; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | static void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, | 30 | void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, |
| 31 | u8* swizzled_data, u8* unswizzled_data, bool unswizzle, | 31 | u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height) { |
| 32 | u32 block_height) { | ||
| 33 | u8* data_ptrs[2]; | 32 | u8* data_ptrs[2]; |
| 34 | for (unsigned y = 0; y < height; ++y) { | 33 | for (unsigned y = 0; y < height; ++y) { |
| 35 | for (unsigned x = 0; x < width; ++x) { | 34 | for (unsigned x = 0; x < width; ++x) { |
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index a700911cf..2562c4b06 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h | |||
| @@ -17,6 +17,10 @@ namespace Texture { | |||
| 17 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, | 17 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, |
| 18 | u32 block_height = TICEntry::DefaultBlockHeight); | 18 | u32 block_height = TICEntry::DefaultBlockHeight); |
| 19 | 19 | ||
| 20 | /// Copies texture data from a buffer and performs swizzling/unswizzling as necessary. | ||
| 21 | void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_per_pixel, | ||
| 22 | u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 block_height); | ||
| 23 | |||
| 20 | /** | 24 | /** |
| 21 | * Decodes an unswizzled texture into a A8R8G8B8 texture. | 25 | * Decodes an unswizzled texture into a A8R8G8B8 texture. |
| 22 | */ | 26 | */ |