Skip to content

Commit 59534d5

Browse files
committed
Start writing the CPP side
1 parent ead4a32 commit 59534d5

File tree

5 files changed

+145
-2
lines changed

5 files changed

+145
-2
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/target
22
/Cargo.lock
3-
.idea
3+
.idea
4+
compile_commands.json

bridge/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ fn main() {
2525

2626
println!("cargo:rerun-if-changed=src/lib.rs");
2727
println!("cargo:rerun-if-changed=src/bridge.cc");
28+
println!("cargo:rerun-if-changed=src/bridge.hpp");
2829
println!("cargo:rerun-if-changed={}", vendor_dir().to_str().unwrap());
2930
}

bridge/src/bridge.cc

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#include "bridge.hpp"
2+
3+
#include <shader_compiler/environment.h>
4+
#include <shader_compiler/frontend/maxwell/translate_program.h>
5+
#include <shader_compiler/backend/spirv/emit_spirv.h>
6+
7+
namespace Bridge {
8+
9+
class DummyEnvironment : public Shader::Environment {
10+
private:
11+
boost::container::vector<u8> binary;
12+
u32 baseOffset;
13+
// those can be ignored
14+
u32 textureBufferIndex;
15+
bool viewportTransformEnabled;
16+
// TODO: stub those
17+
// ShaderManager::ConstantBufferRead constantBufferRead;
18+
// ShaderManager::GetTextureType getTextureType;
19+
20+
public:
21+
DummyEnvironment(Shader::Stage pStage,
22+
boost::container::vector<u8> pBinary, u32 baseOffset
23+
// ShaderManager::ConstantBufferRead constantBufferRead, ShaderManager::GetTextureType getTextureType
24+
)
25+
: binary{std::move(pBinary)}, baseOffset{baseOffset},
26+
textureBufferIndex{0},
27+
viewportTransformEnabled{false}
28+
// constantBufferRead{std::move(constantBufferRead)}, getTextureType{std::move(getTextureType)}
29+
{
30+
stage = pStage;
31+
sph = *reinterpret_cast<Shader::ProgramHeader *>(binary.data());
32+
start_address = baseOffset;
33+
is_propietary_driver = textureBufferIndex == 2;
34+
}
35+
36+
[[nodiscard]] u64 ReadInstruction(u32 address) final {
37+
address -= baseOffset;
38+
if (binary.size() < (address + sizeof(u64)))
39+
throw std::runtime_error("Out of bounds instruction read: 0x{:X}"); // TODO: fmt?
40+
return *reinterpret_cast<u64 *>(binary.data() + address);
41+
}
42+
43+
[[nodiscard]] u32 ReadCbufValue(u32 index, u32 offset) final {
44+
(void)index;
45+
(void)offset;
46+
return 0; // TODO: STUB
47+
// return constantBufferRead(index, offset);
48+
}
49+
50+
[[nodiscard]] Shader::TexturePixelFormat ReadTexturePixelFormat(u32 handle) final {
51+
(void)handle;
52+
throw std::runtime_error("ReadTexturePixelFormat not implemented");
53+
}
54+
55+
[[nodiscard]] Shader::TextureType ReadTextureType(u32 handle) final {
56+
(void)handle;
57+
return Shader::TextureType::Color2D; // TODO: ???
58+
}
59+
60+
[[nodiscard]] u32 ReadViewportTransformState() final {
61+
return viewportTransformEnabled ? 1 : 0; // Only relevant for graphics shaders
62+
}
63+
64+
[[nodiscard]] u32 TextureBoundBuffer() const final {
65+
return textureBufferIndex;
66+
}
67+
68+
[[nodiscard]] u32 LocalMemorySize() const final {
69+
return static_cast<u32>(sph.LocalMemorySize()) + sph.common3.shader_local_memory_crs_size;
70+
}
71+
72+
[[nodiscard]] u32 SharedMemorySize() const final {
73+
return 0; // Only relevant for compute shaders
74+
}
75+
76+
[[nodiscard]] std::array<u32, 3> WorkgroupSize() const final {
77+
return {0, 0, 0}; // Only relevant for compute shaders
78+
}
79+
80+
[[nodiscard]] bool HasHLEMacroState() const final {
81+
return false;
82+
}
83+
84+
[[nodiscard]] std::optional<Shader::ReplaceConstant> GetReplaceConstBuffer(u32 bank, u32 offset) final {
85+
(void)bank;
86+
(void)offset;
87+
return std::nullopt;
88+
}
89+
90+
void Dump(u64 hash) final {
91+
(void)hash;
92+
}
93+
};
94+
95+
rust::Vec<u8> translate_shader(rust::Vec<u8> shader) {
96+
boost::container::vector<u8> binary{shader.begin(), shader.end()};
97+
98+
Shader::ProgramHeader program_header = *reinterpret_cast<Shader::ProgramHeader *>(binary.data());
99+
Shader::Stage stage;
100+
101+
switch (program_header.common0.shader_type.Value()) {
102+
case 1:
103+
stage = Shader::Stage::VertexB;
104+
break;
105+
case 2:
106+
stage = Shader::Stage::TessellationControl;
107+
break;
108+
case 3:
109+
stage = Shader::Stage::TessellationEval;
110+
break;
111+
case 4:
112+
stage = Shader::Stage::Geometry;
113+
break;
114+
case 5:
115+
stage = Shader::Stage::Fragment;
116+
break;
117+
default:
118+
throw std::runtime_error("Unknown shader type");
119+
}
120+
121+
DummyEnvironment environment{stage, std::move(binary), 0x10030};
122+
123+
// Shader::Maxwell::TranslateProgram()
124+
125+
}
126+
}

bridge/src/bridge.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include <rust/cxx.h>
2+
3+
#include <shader_compiler/common/common_types.h>
4+
5+
namespace Bridge {
6+
rust::Vec<u8> translate_shader(rust::Vec<u8> shader);
7+
}

bridge/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
extern crate shader_compiler_sys;
22

3-
#[cxx::bridge(namespace = "Shader")]
3+
#[cxx::bridge(namespace = "Bridge")]
44
mod ffi {
55
unsafe extern "C++" {
6+
include!("shader-compiler-bridge/src/bridge.hpp");
67
include!(<shader_compiler/environment.h>);
8+
9+
/// Translates a binary maxwell shader into a SPIR-V shader
10+
///
11+
/// Expects the shader to start with the [Shader Program Header]
12+
///
13+
/// [Shader Program Header] https://download.nvidia.com/open-gpu-doc/Shader-Program-Header/1/Shader-Program-Header.html
14+
fn translate_shader(shader: Vec<u8>) -> Vec<u8>;
715
}
816
}

0 commit comments

Comments
 (0)