From a2743b905bc22ca687c7849f8f09f799ee5ab239 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 8 Mar 2022 03:52:36 -0500 Subject: [PATCH] aurora: model fixes, texture_convert fixes --- Runtime/World/CWorldShadow.cpp | 1 + aurora/lib/gfx/common.cpp | 115 ++++++++++++++++++++++++++++- aurora/lib/gfx/common.hpp | 6 +- aurora/lib/gfx/gx.cpp | 2 +- aurora/lib/gfx/gx.hpp | 6 +- aurora/lib/gfx/gx_shader.cpp | 2 +- aurora/lib/gfx/model/shader.hpp | 13 +--- aurora/lib/gfx/texture_convert.cpp | 31 ++++---- 8 files changed, 138 insertions(+), 38 deletions(-) diff --git a/Runtime/World/CWorldShadow.cpp b/Runtime/World/CWorldShadow.cpp index b90fab22a..5ad6de448 100644 --- a/Runtime/World/CWorldShadow.cpp +++ b/Runtime/World/CWorldShadow.cpp @@ -36,6 +36,7 @@ void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid x84_lightIdx = lightIdx; } + return; // TODO if (aid != kInvalidAreaId) { const CGameArea* area = mgr.GetWorld()->GetAreaAlways(aid); if (area->IsPostConstructed()) { diff --git a/aurora/lib/gfx/common.cpp b/aurora/lib/gfx/common.cpp index f6be4605f..447013069 100644 --- a/aurora/lib/gfx/common.cpp +++ b/aurora/lib/gfx/common.cpp @@ -68,7 +68,115 @@ struct Command { ShaderDrawCommand draw; } data; }; +} // namespace aurora::gfx +namespace aurora { +template <> +inline void xxh3_update(XXH3_state_t& state, const gfx::colored_quad::PipelineConfig& input) { + XXH3_64bits_update(&state, &input.filterType, sizeof(gfx::colored_quad::PipelineConfig::filterType)); + XXH3_64bits_update(&state, &input.zComparison, sizeof(gfx::colored_quad::PipelineConfig::zComparison)); + XXH3_64bits_update(&state, &input.zTest, sizeof(gfx::colored_quad::PipelineConfig::zTest)); +} +template <> +inline void xxh3_update(XXH3_state_t& state, const gfx::textured_quad::PipelineConfig& input) { + XXH3_64bits_update(&state, &input.filterType, sizeof(gfx::textured_quad::PipelineConfig::filterType)); + XXH3_64bits_update(&state, &input.zComparison, sizeof(gfx::textured_quad::PipelineConfig::zComparison)); + XXH3_64bits_update(&state, &input.zTest, sizeof(gfx::textured_quad::PipelineConfig::zTest)); +} +template <> +inline void xxh3_update(XXH3_state_t& state, const gfx::movie_player::PipelineConfig& input) { + // no-op +} +template <> +inline void xxh3_update(XXH3_state_t& state, const gfx::gx::PipelineConfig& input) { + xxh3_update(state, input.shaderConfig); + XXH3_64bits_update(&state, &input.primitive, sizeof(gfx::gx::PipelineConfig::primitive)); + XXH3_64bits_update(&state, &input.depthFunc, sizeof(gfx::gx::PipelineConfig::depthFunc)); + XXH3_64bits_update(&state, &input.cullMode, sizeof(gfx::gx::PipelineConfig::cullMode)); + XXH3_64bits_update(&state, &input.blendMode, sizeof(gfx::gx::PipelineConfig::blendMode)); + XXH3_64bits_update(&state, &input.blendFacSrc, sizeof(gfx::gx::PipelineConfig::blendFacSrc)); + XXH3_64bits_update(&state, &input.blendFacDst, sizeof(gfx::gx::PipelineConfig::blendFacDst)); + XXH3_64bits_update(&state, &input.blendOp, sizeof(gfx::gx::PipelineConfig::blendOp)); + if (input.dstAlpha) { + XXH3_64bits_update(&state, &*input.dstAlpha, sizeof(float)); + } + XXH3_64bits_update(&state, &input.depthCompare, sizeof(gfx::gx::PipelineConfig::depthCompare)); + XXH3_64bits_update(&state, &input.depthUpdate, sizeof(gfx::gx::PipelineConfig::depthUpdate)); + XXH3_64bits_update(&state, &input.alphaUpdate, sizeof(gfx::gx::PipelineConfig::alphaUpdate)); +} +template <> +inline void xxh3_update(XXH3_state_t& state, const gfx::stream::PipelineConfig& input) { + xxh3_update(state, input); +} +template <> +inline void xxh3_update(XXH3_state_t& state, const gfx::model::PipelineConfig& input) { + xxh3_update(state, input); +} +template <> +inline void xxh3_update(XXH3_state_t& state, const gfx::PipelineCreateCommand& input) { + XXH3_64bits_update(&state, &input.type, sizeof(gfx::PipelineCreateCommand::type)); + switch (input.type) { + case gfx::ShaderType::Aabb: + // TODO + break; + case gfx::ShaderType::ColoredQuad: + xxh3_update(state, input.coloredQuad); + break; + case gfx::ShaderType::TexturedQuad: + xxh3_update(state, input.texturedQuad); + break; + case gfx::ShaderType::MoviePlayer: + xxh3_update(state, input.moviePlayer); + break; + case gfx::ShaderType::Stream: + xxh3_update(state, input.stream); + break; + case gfx::ShaderType::Model: + xxh3_update(state, input.model); + break; + } +} +template <> +inline void xxh3_update(XXH3_state_t& state, const wgpu::BindGroupEntry& input) { + XXH3_64bits_update(&state, &input.binding, sizeof(wgpu::BindGroupEntry::binding)); + XXH3_64bits_update(&state, &input.buffer, sizeof(wgpu::BindGroupEntry::buffer)); + XXH3_64bits_update(&state, &input.offset, sizeof(wgpu::BindGroupEntry::offset)); + if (input.buffer != nullptr) { + XXH3_64bits_update(&state, &input.size, sizeof(wgpu::BindGroupEntry::size)); + } + XXH3_64bits_update(&state, &input.sampler, sizeof(wgpu::BindGroupEntry::sampler)); + XXH3_64bits_update(&state, &input.textureView, sizeof(wgpu::BindGroupEntry::textureView)); +} +template <> +inline void xxh3_update(XXH3_state_t& state, const wgpu::BindGroupDescriptor& input) { + if (input.label != nullptr) { + XXH3_64bits_update(&state, input.label, strlen(input.label)); + } + XXH3_64bits_update(&state, &input.layout, sizeof(wgpu::BindGroupDescriptor::layout)); + XXH3_64bits_update(&state, &input.entryCount, sizeof(wgpu::BindGroupDescriptor::entryCount)); + for (int i = 0; i < input.entryCount; ++i) { + xxh3_update(state, input.entries[i]); + } +} +template <> +inline void xxh3_update(XXH3_state_t& state, const wgpu::SamplerDescriptor& input) { + if (input.label != nullptr) { + XXH3_64bits_update(&state, input.label, strlen(input.label)); + } + XXH3_64bits_update(&state, &input.addressModeU, sizeof(wgpu::SamplerDescriptor::addressModeU)); + XXH3_64bits_update(&state, &input.addressModeV, sizeof(wgpu::SamplerDescriptor::addressModeV)); + XXH3_64bits_update(&state, &input.addressModeW, sizeof(wgpu::SamplerDescriptor::addressModeW)); + XXH3_64bits_update(&state, &input.magFilter, sizeof(wgpu::SamplerDescriptor::magFilter)); + XXH3_64bits_update(&state, &input.minFilter, sizeof(wgpu::SamplerDescriptor::minFilter)); + XXH3_64bits_update(&state, &input.mipmapFilter, sizeof(wgpu::SamplerDescriptor::mipmapFilter)); + XXH3_64bits_update(&state, &input.lodMinClamp, sizeof(wgpu::SamplerDescriptor::lodMinClamp)); + XXH3_64bits_update(&state, &input.lodMaxClamp, sizeof(wgpu::SamplerDescriptor::lodMaxClamp)); + XXH3_64bits_update(&state, &input.compare, sizeof(wgpu::SamplerDescriptor::compare)); + XXH3_64bits_update(&state, &input.maxAnisotropy, sizeof(wgpu::SamplerDescriptor::maxAnisotropy)); +} +} // namespace aurora + +namespace aurora::gfx { using NewPipelineCallback = std::function; std::mutex g_pipelineMutex; static std::thread g_pipelineThread; @@ -188,8 +296,8 @@ PipelineRef pipeline_ref(colored_quad::PipelineConfig config) { [=]() { return create_pipeline(g_state.coloredQuad, config); }); } -void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v, - float h_pad, float v_pad) noexcept { +void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v, float h_pad, + float v_pad) noexcept { auto data = movie_player::make_draw_data(g_state.moviePlayer, tex_y, tex_u, tex_v, h_pad, v_pad); push_draw_command({.type = ShaderType::MoviePlayer, .moviePlayer = data}); } @@ -422,8 +530,7 @@ Range push_storage(const uint8_t* data, size_t length) { } BindGroupRef bind_group_ref(const wgpu::BindGroupDescriptor& descriptor) { - const auto id = - xxh3_hash(descriptor.entries, descriptor.entryCount * sizeof(wgpu::BindGroupEntry), xxh3_hash(descriptor)); + const auto id = xxh3_hash(descriptor); if (!g_cachedBindGroups.contains(id)) { g_cachedBindGroups[id] = g_device.CreateBindGroup(&descriptor); } diff --git a/aurora/lib/gfx/common.hpp b/aurora/lib/gfx/common.hpp index 0e2b99175..2a519e2fd 100644 --- a/aurora/lib/gfx/common.hpp +++ b/aurora/lib/gfx/common.hpp @@ -18,7 +18,11 @@ static inline XXH64_hash_t xxh3_hash(const void* input, size_t len, XXH64_hash_t } template static inline XXH64_hash_t xxh3_hash(const T& input, XXH64_hash_t seed = 0) { - return xxh3_hash(&input, sizeof(T), seed); + XXH3_state_t state; + memset(&state, 0, sizeof(XXH3_state_t)); + XXH3_64bits_reset_withSeed(&state, seed); + xxh3_update(state, input); + return XXH3_64bits_digest(&state); } class ByteBuffer { diff --git a/aurora/lib/gfx/gx.cpp b/aurora/lib/gfx/gx.cpp index 64dbd09f4..8f3bf0931 100644 --- a/aurora/lib/gfx/gx.cpp +++ b/aurora/lib/gfx/gx.cpp @@ -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(stage)].reset(); } diff --git a/aurora/lib/gfx/gx.hpp b/aurora/lib/gfx/gx.hpp index ccc75d06e..3279a8db0 100644 --- a/aurora/lib/gfx/gx.hpp +++ b/aurora/lib/gfx/gx.hpp @@ -164,10 +164,7 @@ inline void xxh3_update(XXH3_state_t& state, const gfx::gx::STevStage& input) { 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; - memset(&state, 0, sizeof(XXH3_state_t)); - XXH3_64bits_reset_withSeed(&state, seed); +inline void xxh3_update(XXH3_state_t& state, const gfx::gx::ShaderConfig& input) { for (const auto& item : input.tevStages) { if (!item) { break; @@ -180,6 +177,5 @@ inline XXH64_hash_t xxh3_hash(const gfx::gx::ShaderConfig& input, XXH64_hash_t s XXH3_64bits_update(&state, &input.alphaDiscard, sizeof(bool)); XXH3_64bits_update(&state, &input.denormalizedVertexAttributes, sizeof(bool)); XXH3_64bits_update(&state, &input.denormalizedHasNrm, sizeof(bool)); - return XXH3_64bits_digest(&state); } } // namespace aurora diff --git a/aurora/lib/gfx/gx_shader.cpp b/aurora/lib/gfx/gx_shader.cpp index d447af852..2999ce507 100644 --- a/aurora/lib/gfx/gx_shader.cpp +++ b/aurora/lib/gfx/gx_shader.cpp @@ -530,7 +530,7 @@ var v_packed_uvs: Vec2Block; } info.usesVtxColor = true; } else { - fragmentFnPre += fmt::format(FMT_STRING("\n var rast{0} = ubuf.cc{0}_mat; // TODO lighting"), i); + fragmentFnPre += fmt::format(FMT_STRING("\n var rast{0} = ubuf.cc{0}_amb; // TODO lighting"), i); } } for (int i = 0; i < info.sampledKcolors.size(); ++i) { diff --git a/aurora/lib/gfx/model/shader.hpp b/aurora/lib/gfx/model/shader.hpp index 860d7e914..a2e83bf87 100644 --- a/aurora/lib/gfx/model/shader.hpp +++ b/aurora/lib/gfx/model/shader.hpp @@ -19,18 +19,9 @@ struct DrawData { gx::GXBindGroups bindGroups; }; -struct PipelineConfig : gx::PipelineConfig { +struct PipelineConfig : gx::PipelineConfig {}; -}; - -struct CachedBindGroup { - wgpu::BindGroupLayout layout; - wgpu::BindGroup bindGroup; - CachedBindGroup(wgpu::BindGroupLayout layout, wgpu::BindGroup&& group) - : layout(std::move(layout)), bindGroup(std::move(group)) {} -}; -struct State { -}; +struct State {}; State construct_state(); wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] PipelineConfig config); diff --git a/aurora/lib/gfx/texture_convert.cpp b/aurora/lib/gfx/texture_convert.cpp index 9d1839904..8273a4ff8 100644 --- a/aurora/lib/gfx/texture_convert.cpp +++ b/aurora/lib/gfx/texture_convert.cpp @@ -66,6 +66,17 @@ static size_t ComputeMippedBlockCountDXT1(u32 w, u32 h, u32 mips) { return ret; } +template +constexpr T bswap16(T val) noexcept { +#if __GNUC__ + return __builtin_bswap16(val); +#elif _WIN32 + return _byteswap_ushort(val); +#else + return (val = (val << 8) | ((val >> 8) & 0xFF)); +#endif +} + static ByteBuffer BuildI4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { const size_t texelCount = ComputeMippedTexelCount(width, height, mips); ByteBuffer buf{sizeof(RGBA8) * texelCount}; @@ -205,11 +216,12 @@ ByteBuffer BuildIA8FromGCN(uint32_t width, uint32_t height, uint32_t mips, Array for (uint32_t y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; for (size_t x = 0; x < 4; ++x) { - const u8 intensity = in[x] >> 8; + const auto texel = bswap16(in[x]); + const u8 intensity = texel >> 8; target[x].r = intensity; target[x].g = intensity; target[x].b = intensity; - target[x].a = in[x] & 0xff; + target[x].a = texel & 0xff; } in += 4; } @@ -319,7 +331,7 @@ ByteBuffer BuildRGB565FromGCN(uint32_t width, uint32_t height, uint32_t mips, Ar for (uint32_t y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; for (size_t x = 0; x < 4; ++x) { - const auto texel = in[x]; + const auto texel = bswap16(in[x]); target[x].r = Convert5To8(texel >> 11 & 0x1f); target[x].g = Convert6To8(texel >> 5 & 0x3f); target[x].b = Convert5To8(texel & 0x1f); @@ -359,7 +371,7 @@ ByteBuffer BuildRGB5A3FromGCN(uint32_t width, uint32_t height, uint32_t mips, Ar for (uint32_t y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; for (size_t x = 0; x < 4; ++x) { - const auto texel = in[x]; + const auto texel = bswap16(in[x]); if ((texel & 0x8000) != 0) { target[x].r = Convert5To8(texel >> 10 & 0x1f); target[x].g = Convert5To8(texel >> 5 & 0x1f); @@ -432,17 +444,6 @@ ByteBuffer BuildRGBA8FromGCN(uint32_t width, uint32_t height, uint32_t mips, Arr return buf; } -template -constexpr T bswap16(T val) noexcept { -#if __GNUC__ - return __builtin_bswap16(val); -#elif _WIN32 - return _byteswap_ushort(val); -#else - return (val = (val << 8) | ((val >> 8) & 0xFF)); -#endif -} - ByteBuffer BuildDXT1FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef data) { const size_t blockCount = ComputeMippedBlockCountDXT1(width, height, mips); ByteBuffer buf{sizeof(DXT1Block) * blockCount};