mirror of https://github.com/AxioDL/metaforce.git
Various model rendering fixes
This commit is contained in:
parent
eb17b8061d
commit
e0a7236ad6
|
@ -71,6 +71,7 @@ FileStoreManager::FileStoreManager(std::string_view org, std::string_view domain
|
|||
#endif
|
||||
} else {
|
||||
m_storeRoot = std::string(prefPath);
|
||||
SDL_free(prefPath);
|
||||
}
|
||||
g_instance = this;
|
||||
}
|
||||
|
|
|
@ -220,7 +220,7 @@ void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& sur
|
|||
}
|
||||
|
||||
// SetNumIndStages(numIndStages);
|
||||
// SetNumTevStages(finalTevCount);
|
||||
aurora::gfx::disable_tev_stage(static_cast<ERglTevStage>(finalTevCount));
|
||||
// SetNumTexGens(tcgCount);
|
||||
// SetNumColorChans(finalNumColorChans);
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ static zeus::CVector3f sPlayerPosition;
|
|||
|
||||
CCubeModel::CCubeModel(std::vector<CCubeSurface>* surfaces, std::vector<TCachedToken<CTexture>>* textures,
|
||||
u8* materialData, std::vector<zeus::CVector3f>* positions, std::vector<zeus::CColor>* colors,
|
||||
std::vector<zeus::CVector3f>* normals, std::vector<zeus::CVector2f>* texCoords,
|
||||
std::vector<zeus::CVector2f>* packedTexCoords, const zeus::CAABox& aabb, u8 flags, bool b1,
|
||||
std::vector<zeus::CVector3f>* normals, std::vector<aurora::Vec2<float>>* texCoords,
|
||||
std::vector<aurora::Vec2<float>>* packedTexCoords, const zeus::CAABox& aabb, u8 flags, bool b1,
|
||||
u32 idx)
|
||||
: x0_modelInstance(surfaces, materialData, positions, colors, normals, texCoords, packedTexCoords)
|
||||
, x1c_textures(textures)
|
||||
|
@ -256,12 +256,8 @@ void CCubeModel::EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransf
|
|||
void CCubeModel::DisableShadowMaps() { sRenderModelShadow = false; }
|
||||
|
||||
void CCubeModel::SetArraysCurrent() {
|
||||
if (x0_modelInstance.GetVertexPointer() != nullptr) {
|
||||
aurora::gfx::model::set_vertex_buffer(*x0_modelInstance.GetVertexPointer());
|
||||
}
|
||||
if (x0_modelInstance.GetNormalPointer() != nullptr) {
|
||||
aurora::gfx::model::set_normal_buffer(*x0_modelInstance.GetNormalPointer());
|
||||
}
|
||||
aurora::gfx::model::set_vertex_buffer(x0_modelInstance.GetVertexPointer());
|
||||
aurora::gfx::model::set_normal_buffer(x0_modelInstance.GetNormalPointer());
|
||||
SetStaticArraysCurrent();
|
||||
}
|
||||
|
||||
|
@ -281,8 +277,8 @@ void CCubeModel::SetRenderModelBlack(bool v) {
|
|||
}
|
||||
|
||||
void CCubeModel::SetSkinningArraysCurrent(TVectorRef positions, TVectorRef normals) {
|
||||
aurora::gfx::model::set_vertex_buffer(*positions);
|
||||
aurora::gfx::model::set_normal_buffer(*normals);
|
||||
aurora::gfx::model::set_vertex_buffer(positions);
|
||||
aurora::gfx::model::set_normal_buffer(normals);
|
||||
// colors unused
|
||||
SetStaticArraysCurrent();
|
||||
}
|
||||
|
@ -295,22 +291,20 @@ void CCubeModel::SetStaticArraysCurrent() {
|
|||
sUsingPackedLightmaps = false;
|
||||
}
|
||||
if (sUsingPackedLightmaps) {
|
||||
aurora::gfx::model::set_tex0_tc_buffer(*packedTexCoords);
|
||||
} else if (texCoords != nullptr) {
|
||||
aurora::gfx::model::set_tex0_tc_buffer(*packedTexCoords);
|
||||
}
|
||||
if (texCoords != nullptr) {
|
||||
aurora::gfx::model::set_tc_buffer(*texCoords);
|
||||
aurora::gfx::model::set_tex0_tc_buffer(packedTexCoords);
|
||||
} else {
|
||||
aurora::gfx::model::set_tex0_tc_buffer(texCoords);
|
||||
}
|
||||
aurora::gfx::model::set_tc_buffer(texCoords);
|
||||
CCubeMaterial::KillCachedViewDepState();
|
||||
}
|
||||
|
||||
void CCubeModel::SetUsingPackedLightmaps(bool v) {
|
||||
sUsingPackedLightmaps = v;
|
||||
if (v) {
|
||||
aurora::gfx::model::set_tex0_tc_buffer(*x0_modelInstance.GetPackedTCPointer());
|
||||
aurora::gfx::model::set_tex0_tc_buffer(x0_modelInstance.GetPackedTCPointer());
|
||||
} else {
|
||||
aurora::gfx::model::set_tex0_tc_buffer(*x0_modelInstance.GetTCPointer());
|
||||
aurora::gfx::model::set_tex0_tc_buffer(x0_modelInstance.GetTCPointer());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,13 +33,13 @@ private:
|
|||
std::vector<zeus::CVector3f>* x8_positions; // was void*
|
||||
std::vector<zeus::CVector3f>* xc_normals; // was void*
|
||||
std::vector<zeus::CColor>* x10_colors; // was void*
|
||||
std::vector<zeus::CVector2f>* x14_texCoords; // was void*
|
||||
std::vector<zeus::CVector2f>* x18_packedTexCoords; // was void*
|
||||
std::vector<aurora::Vec2<float>>* x14_texCoords; // was void*
|
||||
std::vector<aurora::Vec2<float>>* x18_packedTexCoords; // was void*
|
||||
|
||||
public:
|
||||
ModelInstance(std::vector<CCubeSurface>* surfaces, u8* material, std::vector<zeus::CVector3f>* positions,
|
||||
std::vector<zeus::CColor>* colors, std::vector<zeus::CVector3f>* normals,
|
||||
std::vector<zeus::CVector2f>* texCoords, std::vector<zeus::CVector2f>* packedTexCoords)
|
||||
std::vector<aurora::Vec2<float>>* texCoords, std::vector<aurora::Vec2<float>>* packedTexCoords)
|
||||
: x0_surfacePtrs(surfaces)
|
||||
, x4_materialData(material)
|
||||
, x8_positions(positions)
|
||||
|
@ -58,8 +58,8 @@ private:
|
|||
[[nodiscard]] TVectorRef GetVertexPointer() const { return x8_positions; }
|
||||
[[nodiscard]] TVectorRef GetNormalPointer() const { return xc_normals; }
|
||||
[[nodiscard]] std::vector<zeus::CColor>* GetColorPointer() const { return x10_colors; }
|
||||
[[nodiscard]] std::vector<zeus::CVector2f>* GetTCPointer() const { return x14_texCoords; }
|
||||
[[nodiscard]] std::vector<zeus::CVector2f>* GetPackedTCPointer() const { return x18_packedTexCoords; }
|
||||
[[nodiscard]] std::vector<aurora::Vec2<float>>* GetTCPointer() const { return x14_texCoords; }
|
||||
[[nodiscard]] std::vector<aurora::Vec2<float>>* GetPackedTCPointer() const { return x18_packedTexCoords; }
|
||||
};
|
||||
|
||||
ModelInstance x0_modelInstance;
|
||||
|
@ -75,8 +75,8 @@ private:
|
|||
public:
|
||||
CCubeModel(std::vector<CCubeSurface>* surfaces, std::vector<TCachedToken<CTexture>>* textures, u8* materialData,
|
||||
std::vector<zeus::CVector3f>* positions, std::vector<zeus::CColor>* colors,
|
||||
std::vector<zeus::CVector3f>* normals, std::vector<zeus::CVector2f>* texCoords,
|
||||
std::vector<zeus::CVector2f>* packedTexCoords, const zeus::CAABox& aabb, u8 flags, bool b1, u32 idx);
|
||||
std::vector<zeus::CVector3f>* normals, std::vector<aurora::Vec2<float>>* texCoords,
|
||||
std::vector<aurora::Vec2<float>>* packedTexCoords, const zeus::CAABox& aabb, u8 flags, bool b1, u32 idx);
|
||||
|
||||
CCubeMaterial GetMaterialByIndex(u32 idx);
|
||||
bool TryLockTextures();
|
||||
|
|
|
@ -233,8 +233,8 @@ void CCubeRenderer::AddStaticGeometry(const std::vector<CMetroidModelInstance>*
|
|||
const_cast<std::vector<zeus::CVector3f>*>(inst.GetVertexPointer()),
|
||||
const_cast<std::vector<zeus::CColor>*>(inst.GetColorPointer()),
|
||||
const_cast<std::vector<zeus::CVector3f>*>(inst.GetNormalPointer()),
|
||||
const_cast<std::vector<zeus::CVector2f>*>(inst.GetTCPointer()),
|
||||
const_cast<std::vector<zeus::CVector2f>*>(inst.GetPackedTCPointer()),
|
||||
const_cast<std::vector<aurora::Vec2<float>>*>(inst.GetTCPointer()),
|
||||
const_cast<std::vector<aurora::Vec2<float>>*>(inst.GetPackedTCPointer()),
|
||||
inst.GetBoundingBox(), inst.GetFlags(), false, instIdx));
|
||||
++instIdx;
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ class CMetroidModelInstance {
|
|||
std::vector<zeus::CVector3f> x60_positions; // was void*
|
||||
std::vector<zeus::CVector3f> x64_normals; // was void*
|
||||
std::vector<zeus::CColor> x68_colors; // was void*
|
||||
std::vector<zeus::CVector2f> x6c_texCoords; // was void*
|
||||
std::vector<zeus::CVector2f> x70_packedTexCoords; // was void*
|
||||
std::vector<aurora::Vec2<float>> x6c_texCoords; // was void*
|
||||
std::vector<aurora::Vec2<float>> x70_packedTexCoords; // was void*
|
||||
|
||||
public:
|
||||
CMetroidModelInstance() = default;
|
||||
|
@ -40,8 +40,8 @@ public:
|
|||
[[nodiscard]] TVectorRef GetVertexPointer() const { return &x60_positions; }
|
||||
[[nodiscard]] TVectorRef GetNormalPointer() const { return &x64_normals; }
|
||||
[[nodiscard]] const std::vector<zeus::CColor>* GetColorPointer() const { return &x68_colors; }
|
||||
[[nodiscard]] const std::vector<zeus::CVector2f>* GetTCPointer() const { return &x6c_texCoords; }
|
||||
[[nodiscard]] const std::vector<zeus::CVector2f>* GetPackedTCPointer() const { return &x70_packedTexCoords; }
|
||||
[[nodiscard]] const std::vector<aurora::Vec2<float>>* GetTCPointer() const { return &x6c_texCoords; }
|
||||
[[nodiscard]] const std::vector<aurora::Vec2<float>>* GetPackedTCPointer() const { return &x70_packedTexCoords; }
|
||||
};
|
||||
|
||||
} // namespace metaforce
|
||||
|
|
|
@ -87,8 +87,8 @@ private:
|
|||
std::vector<zeus::CVector3f> m_positions;
|
||||
std::vector<zeus::CVector3f> m_normals;
|
||||
std::vector<zeus::CColor> m_colors;
|
||||
std::vector<zeus::CVector2f> m_floatUVs;
|
||||
std::vector<zeus::CVector2f> m_shortUVs;
|
||||
std::vector<aurora::Vec2<float>> m_floatUVs;
|
||||
std::vector<aurora::Vec2<float>> m_shortUVs;
|
||||
|
||||
public:
|
||||
CModel(std::unique_ptr<u8[]> in, u32 dataLen, IObjectStore* store);
|
||||
|
|
|
@ -7,7 +7,55 @@
|
|||
|
||||
#include "Runtime/RetroTypes.hpp"
|
||||
|
||||
#include <zeus/CColor.hpp>
|
||||
|
||||
namespace aurora {
|
||||
template <typename T>
|
||||
struct Vec2 {
|
||||
T x{};
|
||||
T y{};
|
||||
|
||||
constexpr Vec2(T x, T y) : x(x), y(y) {}
|
||||
constexpr Vec2(const zeus::CVector2f& vec) : x(vec.x()), y(vec.y()) {}
|
||||
};
|
||||
template <typename T>
|
||||
struct Vec3 {
|
||||
T x{};
|
||||
T y{};
|
||||
T z{};
|
||||
|
||||
constexpr Vec3(T x, T y, T z) : x(x), y(y), z(z) {}
|
||||
constexpr Vec3(const zeus::CVector3f& vec) : x(vec.x()), y(vec.y()), z(vec.z()) {}
|
||||
};
|
||||
template <typename T>
|
||||
struct Vec4 {
|
||||
T x{};
|
||||
T y{};
|
||||
T z{};
|
||||
T w{};
|
||||
|
||||
constexpr Vec4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {}
|
||||
constexpr Vec4(const zeus::CVector4f& vec) : x(vec.x()), y(vec.y()), z(vec.z()), w(vec.w()) {}
|
||||
constexpr Vec4(const zeus::CColor& color) : x(color.r()), y(color.g()), z(color.b()), w(color.a()) {}
|
||||
};
|
||||
template <typename T>
|
||||
struct Mat4x4 {
|
||||
Vec4<T> m0{};
|
||||
Vec4<T> m1{};
|
||||
Vec4<T> m2{};
|
||||
Vec4<T> m3{};
|
||||
|
||||
constexpr Mat4x4(const Vec4<T>& m0, const Vec4<T>& m1, const Vec4<T>& m2, const Vec4<T>& m3)
|
||||
: m0(m0), m1(m1), m2(m2), m3(m3) {}
|
||||
constexpr Mat4x4(const zeus::CMatrix4f& m) : m0(m[0]), m1(m[1]), m2(m[2]), m3(m[3]) {}
|
||||
};
|
||||
constexpr Mat4x4<float> Mat4x4_Identity{
|
||||
Vec4<float>{1.f, 0.f, 0.f, 0.f},
|
||||
Vec4<float>{0.f, 1.f, 0.f, 0.f},
|
||||
Vec4<float>{0.f, 0.f, 1.f, 0.f},
|
||||
Vec4<float>{0.f, 0.f, 0.f, 1.f},
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ArrayRef {
|
||||
public:
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
#include "common.hpp"
|
||||
|
||||
namespace aurora::gfx::model {
|
||||
void set_vertex_buffer(const std::vector<zeus::CVector3f>& data) noexcept;
|
||||
void set_normal_buffer(const std::vector<zeus::CVector3f>& norm) noexcept;
|
||||
void set_tex0_tc_buffer(const std::vector<zeus::CVector2f>& tcs) noexcept; // Tex coords for TEX0
|
||||
void set_tc_buffer(const std::vector<zeus::CVector2f>& tcs) noexcept; // Tex coords for the TEX1-7
|
||||
void set_vertex_buffer(const std::vector<zeus::CVector3f>* data) noexcept;
|
||||
void set_normal_buffer(const std::vector<zeus::CVector3f>* norm) noexcept;
|
||||
void set_tex0_tc_buffer(const std::vector<Vec2<float>>* tcs) noexcept; // Tex coords for TEX0
|
||||
void set_tc_buffer(const std::vector<Vec2<float>>* tcs) noexcept; // Tex coords for the TEX1-7
|
||||
|
||||
void set_vtx_desc_compressed(u32 vtxDesc) noexcept;
|
||||
void queue_surface(const u8* dlStart, u32 dlSize) noexcept;
|
||||
|
|
|
@ -95,52 +95,6 @@ private:
|
|||
m_capacity = size;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Vec2 {
|
||||
T x{};
|
||||
T y{};
|
||||
|
||||
constexpr Vec2(T x, T y) : x(x), y(y) {}
|
||||
constexpr Vec2(const zeus::CVector2f& vec) : x(vec.x()), y(vec.y()) {}
|
||||
};
|
||||
template <typename T>
|
||||
struct Vec3 {
|
||||
T x{};
|
||||
T y{};
|
||||
T z{};
|
||||
|
||||
constexpr Vec3(T x, T y, T z) : x(x), y(y), z(z) {}
|
||||
constexpr Vec3(const zeus::CVector3f& vec) : x(vec.x()), y(vec.y()), z(vec.z()) {}
|
||||
};
|
||||
template <typename T>
|
||||
struct Vec4 {
|
||||
T x{};
|
||||
T y{};
|
||||
T z{};
|
||||
T w{};
|
||||
|
||||
constexpr Vec4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {}
|
||||
constexpr Vec4(const zeus::CVector4f& vec) : x(vec.x()), y(vec.y()), z(vec.z()), w(vec.w()) {}
|
||||
constexpr Vec4(const zeus::CColor& color) : x(color.r()), y(color.g()), z(color.b()), w(color.a()) {}
|
||||
};
|
||||
template <typename T>
|
||||
struct Mat4x4 {
|
||||
Vec4<T> m0{};
|
||||
Vec4<T> m1{};
|
||||
Vec4<T> m2{};
|
||||
Vec4<T> m3{};
|
||||
|
||||
constexpr Mat4x4(const Vec4<T>& m0, const Vec4<T>& m1, const Vec4<T>& m2, const Vec4<T>& m3)
|
||||
: m0(m0), m1(m1), m2(m2), m3(m3) {}
|
||||
constexpr Mat4x4(const zeus::CMatrix4f& m) : m0(m[0]), m1(m[1]), m2(m[2]), m3(m[3]) {}
|
||||
};
|
||||
constexpr Mat4x4<float> Mat4x4_Identity{
|
||||
Vec4<float>{1.f, 0.f, 0.f, 0.f},
|
||||
Vec4<float>{0.f, 1.f, 0.f, 0.f},
|
||||
Vec4<float>{0.f, 0.f, 1.f, 0.f},
|
||||
Vec4<float>{0.f, 0.f, 0.f, 1.f},
|
||||
};
|
||||
} // namespace aurora
|
||||
|
||||
namespace aurora::gfx {
|
||||
|
|
|
@ -68,7 +68,7 @@ constexpr zeus::CMatrix4f DepthCorrect{
|
|||
0.f, 0.f, 0.f, 1.f,
|
||||
// clang-format on
|
||||
};
|
||||
void update_projection(const zeus::CMatrix4f& proj) noexcept { gx::g_proj = DepthCorrect * proj; }
|
||||
void update_projection(const zeus::CMatrix4f& proj) noexcept { gx::g_proj = /*DepthCorrect **/ proj; }
|
||||
void update_fog_state(const metaforce::CFogState& state) noexcept { gx::g_fogState = state; }
|
||||
|
||||
void disable_tev_stage(metaforce::ERglTevStage stage) noexcept { gx::g_tevStages[static_cast<size_t>(stage)].reset(); }
|
||||
|
@ -295,11 +295,11 @@ wgpu::RenderPipeline build_pipeline(const PipelineConfig& config, const ShaderIn
|
|||
.targetCount = colorTargets.size(),
|
||||
.targets = colorTargets.data(),
|
||||
};
|
||||
const auto layouts = build_bind_group_layouts(info, config.shaderConfig);
|
||||
auto layouts = build_bind_group_layouts(info, config.shaderConfig);
|
||||
const std::array bindGroupLayouts{
|
||||
layouts.uniformLayout,
|
||||
layouts.samplerLayout,
|
||||
layouts.textureLayout,
|
||||
std::move(layouts.uniformLayout),
|
||||
std::move(layouts.samplerLayout),
|
||||
std::move(layouts.textureLayout),
|
||||
};
|
||||
const auto pipelineLayoutDescriptor = wgpu::PipelineLayoutDescriptor{
|
||||
.label = "GX Pipeline Layout",
|
||||
|
@ -368,6 +368,12 @@ Range build_uniform(const ShaderInfo& info) noexcept {
|
|||
const auto xf = get_combined_matrix();
|
||||
uniBuf.append(&xf, 64);
|
||||
}
|
||||
for (int i = 0; i < info.usesTevReg.size(); ++i) {
|
||||
if (!info.usesTevReg.test(i)) {
|
||||
continue;
|
||||
}
|
||||
uniBuf.append(&g_colorRegs[i], 16);
|
||||
}
|
||||
for (int i = 0; i < info.sampledColorChannels.size(); ++i) {
|
||||
if (!info.sampledColorChannels.test(i)) {
|
||||
continue;
|
||||
|
|
|
@ -108,6 +108,7 @@ struct ShaderInfo {
|
|||
std::bitset<maxTextures> sampledTextures;
|
||||
std::bitset<4> sampledKcolors;
|
||||
std::bitset<2> sampledColorChannels;
|
||||
std::bitset<3> usesTevReg;
|
||||
u32 uniformSize = 0;
|
||||
bool usesVtxColor : 1 = false;
|
||||
bool usesNormal : 1 = false;
|
||||
|
@ -143,21 +144,29 @@ struct DlVert {
|
|||
|
||||
namespace aurora {
|
||||
template <>
|
||||
inline void xxh3_update(XXH3_state_t& state, const metaforce::CTevCombiners::CTevOp& input) {
|
||||
XXH3_64bits_update(&state, &input.x0_clamp, sizeof(bool));
|
||||
XXH3_64bits_update(&state, &input.x4_op, sizeof(metaforce::CTevCombiners::CTevOp::x4_op));
|
||||
XXH3_64bits_update(&state, &input.x8_bias, sizeof(metaforce::CTevCombiners::CTevOp::x8_bias));
|
||||
XXH3_64bits_update(&state, &input.xc_scale, sizeof(metaforce::CTevCombiners::CTevOp::xc_scale));
|
||||
XXH3_64bits_update(&state, &input.x10_regId, sizeof(metaforce::CTevCombiners::CTevOp::x10_regId));
|
||||
}
|
||||
template <>
|
||||
inline void xxh3_update(XXH3_state_t& state, const gfx::gx::STevStage& input) {
|
||||
XXH3_64bits_update(&state, &input.colorPass, sizeof(metaforce::CTevCombiners::ColorPass));
|
||||
XXH3_64bits_update(&state, &input.alphaPass, sizeof(metaforce::CTevCombiners::AlphaPass));
|
||||
XXH3_64bits_update(&state, &input.colorOp, sizeof(metaforce::CTevCombiners::CTevOp));
|
||||
XXH3_64bits_update(&state, &input.alphaOp, sizeof(metaforce::CTevCombiners::CTevOp));
|
||||
XXH3_64bits_update(&state, &input.kcSel, sizeof(GX::TevKColorSel));
|
||||
XXH3_64bits_update(&state, &input.kaSel, sizeof(GX::TevKAlphaSel));
|
||||
XXH3_64bits_update(&state, &input.texCoordId, sizeof(GX::TexCoordID));
|
||||
XXH3_64bits_update(&state, &input.texMapId, sizeof(GX::TexMapID));
|
||||
XXH3_64bits_update(&state, &input.channelId, sizeof(GX::ChannelID));
|
||||
XXH3_64bits_update(&state, &input.colorPass, sizeof(gfx::gx::STevStage::colorPass));
|
||||
XXH3_64bits_update(&state, &input.alphaPass, sizeof(gfx::gx::STevStage::alphaPass));
|
||||
xxh3_update(state, input.colorOp);
|
||||
xxh3_update(state, input.alphaOp);
|
||||
XXH3_64bits_update(&state, &input.kcSel, sizeof(gfx::gx::STevStage::kcSel));
|
||||
XXH3_64bits_update(&state, &input.kaSel, sizeof(gfx::gx::STevStage::kaSel));
|
||||
XXH3_64bits_update(&state, &input.texCoordId, sizeof(gfx::gx::STevStage::texCoordId));
|
||||
XXH3_64bits_update(&state, &input.texMapId, sizeof(gfx::gx::STevStage::texMapId));
|
||||
XXH3_64bits_update(&state, &input.channelId, sizeof(gfx::gx::STevStage::channelId));
|
||||
}
|
||||
template <>
|
||||
inline XXH64_hash_t xxh3_hash(const gfx::gx::ShaderConfig& input, XXH64_hash_t seed) {
|
||||
XXH3_state_t state;
|
||||
XXH3_INITSTATE(&state);
|
||||
memset(&state, 0, sizeof(XXH3_state_t));
|
||||
XXH3_64bits_reset_withSeed(&state, seed);
|
||||
for (const auto& item : input.tevStages) {
|
||||
if (!item) {
|
||||
|
@ -165,7 +174,9 @@ inline XXH64_hash_t xxh3_hash(const gfx::gx::ShaderConfig& input, XXH64_hash_t s
|
|||
}
|
||||
xxh3_update(state, *item);
|
||||
}
|
||||
XXH3_64bits_update(&state, input.channelMatSrcs.data(), input.channelMatSrcs.size() * sizeof(GX::ColorSrc));
|
||||
for (const auto& item : input.channelMatSrcs) {
|
||||
XXH3_64bits_update(&state, &item, sizeof(GX::ColorSrc));
|
||||
}
|
||||
XXH3_64bits_update(&state, &input.alphaDiscard, sizeof(bool));
|
||||
XXH3_64bits_update(&state, &input.denormalizedVertexAttributes, sizeof(bool));
|
||||
XXH3_64bits_update(&state, &input.denormalizedHasNrm, sizeof(bool));
|
||||
|
|
|
@ -19,13 +19,23 @@ static std::string color_arg_reg(GX::TevColorArg arg, size_t stageIdx, const STe
|
|||
case GX::CC_APREV:
|
||||
return "prev.a";
|
||||
case GX::CC_C0:
|
||||
info.usesTevReg.set(0);
|
||||
return "tevreg0.rgb";
|
||||
case GX::CC_A0:
|
||||
info.usesTevReg.set(0);
|
||||
return "tevreg0.a";
|
||||
case GX::CC_C1:
|
||||
info.usesTevReg.set(1);
|
||||
return "tevreg1.rgb";
|
||||
case GX::CC_A1:
|
||||
info.usesTevReg.set(1);
|
||||
return "tevreg1.a";
|
||||
case GX::CC_C2:
|
||||
info.usesTevReg.set(2);
|
||||
return "tevreg2.rgb";
|
||||
case GX::CC_A2:
|
||||
Log.report(logvisor::Fatal, FMT_STRING("TODO {}"), arg);
|
||||
unreachable();
|
||||
info.usesTevReg.set(2);
|
||||
return "tevreg2.a";
|
||||
case GX::CC_TEXC: {
|
||||
if (stage.texMapId == GX::TEXMAP_NULL) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("unmapped texture for stage {}"), stageIdx);
|
||||
|
@ -161,6 +171,9 @@ static std::string color_arg_reg(GX::TevColorArg arg, size_t stageIdx, const STe
|
|||
}
|
||||
case GX::CC_ZERO:
|
||||
return "0.0";
|
||||
default:
|
||||
Log.report(logvisor::Fatal, FMT_STRING("invalid color arg {}"), arg);
|
||||
unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,10 +182,14 @@ static std::string alpha_arg_reg(GX::TevAlphaArg arg, size_t stageIdx, const STe
|
|||
case GX::CA_APREV:
|
||||
return "prev.a";
|
||||
case GX::CA_A0:
|
||||
info.usesTevReg.set(0);
|
||||
return "tevreg0.a";
|
||||
case GX::CA_A1:
|
||||
info.usesTevReg.set(1);
|
||||
return "tevreg1.a";
|
||||
case GX::CA_A2:
|
||||
Log.report(logvisor::Fatal, FMT_STRING("TODO {}"), arg);
|
||||
unreachable();
|
||||
info.usesTevReg.set(2);
|
||||
return "tevreg2.a";
|
||||
case GX::CA_TEXA: {
|
||||
if (stage.texMapId == GX::TEXMAP_NULL) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("unmapped texture for stage {}"), stageIdx);
|
||||
|
@ -269,6 +286,9 @@ static std::string alpha_arg_reg(GX::TevAlphaArg arg, size_t stageIdx, const STe
|
|||
}
|
||||
case GX::CA_ZERO:
|
||||
return "0.0";
|
||||
default:
|
||||
Log.report(logvisor::Fatal, FMT_STRING("invalid alpha arg {}"), arg);
|
||||
unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,6 +312,9 @@ static std::string_view tev_bias(GX::TevBias bias) {
|
|||
return " + 0.5";
|
||||
case GX::TB_SUBHALF:
|
||||
return " - 0.5";
|
||||
default:
|
||||
Log.report(logvisor::Fatal, FMT_STRING("invalid bias {}"), bias);
|
||||
unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,6 +328,9 @@ static std::string_view tev_scale(GX::TevScale scale) {
|
|||
return " * 4.0";
|
||||
case GX::CS_DIVIDE_2:
|
||||
return " / 2.0";
|
||||
default:
|
||||
Log.report(logvisor::Fatal, FMT_STRING("invalid scale {}"), scale);
|
||||
unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,7 +405,7 @@ std::pair<wgpu::ShaderModule, ShaderInfo> build_shader(const ShaderConfig& confi
|
|||
} else {
|
||||
uniformBindings += R"""(
|
||||
struct Vec3Block {
|
||||
data: array<vec3<f32>>;
|
||||
data: array<vec4<f32>>;
|
||||
};
|
||||
struct Vec2Block {
|
||||
data: array<vec2<f32>>;
|
||||
|
@ -398,7 +424,7 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
|||
"\n , @location(1) in_uv_0_4_idx: vec4<i32>"
|
||||
"\n , @location(2) in_uv_5_7_idx: vec4<i32>";
|
||||
vtxOutAttrs += "\n @builtin(position) pos: vec4<f32>;";
|
||||
vtxXfrAttrsPre += "\n out.pos = ubuf.xf * vec4<f32>(v_verts.data[in_pos_nrm_idx[0]], 1.0);";
|
||||
vtxXfrAttrsPre += "\n out.pos = ubuf.xf * vec4<f32>(v_verts.data[in_pos_nrm_idx[0]].xyz, 1.0);";
|
||||
}
|
||||
|
||||
std::string fragmentFnPre;
|
||||
|
@ -413,6 +439,18 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
|||
case GX::TevRegID::TEVPREV:
|
||||
outReg = "prev";
|
||||
break;
|
||||
case GX::TEVREG0:
|
||||
outReg = "tevreg0";
|
||||
info.usesTevReg.set(0);
|
||||
break;
|
||||
case GX::TEVREG1:
|
||||
outReg = "tevreg1";
|
||||
info.usesTevReg.set(1);
|
||||
break;
|
||||
case GX::TEVREG2:
|
||||
outReg = "tevreg2";
|
||||
info.usesTevReg.set(2);
|
||||
break;
|
||||
default:
|
||||
Log.report(logvisor::Fatal, FMT_STRING("TODO: colorOp outReg {}"), stage->colorOp.x10_regId);
|
||||
}
|
||||
|
@ -423,6 +461,9 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
|||
color_arg_reg(stage->colorPass.x8_c, idx, *stage, info),
|
||||
color_arg_reg(stage->colorPass.xc_d, idx, *stage, info), tev_op(stage->colorOp.x4_op),
|
||||
tev_bias(stage->colorOp.x8_bias), tev_scale(stage->colorOp.xc_scale));
|
||||
if (stage->colorOp.x0_clamp) {
|
||||
op = fmt::format(FMT_STRING("clamp({}, vec3<f32>(0.0), vec3<f32>(1.0))"), op);
|
||||
}
|
||||
fragmentFn += fmt::format(FMT_STRING("\n {0} = vec4<f32>({1}, {0}.a);"), outReg, op);
|
||||
}
|
||||
{
|
||||
|
@ -431,6 +472,18 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
|||
case GX::TevRegID::TEVPREV:
|
||||
outReg = "prev.a";
|
||||
break;
|
||||
case GX::TEVREG0:
|
||||
outReg = "tevreg0.a";
|
||||
info.usesTevReg.set(0);
|
||||
break;
|
||||
case GX::TEVREG1:
|
||||
outReg = "tevreg1.a";
|
||||
info.usesTevReg.set(1);
|
||||
break;
|
||||
case GX::TEVREG2:
|
||||
outReg = "tevreg2.a";
|
||||
info.usesTevReg.set(2);
|
||||
break;
|
||||
default:
|
||||
Log.report(logvisor::Fatal, FMT_STRING("TODO: alphaOp outReg {}"), stage->alphaOp.x10_regId);
|
||||
}
|
||||
|
@ -441,10 +494,20 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
|||
alpha_arg_reg(stage->alphaPass.x8_c, idx, *stage, info),
|
||||
alpha_arg_reg(stage->alphaPass.xc_d, idx, *stage, info), tev_op(stage->alphaOp.x4_op),
|
||||
tev_bias(stage->alphaOp.x8_bias), tev_scale(stage->alphaOp.xc_scale));
|
||||
if (stage->alphaOp.x0_clamp) {
|
||||
op = fmt::format(FMT_STRING("clamp({}, 0.0, 1.0)"), op);
|
||||
}
|
||||
fragmentFn += fmt::format(FMT_STRING("\n {0} = {1};"), outReg, op);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
for (int i = 0; i < info.usesTevReg.size(); ++i) {
|
||||
if (!info.usesTevReg.test(i)) {
|
||||
continue;
|
||||
}
|
||||
uniBufAttrs += fmt::format(FMT_STRING("\n tevreg{}: vec4<f32>;"), i);
|
||||
fragmentFnPre += fmt::format(FMT_STRING("\n var tevreg{0} = ubuf.tevreg{0};"), i);
|
||||
}
|
||||
for (int i = 0; i < info.sampledColorChannels.size(); ++i) {
|
||||
if (!info.sampledColorChannels.test(i)) {
|
||||
continue;
|
||||
|
@ -499,12 +562,12 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
|||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) tex{}_uv: vec2<f32>;"), locIdx, i);
|
||||
if (i < 4) {
|
||||
if (i == 0) {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.tex{}_uv = v_packed_uvs.data[in_uv_0_4[{}]];"), i, i);
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.tex{}_uv = v_packed_uvs.data[in_uv_0_4_idx[{}]];"), i, i);
|
||||
} else {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.tex{}_uv = v_uvs.data[in_uv_0_4[{}]];"), i, i);
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.tex{}_uv = v_uvs.data[in_uv_0_4_idx[{}]];"), i, i);
|
||||
}
|
||||
} else {
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.tex{}_uv = v_uvs.data[in_uv_5_7[{}]];"), i, i - 4);
|
||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.tex{}_uv = v_uvs.data[in_uv_5_7_idx[{}]];"), i, i - 4);
|
||||
}
|
||||
}
|
||||
fragmentFnPre += fmt::format(
|
||||
|
@ -544,9 +607,10 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {{
|
|||
|
||||
wgpu::ShaderModuleWGSLDescriptor wgslDescriptor{};
|
||||
wgslDescriptor.source = shaderSource.c_str();
|
||||
const auto label = fmt::format(FMT_STRING("GX Shader {:x}"), hash);
|
||||
const auto shaderDescriptor = wgpu::ShaderModuleDescriptor{
|
||||
.nextInChain = &wgslDescriptor,
|
||||
.label = "GX Shader",
|
||||
.label = label.c_str(),
|
||||
};
|
||||
auto shader = gpu::g_device.CreateShaderModule(&shaderDescriptor);
|
||||
|
||||
|
|
|
@ -10,14 +10,14 @@ enum class VtxDescAttr : u8 {
|
|||
Position = 0,
|
||||
Normal = 2,
|
||||
Color0 = 4,
|
||||
Color1 = 8,
|
||||
Tex0 = 10,
|
||||
Tex1 = 12,
|
||||
Tex2 = 14,
|
||||
Tex3 = 16,
|
||||
Tex4 = 18,
|
||||
Tex5 = 20,
|
||||
Tex6 = 22,
|
||||
Color1 = 6,
|
||||
Tex0 = 8,
|
||||
Tex1 = 10,
|
||||
Tex2 = 12,
|
||||
Tex3 = 14,
|
||||
Tex4 = 16,
|
||||
Tex5 = 18,
|
||||
Tex6 = 20,
|
||||
PnMatIdx = 24,
|
||||
Tex0MatIdx = 25,
|
||||
Tex1MatIdx = 26,
|
||||
|
@ -51,13 +51,13 @@ static logvisor::Module Log("aurora::gfx::model");
|
|||
|
||||
static const std::vector<zeus::CVector3f>* vtxData;
|
||||
static const std::vector<zeus::CVector3f>* nrmData;
|
||||
static const std::vector<zeus::CVector2f>* tex0TcData;
|
||||
static const std::vector<zeus::CVector2f>* tcData;
|
||||
static const std::vector<Vec2<float>>* tex0TcData;
|
||||
static const std::vector<Vec2<float>>* tcData;
|
||||
|
||||
void set_vertex_buffer(const std::vector<zeus::CVector3f>& data) noexcept { vtxData = &data; }
|
||||
void set_normal_buffer(const std::vector<zeus::CVector3f>& norm) noexcept { nrmData = &norm; }
|
||||
void set_tex0_tc_buffer(const std::vector<zeus::CVector2f>& tcs) noexcept { tex0TcData = &tcs; }
|
||||
void set_tc_buffer(const std::vector<zeus::CVector2f>& tcs) noexcept { tcData = &tcs; }
|
||||
void set_vertex_buffer(const std::vector<zeus::CVector3f>* data) noexcept { vtxData = data; }
|
||||
void set_normal_buffer(const std::vector<zeus::CVector3f>* norm) noexcept { nrmData = norm; }
|
||||
void set_tex0_tc_buffer(const std::vector<Vec2<float>>* tcs) noexcept { tex0TcData = tcs; }
|
||||
void set_tc_buffer(const std::vector<Vec2<float>>* tcs) noexcept { tcData = tcs; }
|
||||
|
||||
enum class VertexFormat : u8 {
|
||||
F32F32,
|
||||
|
@ -170,12 +170,12 @@ void queue_surface(const u8* dlStart, u32 dlSize) noexcept {
|
|||
const auto idxRange = push_indices(ArrayRef{indices});
|
||||
const auto sVtxRange = push_storage(reinterpret_cast<const uint8_t*>(vtxData->data()), vtxData->size() * 16);
|
||||
const auto sNrmRange = push_storage(reinterpret_cast<const uint8_t*>(nrmData->data()), nrmData->size() * 16);
|
||||
const auto sTcRange = push_storage(reinterpret_cast<const uint8_t*>(tcData->data()), tcData->size() * 16);
|
||||
const auto sTcRange = push_storage(reinterpret_cast<const uint8_t*>(tcData->data()), tcData->size() * 8);
|
||||
Range sPackedTcRange;
|
||||
if (tcData == tex0TcData) {
|
||||
sPackedTcRange = sTcRange;
|
||||
} else {
|
||||
sPackedTcRange = push_storage(reinterpret_cast<const uint8_t*>(tex0TcData->data()), tex0TcData->size() * 16);
|
||||
sPackedTcRange = push_storage(reinterpret_cast<const uint8_t*>(tex0TcData->data()), tex0TcData->size() * 8);
|
||||
}
|
||||
|
||||
model::PipelineConfig config{};
|
||||
|
|
|
@ -130,27 +130,38 @@ void write_texture(const TextureHandle& handle, ArrayRef<uint8_t> data) noexcept
|
|||
}
|
||||
}
|
||||
|
||||
const auto dstView = wgpu::ImageCopyTexture{
|
||||
.texture = ref.texture,
|
||||
};
|
||||
if (ref.size.depthOrArrayLayers != 1) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("write_texture: unsupported depth {}"), ref.size.depthOrArrayLayers);
|
||||
unreachable();
|
||||
uint32_t offset = 0;
|
||||
for (uint32_t mip = 0; mip < ref.mipCount; ++mip) {
|
||||
const auto mipSize = wgpu::Extent3D{
|
||||
.width = std::max(ref.size.width >> mip, 1u),
|
||||
.height = std::max(ref.size.height >> mip, 1u),
|
||||
.depthOrArrayLayers = ref.size.depthOrArrayLayers,
|
||||
};
|
||||
const auto info = format_info(ref.format);
|
||||
const auto physicalSize = physical_size(mipSize, info);
|
||||
const uint32_t widthBlocks = physicalSize.width / info.blockWidth;
|
||||
const uint32_t heightBlocks = physicalSize.height / info.blockHeight;
|
||||
const uint32_t bytesPerRow = widthBlocks * info.blockSize;
|
||||
const uint32_t dataSize = bytesPerRow * heightBlocks * mipSize.depthOrArrayLayers;
|
||||
if (offset + dataSize > data.size()) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("write_texture: expected at least {} bytes, got {}"), offset + dataSize,
|
||||
data.size());
|
||||
unreachable();
|
||||
}
|
||||
const auto dstView = wgpu::ImageCopyTexture{
|
||||
.texture = ref.texture,
|
||||
.mipLevel = mip,
|
||||
};
|
||||
const auto dataLayout = wgpu::TextureDataLayout{
|
||||
.bytesPerRow = bytesPerRow,
|
||||
.rowsPerImage = heightBlocks,
|
||||
};
|
||||
g_queue.WriteTexture(&dstView, data.data() + offset, dataSize, &dataLayout, &physicalSize);
|
||||
offset += dataSize;
|
||||
}
|
||||
const auto info = format_info(ref.format);
|
||||
const auto physicalSize = physical_size(ref.size, info);
|
||||
const uint32_t widthBlocks = physicalSize.width / info.blockWidth;
|
||||
const uint32_t heightBlocks = physicalSize.height / info.blockHeight;
|
||||
const uint32_t bytesPerRow = widthBlocks * info.blockSize;
|
||||
const uint32_t dataSize = bytesPerRow * heightBlocks * ref.size.depthOrArrayLayers;
|
||||
if (dataSize > data.size()) {
|
||||
Log.report(logvisor::Fatal, FMT_STRING("write_texture: expected at least {} bytes, got {}"), dataSize, data.size());
|
||||
unreachable();
|
||||
if (offset < data.size()) {
|
||||
Log.report(logvisor::Warning, FMT_STRING("write_texture: texture used {} bytes, but given {} bytes"), offset,
|
||||
data.size());
|
||||
}
|
||||
const auto dataLayout = wgpu::TextureDataLayout{
|
||||
.bytesPerRow = bytesPerRow,
|
||||
.rowsPerImage = heightBlocks,
|
||||
};
|
||||
g_queue.WriteTexture(&dstView, data.data(), dataSize, &dataLayout, &ref.size);
|
||||
}
|
||||
} // namespace aurora::gfx
|
||||
|
|
|
@ -102,7 +102,7 @@ static TextureWithSampler create_depth_texture() {
|
|||
}
|
||||
|
||||
static void error_callback(WGPUErrorType type, char const* message, void* userdata) {
|
||||
Log.report(logvisor::Error, FMT_STRING("Dawn error {}: {}"),
|
||||
Log.report(logvisor::Fatal, FMT_STRING("Dawn error {}: {}"),
|
||||
magic_enum::enum_name(static_cast<wgpu::ErrorType>(type)), message);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue