Various model rendering fixes

This commit is contained in:
Luke Street 2022-03-08 02:44:46 -05:00
parent eb17b8061d
commit e0a7236ad6
16 changed files with 236 additions and 147 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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:

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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));

View File

@ -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);

View File

@ -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{};

View File

@ -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

View File

@ -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);
}