mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-17 19:21:30 +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/fs.cpp src/core/services/gsp_gpu.cpp src/core/services/gsp_lcd.cpp
|
||||||
src/core/services/ndm.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
|
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
|
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/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/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/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
|
set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
|
#include "PICA/shader_unit.hpp"
|
||||||
|
|
||||||
class GPU {
|
class GPU {
|
||||||
Memory& mem;
|
Memory& mem;
|
||||||
static constexpr u32 regNum = 0x300;
|
static constexpr u32 regNum = 0x300;
|
||||||
|
ShaderUnit shaderUnit;
|
||||||
std::array<u32, regNum> regs; // GPU internal registers
|
std::array<u32, regNum> regs; // GPU internal registers
|
||||||
|
|
||||||
public:
|
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 <fstream>
|
||||||
|
|
||||||
#include "cpu.hpp"
|
#include "cpu.hpp"
|
||||||
#include "gpu.hpp"
|
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
#include "opengl.hpp"
|
#include "opengl.hpp"
|
||||||
|
#include "PICA/gpu.hpp"
|
||||||
#include "SFML/Window.hpp"
|
#include "SFML/Window.hpp"
|
||||||
#include "SFML/Graphics.hpp"
|
#include "SFML/Graphics.hpp"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "gpu.hpp"
|
#include "PICA/gpu.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "kernel_types.hpp"
|
#include "kernel_types.hpp"
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "gpu.hpp"
|
#include "PICA/gpu.hpp"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
void GPU::reset() {
|
void GPU::reset() {
|
||||||
regs.fill(0);
|
regs.fill(0);
|
||||||
|
shaderUnit.reset();
|
||||||
// TODO: Reset blending, texturing, etc here
|
// 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) {
|
u32 GPU::readReg(u32 address) {
|
||||||
printf("Ignoring read from GPU register %08X\n", 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);
|
const u32 index = (address - 0x1EF01000) / sizeof(u32);
|
||||||
writeInternalReg(index, value, 0xffffffff);
|
writeInternalReg(index, value, 0xffffffff);
|
||||||
} else {
|
} 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) {
|
void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
|
using namespace PICAInternalRegs;
|
||||||
|
|
||||||
if (index > regNum) {
|
if (index > regNum) {
|
||||||
Helpers::panic("Tried to write to invalid GPU register. Index: %X, value: %08X\n", index, value);
|
Helpers::panic("Tried to write to invalid GPU register. Index: %X, value: %08X\n", index, value);
|
||||||
return;
|
return;
|
||||||
|
@ -32,7 +35,22 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
u32 currentValue = regs[index];
|
u32 currentValue = regs[index];
|
||||||
u32 newValue = (currentValue & ~mask) | (value & mask); // Only overwrite the bits specified by "mask"
|
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) {
|
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:
|
default:
|
||||||
printf("GPU: Wrote to unimplemented internal reg: %X, value: %08X\n", index, newValue);
|
printf("GPU: Wrote to unimplemented internal reg: %X, value: %08X\n", index, newValue);
|
||||||
break;
|
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
|
// Actually send command list (aka display list) to GPU
|
||||||
void GPUService::processCommandList(u32* cmd) {
|
void GPUService::processCommandList(u32* cmd) {
|
||||||
u32 address = cmd[1] & ~7; // Buffer address
|
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 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)
|
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
Add a link
Reference in a new issue