mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-06 22:25:41 +12:00
[PICA] Shader uploads
This commit is contained in:
parent
36a30da78d
commit
5993dc4759
11 changed files with 105 additions and 9 deletions
|
@ -54,7 +54,7 @@ set(SERVICE_SOURCE_FILES src/core/services/service_manager.cpp src/core/services
|
|||
src/core/services/fs.cpp src/core/services/gsp_gpu.cpp src/core/services/gsp_lcd.cpp
|
||||
src/core/services/ndm.cpp
|
||||
)
|
||||
set(PICA_SOURCE_FILES src/core/PICA/gpu.cpp src/core/PICA/regs.cpp)
|
||||
set(PICA_SOURCE_FILES src/core/PICA/gpu.cpp src/core/PICA/regs.cpp src/core/PICA/shader_unit.cpp)
|
||||
|
||||
set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/opengl.hpp include/termcolor.hpp
|
||||
include/cpu.hpp include/cpu_dynarmic.hpp include/memory.hpp include/kernel/kernel.hpp
|
||||
|
@ -62,7 +62,8 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/opengl.hpp inc
|
|||
include/kernel/config_mem.hpp include/services/service_manager.hpp include/services/apt.hpp
|
||||
include/kernel/handles.hpp include/services/hid.hpp include/services/fs.hpp
|
||||
include/services/gsp_gpu.hpp include/services/gsp_lcd.hpp include/arm_defs.hpp
|
||||
include/gpu.hpp include/services/ndm.hpp
|
||||
include/PICA/gpu.hpp include/PICA/regs.hpp include/services/ndm.hpp
|
||||
include/PICA/shader.hpp include/PICA/shader_unit.hpp
|
||||
)
|
||||
|
||||
set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
#include <array>
|
||||
#include "helpers.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "PICA/shader_unit.hpp"
|
||||
|
||||
class GPU {
|
||||
Memory& mem;
|
||||
static constexpr u32 regNum = 0x300;
|
||||
ShaderUnit shaderUnit;
|
||||
std::array<u32, regNum> regs; // GPU internal registers
|
||||
|
||||
public:
|
16
include/PICA/regs.hpp
Normal file
16
include/PICA/regs.hpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
namespace PICAInternalRegs {
|
||||
enum : u32 {
|
||||
VertexShaderTransferEnd = 0x2BF,
|
||||
VertexShaderTransferIndex = 0x2CB,
|
||||
VertexShaderData0 = 0x2CC,
|
||||
VertexShaderData1 = 0x2CD,
|
||||
VertexShaderData2 = 0x2CE,
|
||||
VertexShaderData3 = 0x2CF,
|
||||
VertexShaderData4 = 0x2D0,
|
||||
VertexShaderData5 = 0x2D1,
|
||||
VertexShaderData6 = 0x2D2,
|
||||
VertexShaderData7 = 0x2D3,
|
||||
};
|
||||
}
|
41
include/PICA/shader.hpp
Normal file
41
include/PICA/shader.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include "helpers.hpp"
|
||||
|
||||
class PICAShader {
|
||||
int bufferIndex; // Index of the next instruction to overwrite
|
||||
|
||||
public:
|
||||
std::array<u32, 512> loadedShader; // Currently loaded & active shader
|
||||
std::array<u32, 512> bufferedShader; // Shader to be transferred when the SH_CODETRANSFER_END reg gets written to
|
||||
|
||||
u32 boolUniform;
|
||||
std::array<u32, 4> intUniforms;
|
||||
std::array<u32, 8> floatUniforms;
|
||||
|
||||
void reset() {
|
||||
loadedShader.fill(0);
|
||||
bufferedShader.fill(0);
|
||||
|
||||
intUniforms.fill(0);
|
||||
floatUniforms.fill(0);
|
||||
boolUniform = 0;
|
||||
bufferIndex = 0;
|
||||
}
|
||||
|
||||
void finalize() {
|
||||
std::memcpy(&loadedShader[0], &bufferedShader[0], 512 * sizeof(u32));
|
||||
}
|
||||
|
||||
void setBufferIndex(u32 offset) {
|
||||
if (offset != 0) Helpers::panic("Is this register 9 or 11 bit?");
|
||||
bufferIndex = (offset >> 2) & 511;
|
||||
}
|
||||
|
||||
void uploadWord(u32 word) {
|
||||
bufferedShader[bufferIndex++] = word;
|
||||
bufferIndex &= 511;
|
||||
}
|
||||
};
|
11
include/PICA/shader_unit.hpp
Normal file
11
include/PICA/shader_unit.hpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
#include "PICA/shader.hpp"
|
||||
|
||||
class ShaderUnit {
|
||||
|
||||
public:
|
||||
PICAShader vs; // Vertex shader
|
||||
PICAShader gs; // Geometry shader
|
||||
|
||||
void reset();
|
||||
};
|
|
@ -4,9 +4,9 @@
|
|||
#include <fstream>
|
||||
|
||||
#include "cpu.hpp"
|
||||
#include "gpu.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "opengl.hpp"
|
||||
#include "PICA/gpu.hpp"
|
||||
#include "SFML/Window.hpp"
|
||||
#include "SFML/Graphics.hpp"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <cstring>
|
||||
#include "gpu.hpp"
|
||||
#include "PICA/gpu.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "kernel_types.hpp"
|
||||
#include "memory.hpp"
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#include "gpu.hpp"
|
||||
#include "PICA/gpu.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
void GPU::reset() {
|
||||
regs.fill(0);
|
||||
shaderUnit.reset();
|
||||
// TODO: Reset blending, texturing, etc here
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "gpu.hpp"
|
||||
#include "PICA/gpu.hpp"
|
||||
#include "PICA/regs.hpp"
|
||||
|
||||
u32 GPU::readReg(u32 address) {
|
||||
printf("Ignoring read from GPU register %08X\n", address);
|
||||
|
@ -10,7 +11,7 @@ void GPU::writeReg(u32 address, u32 value) {
|
|||
const u32 index = (address - 0x1EF01000) / sizeof(u32);
|
||||
writeInternalReg(index, value, 0xffffffff);
|
||||
} else {
|
||||
Helpers::panic("Ignoring write to GPU register %08X. Value: %08X\n", address, value);
|
||||
printf("Ignoring write to external GPU register %08X. Value: %08X\n", address, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +25,8 @@ u32 GPU::readInternalReg(u32 index) {
|
|||
}
|
||||
|
||||
void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||
using namespace PICAInternalRegs;
|
||||
|
||||
if (index > regNum) {
|
||||
Helpers::panic("Tried to write to invalid GPU register. Index: %X, value: %08X\n", index, value);
|
||||
return;
|
||||
|
@ -32,7 +35,22 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
|||
u32 currentValue = regs[index];
|
||||
u32 newValue = (currentValue & ~mask) | (value & mask); // Only overwrite the bits specified by "mask"
|
||||
|
||||
// TODO: Figure out if things like the shader index use the unmasked value or the masked one
|
||||
// We currently use the unmasked value like Citra does
|
||||
switch (index) {
|
||||
case VertexShaderTransferEnd:
|
||||
if (value != 0) shaderUnit.vs.finalize();
|
||||
break;
|
||||
|
||||
case VertexShaderTransferIndex:
|
||||
shaderUnit.vs.setBufferIndex(value);
|
||||
break;
|
||||
|
||||
case VertexShaderData0: case VertexShaderData1: case VertexShaderData2: case VertexShaderData3:
|
||||
case VertexShaderData4: case VertexShaderData5: case VertexShaderData6: case VertexShaderData7:
|
||||
shaderUnit.vs.uploadWord(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("GPU: Wrote to unimplemented internal reg: %X, value: %08X\n", index, newValue);
|
||||
break;
|
||||
|
|
6
src/core/PICA/shader_unit.cpp
Normal file
6
src/core/PICA/shader_unit.cpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include "PICA/shader_unit.hpp"
|
||||
|
||||
void ShaderUnit::reset() {
|
||||
vs.reset();
|
||||
gs.reset();
|
||||
}
|
|
@ -252,7 +252,7 @@ void GPUService::memoryFill(u32* cmd) {
|
|||
// Actually send command list (aka display list) to GPU
|
||||
void GPUService::processCommandList(u32* cmd) {
|
||||
u32 address = cmd[1] & ~7; // Buffer address
|
||||
u32 size = cmd[2] * 8; // Buffer size in bytes
|
||||
u32 size = cmd[2] & ~3; // Buffer size in bytes
|
||||
bool updateGas = cmd[3] == 1; // Update gas additive blend results (0 = don't update, 1 = update)
|
||||
bool flushBuffer = cmd[7] == 1; // Flush buffer (0 = don't flush, 1 = flush)
|
||||
|
||||
|
@ -305,5 +305,5 @@ void GPUService::processCommandList(u32* cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
Helpers::panic("GPU::GSP::processCommandList. Address: %08X, size in bytes: %08X", address, size);
|
||||
printf("GPU::GSP::processCommandList. Address: %08X, size in bytes: %08X\n", address, size);
|
||||
}
|
Loading…
Add table
Reference in a new issue