mirror of https://github.com/AxioDL/metaforce.git
Implement HandleTransparency, lighting & fix texture load
This commit is contained in:
parent
a2743b905b
commit
e88f831950
|
@ -305,11 +305,36 @@ void CCubeMaterial::EnsureViewDepStateCached(const CCubeSurface* surface) {
|
||||||
u32 CCubeMaterial::HandleColorChannels(u32 chanCount, u32 firstChan) {
|
u32 CCubeMaterial::HandleColorChannels(u32 chanCount, u32 firstChan) {
|
||||||
if (CCubeModel::sRenderModelShadow) {
|
if (CCubeModel::sRenderModelShadow) {
|
||||||
if (chanCount != 0) {
|
if (chanCount != 0) {
|
||||||
// TODO
|
aurora::gfx::set_chan_amb_color(GX::COLOR1A1, zeus::skBlack);
|
||||||
|
aurora::gfx::set_chan_mat_color(GX::COLOR1A1, zeus::skWhite);
|
||||||
|
|
||||||
|
// TODO chan / lights
|
||||||
|
|
||||||
|
aurora::gfx::set_chan_mat_color(GX::COLOR0A0, zeus::skWhite);
|
||||||
}
|
}
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chanCount == 2) {
|
||||||
|
aurora::gfx::set_chan_amb_color(GX::COLOR1A1, zeus::skBlack);
|
||||||
|
aurora::gfx::set_chan_mat_color(GX::COLOR1A1, zeus::skWhite);
|
||||||
|
} else {
|
||||||
|
// TODO chan ctrls
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chanCount == 0) {
|
||||||
|
// TODO more chan ctrls
|
||||||
|
} else {
|
||||||
|
auto uVar3 = firstChan & 0xfffffffe;
|
||||||
|
// TODO enabled lights
|
||||||
|
// TODO chan ctrl
|
||||||
|
// if (sEnabledLights == 0) {
|
||||||
|
// aurora::gfx::set_chan_mat_color(GX::COLOR0A0, amb_clr);
|
||||||
|
// } else {
|
||||||
|
aurora::gfx::set_chan_mat_color(GX::COLOR0A0, zeus::skWhite);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
aurora::gfx::set_chan_mat_src(GX::COLOR0A0, GX::SRC_REG);
|
aurora::gfx::set_chan_mat_src(GX::COLOR0A0, GX::SRC_REG);
|
||||||
aurora::gfx::set_chan_mat_src(GX::COLOR1A1, GX::SRC_REG);
|
aurora::gfx::set_chan_mat_src(GX::COLOR1A1, GX::SRC_REG);
|
||||||
|
@ -385,36 +410,56 @@ void CCubeMaterial::HandleTransparency(u32& finalTevCount, u32& finalKColorCount
|
||||||
}
|
}
|
||||||
if (modelFlags.x0_blendMode == 3) {
|
if (modelFlags.x0_blendMode == 3) {
|
||||||
// Stage outputting splatted KAlpha as color to reg0
|
// Stage outputting splatted KAlpha as color to reg0
|
||||||
|
aurora::gfx::update_tev_stage(static_cast<ERglTevStage>(finalTevCount),
|
||||||
|
CTevCombiners::ColorPass{GX::CC_ZERO, GX::CC_ZERO, GX::CC_ZERO, GX::CC_KONST},
|
||||||
|
CTevCombiners::AlphaPass{GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_APREV},
|
||||||
|
CTevCombiners::CTevOp{true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, GX::TEVREG0},
|
||||||
|
CTevCombiners::CTevOp{true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, GX::TEVPREV});
|
||||||
// GXSetTevColorIn(finalTevCount, TEVCOLORARG_ZERO, TEVCOLORARG_ZERO, TEVCOLORARG_ZERO, TEVCOLORARG_KONST);
|
// GXSetTevColorIn(finalTevCount, TEVCOLORARG_ZERO, TEVCOLORARG_ZERO, TEVCOLORARG_ZERO, TEVCOLORARG_KONST);
|
||||||
// GXSetTevAlphaIn(finalTevCount, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_APREV);
|
// GXSetTevAlphaIn(finalTevCount, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_APREV);
|
||||||
// GXSetTevColorOp(finalTevCount, 0, 0, 0, 1, 1); // ColorReg0
|
// GXSetTevColorOp(finalTevCount, 0, 0, 0, 1, 1); // ColorReg0
|
||||||
|
aurora::gfx::set_tev_k_color_sel(static_cast<GX::TevStageID>(finalTevCount),
|
||||||
|
static_cast<GX::TevKColorSel>(finalKColorCount + GX::TEV_KCSEL_K0_A));
|
||||||
// GXSetTevKColorSel(finalTevCount, finalKColorCount+28);
|
// GXSetTevKColorSel(finalTevCount, finalKColorCount+28);
|
||||||
// GXSetTevAlphaOp(finalTevCount, 0, 0, 0, 1, 0); // AlphaRegPrev
|
// GXSetTevAlphaOp(finalTevCount, 0, 0, 0, 1, 0); // AlphaRegPrev
|
||||||
// GXSetTevOrder(finalTevCount, 255, 255, 255);
|
// GXSetTevOrder(finalTevCount, 255, 255, 255);
|
||||||
// GXSetTevDirect(finalTevCount);
|
// GXSetTevDirect(finalTevCount);
|
||||||
// Stage interpolating from splatted KAlpha using KColor
|
// Stage interpolating from splatted KAlpha using KColor
|
||||||
|
aurora::gfx::update_tev_stage(static_cast<ERglTevStage>(finalTevCount + 1),
|
||||||
|
CTevCombiners::ColorPass{GX::CC_CPREV, GX::CC_C0, GX::CC_KONST, GX::CC_ZERO},
|
||||||
|
CTevCombiners::AlphaPass{GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_APREV},
|
||||||
|
CTevCombiners::CTevOp{true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, GX::TEVPREV},
|
||||||
|
CTevCombiners::CTevOp{true, GX::TEV_ADD, GX::TB_ZERO, GX::CS_SCALE_1, GX::TEVPREV});
|
||||||
// GXSetTevColorIn(finalTevCount + 1, TEVCOLORARG_CPREV, TEVCOLORARG_C0, TEVCOLORARG_KONST, TEVCOLORARG_ZERO);
|
// GXSetTevColorIn(finalTevCount + 1, TEVCOLORARG_CPREV, TEVCOLORARG_C0, TEVCOLORARG_KONST, TEVCOLORARG_ZERO);
|
||||||
// GXSetTevAlphaIn(finalTevCount + 1, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_APREV);
|
// GXSetTevAlphaIn(finalTevCount + 1, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_APREV);
|
||||||
|
aurora::gfx::set_tev_k_color_sel(static_cast<GX::TevStageID>(finalTevCount + 1),
|
||||||
|
static_cast<GX::TevKColorSel>(finalKColorCount + GX::TEV_KCSEL_K0));
|
||||||
// GXSetTevKColorSel(finalTevCount, finalKColorCount+12);
|
// GXSetTevKColorSel(finalTevCount, finalKColorCount+12);
|
||||||
// SetStandardTevColorAlphaOp(finalTevCount + 1);
|
// SetStandardTevColorAlphaOp(finalTevCount + 1);
|
||||||
// GXSetTevDirect(finalTevCount + 1);
|
// GXSetTevDirect(finalTevCount + 1);
|
||||||
// GXSetTevOrder(finalTevCount + 1, 255, 255, 255);
|
// GXSetTevOrder(finalTevCount + 1, 255, 255, 255);
|
||||||
|
aurora::gfx::set_tev_k_color(static_cast<GX::TevKColorID>(finalKColorCount), modelFlags.x4_color);
|
||||||
// GXSetTevKColor(finalKColorCount, modelFlags.x4_color);
|
// GXSetTevKColor(finalKColorCount, modelFlags.x4_color);
|
||||||
finalKColorCount += 1;
|
finalKColorCount += 1;
|
||||||
finalTevCount += 2;
|
finalTevCount += 2;
|
||||||
} else {
|
} else {
|
||||||
// Mul KAlpha
|
// Mul KAlpha
|
||||||
|
CTevCombiners::AlphaPass alphaPass{GX::CA_ZERO, GX::CA_KONST, GX::CA_APREV, GX::CA_ZERO};
|
||||||
u32 tevAlpha = 0x000380C7; // TEVALPHAARG_ZERO, TEVALPHAARG_KONST, TEVALPHAARG_APREV, TEVALPHAARG_ZERO
|
u32 tevAlpha = 0x000380C7; // TEVALPHAARG_ZERO, TEVALPHAARG_KONST, TEVALPHAARG_APREV, TEVALPHAARG_ZERO
|
||||||
if (modelFlags.x0_blendMode == 8) {
|
if (modelFlags.x0_blendMode == 8) {
|
||||||
// Set KAlpha
|
// Set KAlpha
|
||||||
|
alphaPass = {GX::CA_ZERO, GX::CA_ZERO, GX::CA_ZERO, GX::CA_KONST};
|
||||||
tevAlpha = 0x00031CE7; // TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_KONST
|
tevAlpha = 0x00031CE7; // TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_ZERO, TEVALPHAARG_KONST
|
||||||
}
|
}
|
||||||
// Mul KColor
|
// Mul KColor
|
||||||
|
CTevCombiners::ColorPass colorPass{GX::CC_ZERO, GX::CC_KONST, GX::CC_CPREV, GX::CC_ZERO};
|
||||||
u32 tevColor = 0x000781CF; // TEVCOLORARG_ZERO, TEVCOLORARG_KONST, TEVCOLORARG_CPREV, TEVCOLORARG_ZERO
|
u32 tevColor = 0x000781CF; // TEVCOLORARG_ZERO, TEVCOLORARG_KONST, TEVCOLORARG_CPREV, TEVCOLORARG_ZERO
|
||||||
if (modelFlags.x0_blendMode == 2) {
|
if (modelFlags.x0_blendMode == 2) {
|
||||||
// Add KColor
|
// Add KColor
|
||||||
|
colorPass = {GX::CC_ZERO, GX::CC_ONE, GX::CC_CPREV, GX::CC_KONST};
|
||||||
tevColor = 0x0007018F; // TEVCOLORARG_ZERO, TEVCOLORARG_ONE, TEVCOLORARG_CPREV, TEVCOLORARG_KONST
|
tevColor = 0x0007018F; // TEVCOLORARG_ZERO, TEVCOLORARG_ONE, TEVCOLORARG_CPREV, TEVCOLORARG_KONST
|
||||||
}
|
}
|
||||||
|
aurora::gfx::update_tev_stage(static_cast<ERglTevStage>(finalTevCount), colorPass, alphaPass, {}, {});
|
||||||
// GXSetTevColorIn(finalTevCount)
|
// GXSetTevColorIn(finalTevCount)
|
||||||
// GXSetTevAlphaIn(finalTevCount)
|
// GXSetTevAlphaIn(finalTevCount)
|
||||||
// SetStandardTevColorAlphaOp(finalTevCount);
|
// SetStandardTevColorAlphaOp(finalTevCount);
|
||||||
|
@ -422,8 +467,13 @@ void CCubeMaterial::HandleTransparency(u32& finalTevCount, u32& finalKColorCount
|
||||||
finalACFlags = 0x100;
|
finalACFlags = 0x100;
|
||||||
// GXSetTevDirect(finalTevCount);
|
// GXSetTevDirect(finalTevCount);
|
||||||
// GXSetTevOrder(finalTevCount, 255, 255, 255);
|
// GXSetTevOrder(finalTevCount, 255, 255, 255);
|
||||||
|
aurora::gfx::set_tev_k_color(static_cast<GX::TevKColorID>(finalKColorCount), modelFlags.x4_color);
|
||||||
// GXSetTevKColor(finalKColorCount, modelFlags.x4_color);
|
// GXSetTevKColor(finalKColorCount, modelFlags.x4_color);
|
||||||
|
aurora::gfx::set_tev_k_color_sel(static_cast<GX::TevStageID>(finalKColorCount),
|
||||||
|
static_cast<GX::TevKColorSel>(finalKColorCount + GX::TEV_KCSEL_K0));
|
||||||
// GXSetTevKColorSel(finalTevCount, finalKColorCount+12);
|
// GXSetTevKColorSel(finalTevCount, finalKColorCount+12);
|
||||||
|
aurora::gfx::set_tev_k_alpha_sel(static_cast<GX::TevStageID>(finalTevCount),
|
||||||
|
static_cast<GX::TevKAlphaSel>(finalKColorCount + GX::TEV_KASEL_K0_A));
|
||||||
// GXSetTevKAlphaSel(finalTevCount, finalKColorCount+28);
|
// GXSetTevKAlphaSel(finalTevCount, finalKColorCount+28);
|
||||||
finalTevCount += 1;
|
finalTevCount += 1;
|
||||||
finalKColorCount += 1;
|
finalKColorCount += 1;
|
||||||
|
@ -473,8 +523,8 @@ void CCubeMaterial::EnsureTevsDirect() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//CGX::SetNumIndStages(0);
|
// CGX::SetNumIndStages(0);
|
||||||
//CGX::SetTevDirect(sCurrentTevStage);
|
// CGX::SetTevDirect(sCurrentTevStage);
|
||||||
sCurrentTevStage = GX::NULL_STAGE;
|
sCurrentTevStage = GX::NULL_STAGE;
|
||||||
}
|
}
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -78,7 +78,7 @@ bool CCubeModel::TryLockTextures() {
|
||||||
}
|
}
|
||||||
if (loadTexture) {
|
if (loadTexture) {
|
||||||
// texture->LoadToMRAM();
|
// texture->LoadToMRAM();
|
||||||
texturesPumped = true;
|
// texturesPumped = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!texturesPumped) {
|
if (!texturesPumped) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ add_library(aurora STATIC
|
||||||
lib/imgui.cpp
|
lib/imgui.cpp
|
||||||
lib/input.cpp
|
lib/input.cpp
|
||||||
lib/dawn/BackendBinding.cpp
|
lib/dawn/BackendBinding.cpp
|
||||||
lib/dawn/Hacks.cpp
|
|
||||||
lib/gfx/common.cpp
|
lib/gfx/common.cpp
|
||||||
lib/gfx/texture.cpp
|
lib/gfx/texture.cpp
|
||||||
lib/gfx/stream.cpp
|
lib/gfx/stream.cpp
|
||||||
|
|
|
@ -248,9 +248,9 @@ enum class ZComp : uint8_t {
|
||||||
|
|
||||||
constexpr u32 MaxLights = 8;
|
constexpr u32 MaxLights = 8;
|
||||||
struct Light {
|
struct Light {
|
||||||
zeus::CVector3f pos;
|
zeus::CVector3f pos{0.f, 0.f, 0.f};
|
||||||
zeus::CVector3f dir;
|
zeus::CVector3f dir{0.f, 0.f, -1.f};
|
||||||
zeus::CColor color;
|
zeus::CColor color{0.f, 0.f, 0.f, 0.f};
|
||||||
zeus::CVector3f linAtt{1.f, 0.f, 0.f};
|
zeus::CVector3f linAtt{1.f, 0.f, 0.f};
|
||||||
zeus::CVector3f angAtt{1.f, 0.f, 0.f};
|
zeus::CVector3f angAtt{1.f, 0.f, 0.f};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#include "Hacks.hpp"
|
|
||||||
|
|
||||||
#include "dawn/native/Device.h"
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include "dawn/native/d3d12/AdapterD3D12.h"
|
|
||||||
#include "dawn/native/d3d12/BackendD3D12.h"
|
|
||||||
#include "dawn/native/d3d12/DeviceD3D12.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace dawn::native {
|
|
||||||
class HackedDevice : public DeviceBase {
|
|
||||||
public:
|
|
||||||
void _ForceSetToggle(Toggle toggle, bool isEnabled) { ForceSetToggle(toggle, isEnabled); }
|
|
||||||
};
|
|
||||||
} // namespace dawn::native
|
|
||||||
|
|
||||||
namespace aurora::gpu::hacks {
|
|
||||||
void apply_toggles(WGPUDevice device) {
|
|
||||||
auto* hack = static_cast<dawn::native::HackedDevice*>(static_cast<void*>(device));
|
|
||||||
hack->_ForceSetToggle(dawn::native::Toggle::UseUserDefinedLabelsInBackend, true);
|
|
||||||
#if _WIN32
|
|
||||||
hack->_ForceSetToggle(dawn::native::Toggle::UseDXC, true);
|
|
||||||
auto* backend = dawn::native::d3d12::ToBackend(hack->GetAdapter())->GetBackend();
|
|
||||||
backend->EnsureDxcCompiler();
|
|
||||||
backend->EnsureDxcLibrary();
|
|
||||||
backend->EnsureDxcValidator();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} // namespace aurora::gpu::hacks
|
|
|
@ -1,10 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <dawn/webgpu.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helpers to expose private Dawn APIs
|
|
||||||
*/
|
|
||||||
namespace aurora::gpu::hacks {
|
|
||||||
void apply_toggles(WGPUDevice device);
|
|
||||||
} // namespace aurora::gpu::hacks
|
|
|
@ -424,24 +424,18 @@ void shutdown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(const wgpu::RenderPassEncoder& pass) {
|
void render(const wgpu::RenderPassEncoder& pass) {
|
||||||
{
|
const auto writeBuffer = [](ByteBuffer& buf, wgpu::Buffer& out) {
|
||||||
if (g_verts.size() > 0) {
|
const auto size = buf.size();
|
||||||
g_queue.WriteBuffer(g_vertexBuffer, 0, g_verts.data(), g_verts.size());
|
if (size > 0) {
|
||||||
g_verts.clear();
|
g_queue.WriteBuffer(out, 0, buf.data(), size);
|
||||||
|
buf.clear();
|
||||||
|
buf.reserve_extra(size); // Reserve size from previous frame
|
||||||
}
|
}
|
||||||
if (g_uniforms.size() > 0) {
|
};
|
||||||
g_queue.WriteBuffer(g_uniformBuffer, 0, g_uniforms.data(), g_uniforms.size());
|
writeBuffer(g_verts, g_vertexBuffer);
|
||||||
g_uniforms.clear();
|
writeBuffer(g_uniforms, g_uniformBuffer);
|
||||||
}
|
writeBuffer(g_indices, g_indexBuffer);
|
||||||
if (g_indices.size() > 0) {
|
writeBuffer(g_storage, g_storageBuffer);
|
||||||
g_queue.WriteBuffer(g_indexBuffer, 0, g_indices.data(), g_indices.size());
|
|
||||||
g_indices.clear();
|
|
||||||
}
|
|
||||||
if (g_storage.size() > 0) {
|
|
||||||
g_queue.WriteBuffer(g_storageBuffer, 0, g_storage.data(), g_storage.size());
|
|
||||||
g_storage.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_currentPipeline = UINT64_MAX;
|
g_currentPipeline = UINT64_MAX;
|
||||||
|
|
||||||
|
@ -514,7 +508,19 @@ static inline Range push(ByteBuffer& target, const uint8_t* data, size_t length,
|
||||||
target.append_zeroes(padding);
|
target.append_zeroes(padding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {begin, begin + length};
|
return {begin, begin + length + padding};
|
||||||
|
}
|
||||||
|
static inline Range map(ByteBuffer& target, size_t length, size_t alignment) {
|
||||||
|
size_t padding = 0;
|
||||||
|
if (alignment != 0) {
|
||||||
|
padding = alignment - length % alignment;
|
||||||
|
}
|
||||||
|
if (length == 0) {
|
||||||
|
length = alignment;
|
||||||
|
}
|
||||||
|
auto begin = target.size();
|
||||||
|
target.append_zeroes(length + padding);
|
||||||
|
return {begin, begin + length + padding};
|
||||||
}
|
}
|
||||||
Range push_verts(const uint8_t* data, size_t length) { return push(g_verts, data, length, 0 /* TODO? */); }
|
Range push_verts(const uint8_t* data, size_t length) { return push(g_verts, data, length, 0 /* TODO? */); }
|
||||||
Range push_indices(const uint8_t* data, size_t length) { return push(g_indices, data, length, 0 /* TODO? */); }
|
Range push_indices(const uint8_t* data, size_t length) { return push(g_indices, data, length, 0 /* TODO? */); }
|
||||||
|
@ -528,6 +534,26 @@ Range push_storage(const uint8_t* data, size_t length) {
|
||||||
g_device.GetLimits(&limits);
|
g_device.GetLimits(&limits);
|
||||||
return push(g_storage, data, length, limits.limits.minStorageBufferOffsetAlignment);
|
return push(g_storage, data, length, limits.limits.minStorageBufferOffsetAlignment);
|
||||||
}
|
}
|
||||||
|
std::pair<ByteBuffer, Range> map_verts(size_t length) {
|
||||||
|
const auto range = map(g_verts, length, 0 /* TODO? */);
|
||||||
|
return {ByteBuffer{g_verts.data() + range.first, range.second - range.first}, range};
|
||||||
|
}
|
||||||
|
std::pair<ByteBuffer, Range> map_indices(size_t length) {
|
||||||
|
const auto range = map(g_indices, length, 0 /* TODO? */);
|
||||||
|
return {ByteBuffer{g_indices.data() + range.first, range.second - range.first}, range};
|
||||||
|
}
|
||||||
|
std::pair<ByteBuffer, Range> map_uniform(size_t length) {
|
||||||
|
wgpu::SupportedLimits limits;
|
||||||
|
g_device.GetLimits(&limits);
|
||||||
|
const auto range = map(g_uniforms, length, limits.limits.minUniformBufferOffsetAlignment);
|
||||||
|
return {ByteBuffer{g_uniforms.data() + range.first, range.second - range.first}, range};
|
||||||
|
}
|
||||||
|
std::pair<ByteBuffer, Range> map_storage(size_t length) {
|
||||||
|
wgpu::SupportedLimits limits;
|
||||||
|
g_device.GetLimits(&limits);
|
||||||
|
const auto range = map(g_storage, length, limits.limits.minStorageBufferOffsetAlignment);
|
||||||
|
return {ByteBuffer{g_storage.data() + range.first, range.second - range.first}, range};
|
||||||
|
}
|
||||||
|
|
||||||
BindGroupRef bind_group_ref(const wgpu::BindGroupDescriptor& descriptor) {
|
BindGroupRef bind_group_ref(const wgpu::BindGroupDescriptor& descriptor) {
|
||||||
const auto id = xxh3_hash(descriptor);
|
const auto id = xxh3_hash(descriptor);
|
||||||
|
|
|
@ -30,26 +30,32 @@ public:
|
||||||
ByteBuffer() noexcept = default;
|
ByteBuffer() noexcept = default;
|
||||||
explicit ByteBuffer(size_t size) noexcept
|
explicit ByteBuffer(size_t size) noexcept
|
||||||
: m_data(static_cast<uint8_t*>(calloc(1, size))), m_length(size), m_capacity(size) {}
|
: m_data(static_cast<uint8_t*>(calloc(1, size))), m_length(size), m_capacity(size) {}
|
||||||
|
explicit ByteBuffer(uint8_t* data, size_t size) noexcept
|
||||||
|
: m_data(data), m_length(0), m_capacity(size), m_owned(false) {}
|
||||||
~ByteBuffer() noexcept {
|
~ByteBuffer() noexcept {
|
||||||
if (m_data != nullptr) {
|
if (m_data != nullptr && m_owned) {
|
||||||
free(m_data);
|
free(m_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ByteBuffer(ByteBuffer&& rhs) noexcept : m_data(rhs.m_data), m_length(rhs.m_length), m_capacity(rhs.m_capacity) {
|
ByteBuffer(ByteBuffer&& rhs) noexcept
|
||||||
|
: m_data(rhs.m_data), m_length(rhs.m_length), m_capacity(rhs.m_capacity), m_owned(rhs.m_owned) {
|
||||||
rhs.m_data = nullptr;
|
rhs.m_data = nullptr;
|
||||||
rhs.m_length = 0;
|
rhs.m_length = 0;
|
||||||
rhs.m_capacity = 0;
|
rhs.m_capacity = 0;
|
||||||
|
rhs.m_owned = true;
|
||||||
}
|
}
|
||||||
ByteBuffer& operator=(ByteBuffer&& rhs) noexcept {
|
ByteBuffer& operator=(ByteBuffer&& rhs) noexcept {
|
||||||
if (m_data != nullptr) {
|
if (m_data != nullptr && m_owned) {
|
||||||
free(m_data);
|
free(m_data);
|
||||||
}
|
}
|
||||||
m_data = rhs.m_data;
|
m_data = rhs.m_data;
|
||||||
m_length = rhs.m_length;
|
m_length = rhs.m_length;
|
||||||
m_capacity = rhs.m_capacity;
|
m_capacity = rhs.m_capacity;
|
||||||
|
m_owned = rhs.m_owned;
|
||||||
rhs.m_data = nullptr;
|
rhs.m_data = nullptr;
|
||||||
rhs.m_length = 0;
|
rhs.m_length = 0;
|
||||||
rhs.m_capacity = 0;
|
rhs.m_capacity = 0;
|
||||||
|
rhs.m_owned = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ByteBuffer(ByteBuffer const&) = delete;
|
ByteBuffer(ByteBuffer const&) = delete;
|
||||||
|
@ -61,38 +67,52 @@ public:
|
||||||
[[nodiscard]] bool empty() const noexcept { return m_length == 0; }
|
[[nodiscard]] bool empty() const noexcept { return m_length == 0; }
|
||||||
|
|
||||||
void append(const void* data, size_t size) {
|
void append(const void* data, size_t size) {
|
||||||
resize(m_length + size);
|
resize(m_length + size, false);
|
||||||
memcpy(m_data + m_length, data, size);
|
memcpy(m_data + m_length, data, size);
|
||||||
m_length += size;
|
m_length += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_zeroes(size_t size) {
|
void append_zeroes(size_t size) {
|
||||||
resize(m_length + size);
|
resize(m_length + size, true);
|
||||||
memset(m_data + m_length, 0, size);
|
|
||||||
m_length += size;
|
m_length += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
if (m_data != nullptr) {
|
if (m_data != nullptr && m_owned) {
|
||||||
free(m_data);
|
free(m_data);
|
||||||
}
|
}
|
||||||
m_data = nullptr;
|
m_data = nullptr;
|
||||||
m_length = 0;
|
m_length = 0;
|
||||||
m_capacity = 0;
|
m_capacity = 0;
|
||||||
|
m_owned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reserve_extra(size_t size) { resize(m_length + size, true); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t* m_data = nullptr;
|
uint8_t* m_data = nullptr;
|
||||||
size_t m_length = 0;
|
size_t m_length = 0;
|
||||||
size_t m_capacity = 0;
|
size_t m_capacity = 0;
|
||||||
|
bool m_owned = true;
|
||||||
|
|
||||||
void resize(size_t size) {
|
void resize(size_t size, bool zeroed) {
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
clear();
|
clear();
|
||||||
} else if (m_data == nullptr) {
|
} else if (m_data == nullptr) {
|
||||||
m_data = static_cast<uint8_t*>(malloc(size));
|
if (zeroed) {
|
||||||
|
m_data = static_cast<uint8_t*>(calloc(1, size));
|
||||||
|
} else {
|
||||||
|
m_data = static_cast<uint8_t*>(malloc(size));
|
||||||
|
}
|
||||||
|
m_owned = true;
|
||||||
} else if (size > m_capacity) {
|
} else if (size > m_capacity) {
|
||||||
|
if (!m_owned) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
m_data = static_cast<uint8_t*>(realloc(m_data, size));
|
m_data = static_cast<uint8_t*>(realloc(m_data, size));
|
||||||
|
if (zeroed) {
|
||||||
|
memset(m_data + m_capacity, 0, size - m_capacity);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -165,6 +185,10 @@ template <typename T>
|
||||||
static inline Range push_storage(const T& data) {
|
static inline Range push_storage(const T& data) {
|
||||||
return push_storage(reinterpret_cast<const uint8_t*>(&data), sizeof(T));
|
return push_storage(reinterpret_cast<const uint8_t*>(&data), sizeof(T));
|
||||||
}
|
}
|
||||||
|
std::pair<ByteBuffer, Range> map_verts(size_t length);
|
||||||
|
std::pair<ByteBuffer, Range> map_indices(size_t length);
|
||||||
|
std::pair<ByteBuffer, Range> map_uniform(size_t length);
|
||||||
|
std::pair<ByteBuffer, Range> map_storage(size_t length);
|
||||||
|
|
||||||
template <typename State>
|
template <typename State>
|
||||||
const State& get_state();
|
const State& get_state();
|
||||||
|
|
|
@ -363,29 +363,53 @@ ShaderInfo populate_pipeline_config(PipelineConfig& config, GX::Primitive primit
|
||||||
}
|
}
|
||||||
|
|
||||||
Range build_uniform(const ShaderInfo& info) noexcept {
|
Range build_uniform(const ShaderInfo& info) noexcept {
|
||||||
ByteBuffer uniBuf;
|
auto [buf, range] = map_uniform(info.uniformSize);
|
||||||
{
|
{
|
||||||
const auto xf = get_combined_matrix();
|
buf.append(&g_mv, 64);
|
||||||
uniBuf.append(&xf, 64);
|
buf.append(&g_mvInv, 64);
|
||||||
|
buf.append(&g_proj, 64);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < info.usesTevReg.size(); ++i) {
|
for (int i = 0; i < info.usesTevReg.size(); ++i) {
|
||||||
if (!info.usesTevReg.test(i)) {
|
if (!info.usesTevReg.test(i)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uniBuf.append(&g_colorRegs[i], 16);
|
buf.append(&g_colorRegs[i], 16);
|
||||||
|
}
|
||||||
|
if (info.sampledColorChannels.any()) {
|
||||||
|
zeus::CColor ambient = zeus::skClear;
|
||||||
|
int addedLights = 0;
|
||||||
|
for (int i = 0; i < g_lightState.size(); ++i) {
|
||||||
|
if (!g_lightState.test(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto& variant = g_lights[i];
|
||||||
|
if (std::holds_alternative<zeus::CColor>(variant)) {
|
||||||
|
ambient += std::get<zeus::CColor>(variant);
|
||||||
|
} else if (std::holds_alternative<Light>(variant)) {
|
||||||
|
static_assert(sizeof(Light) == 80);
|
||||||
|
buf.append(&std::get<Light>(variant), sizeof(Light));
|
||||||
|
++addedLights;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constexpr Light emptyLight{};
|
||||||
|
for (int i = addedLights; i < MaxLights; ++i) {
|
||||||
|
buf.append(&emptyLight, sizeof(Light));
|
||||||
|
}
|
||||||
|
buf.append(&ambient, 16);
|
||||||
|
// fmt::print(FMT_STRING("Added lights: {}, ambient: {},{},{},{}\n"), addedLights, ambient.r(), ambient.g(), ambient.b(), ambient.a());
|
||||||
}
|
}
|
||||||
for (int i = 0; i < info.sampledColorChannels.size(); ++i) {
|
for (int i = 0; i < info.sampledColorChannels.size(); ++i) {
|
||||||
if (!info.sampledColorChannels.test(i)) {
|
if (!info.sampledColorChannels.test(i)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uniBuf.append(&g_colorChannels[i].ambColor, 16);
|
buf.append(&g_colorChannels[i].ambColor, 16);
|
||||||
uniBuf.append(&g_colorChannels[i].matColor, 16);
|
buf.append(&g_colorChannels[i].matColor, 16);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < info.sampledKcolors.size(); ++i) {
|
for (int i = 0; i < info.sampledKcolors.size(); ++i) {
|
||||||
if (!info.sampledKcolors.test(i)) {
|
if (!info.sampledKcolors.test(i)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uniBuf.append(&g_kcolors[i], 16);
|
buf.append(&g_kcolors[i], 16);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < info.sampledTextures.size(); ++i) {
|
for (int i = 0; i < info.sampledTextures.size(); ++i) {
|
||||||
if (!info.sampledTextures.test(i)) {
|
if (!info.sampledTextures.test(i)) {
|
||||||
|
@ -396,9 +420,9 @@ Range build_uniform(const ShaderInfo& info) noexcept {
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("unbound texture {}"), i);
|
Log.report(logvisor::Fatal, FMT_STRING("unbound texture {}"), i);
|
||||||
unreachable();
|
unreachable();
|
||||||
}
|
}
|
||||||
uniBuf.append(&tex.lod, 4);
|
buf.append(&tex.lod, 4);
|
||||||
}
|
}
|
||||||
return push_uniform(uniBuf.data(), uniBuf.size());
|
return range;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unordered_map<u32, wgpu::BindGroupLayout> sUniformBindGroupLayouts;
|
static std::unordered_map<u32, wgpu::BindGroupLayout> sUniformBindGroupLayouts;
|
||||||
|
|
|
@ -342,7 +342,7 @@ std::pair<wgpu::ShaderModule, ShaderInfo> build_shader(const ShaderConfig& confi
|
||||||
|
|
||||||
Log.report(logvisor::Info, FMT_STRING("Shader config (hash {:x}):"), hash);
|
Log.report(logvisor::Info, FMT_STRING("Shader config (hash {:x}):"), hash);
|
||||||
ShaderInfo info{
|
ShaderInfo info{
|
||||||
.uniformSize = 64, // MVP MTX
|
.uniformSize = 64 * 3, // mv, mvInv, proj
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -383,6 +383,7 @@ std::pair<wgpu::ShaderModule, ShaderInfo> build_shader(const ShaderConfig& confi
|
||||||
Log.report(logvisor::Info, FMT_STRING(" denormalizedVertexAttributes: {}"), config.denormalizedVertexAttributes);
|
Log.report(logvisor::Info, FMT_STRING(" denormalizedVertexAttributes: {}"), config.denormalizedVertexAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string uniformPre;
|
||||||
std::string uniBufAttrs;
|
std::string uniBufAttrs;
|
||||||
std::string uniformBindings;
|
std::string uniformBindings;
|
||||||
std::string sampBindings;
|
std::string sampBindings;
|
||||||
|
@ -395,11 +396,15 @@ std::pair<wgpu::ShaderModule, ShaderInfo> build_shader(const ShaderConfig& confi
|
||||||
if (config.denormalizedVertexAttributes) {
|
if (config.denormalizedVertexAttributes) {
|
||||||
vtxInAttrs += "\n @location(0) in_pos: vec3<f32>";
|
vtxInAttrs += "\n @location(0) in_pos: vec3<f32>";
|
||||||
vtxOutAttrs += "\n @builtin(position) pos: vec4<f32>;";
|
vtxOutAttrs += "\n @builtin(position) pos: vec4<f32>;";
|
||||||
vtxXfrAttrsPre += "\n out.pos = ubuf.xf * vec4<f32>(in_pos, 1.0);";
|
vtxXfrAttrsPre += "\n var obj_pos = vec4<f32>(in_pos, 1.0);"
|
||||||
|
"\n var mv_pos = ubuf.mv * obj_pos;"
|
||||||
|
"\n out.pos = ubuf.proj * mv_pos;";
|
||||||
if (config.denormalizedHasNrm) {
|
if (config.denormalizedHasNrm) {
|
||||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) nrm: vec3<f32>;"), locIdx);
|
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) nrm: vec3<f32>;"), locIdx);
|
||||||
vtxInAttrs += fmt::format(FMT_STRING("\n , @location({}) in_nrm: vec3<f32>"), ++locIdx);
|
vtxInAttrs += fmt::format(FMT_STRING("\n , @location({}) in_nrm: vec3<f32>"), ++locIdx);
|
||||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.nrm = in_nrm;"));
|
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.nrm = in_nrm;"));
|
||||||
|
vtxXfrAttrsPre += "\n var obj_norm = vec4<f32>(in_nrm, 0.0);"
|
||||||
|
"\n var mv_norm = ubuf.mv_inv * obj_norm;";
|
||||||
info.usesNormal = true;
|
info.usesNormal = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -424,7 +429,11 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
||||||
"\n , @location(1) in_uv_0_4_idx: vec4<i32>"
|
"\n , @location(1) in_uv_0_4_idx: vec4<i32>"
|
||||||
"\n , @location(2) in_uv_5_7_idx: vec4<i32>";
|
"\n , @location(2) in_uv_5_7_idx: vec4<i32>";
|
||||||
vtxOutAttrs += "\n @builtin(position) pos: vec4<f32>;";
|
vtxOutAttrs += "\n @builtin(position) pos: vec4<f32>;";
|
||||||
vtxXfrAttrsPre += "\n out.pos = ubuf.xf * vec4<f32>(v_verts.data[in_pos_nrm_idx[0]].xyz, 1.0);";
|
vtxXfrAttrsPre += "\n var obj_pos = vec4<f32>(v_verts.data[in_pos_nrm_idx[0]].xyz, 1.0);"
|
||||||
|
"\n var obj_norm = vec4<f32>(v_verts.data[in_pos_nrm_idx[1]].xyz, 0.0);"
|
||||||
|
"\n var mv_pos = ubuf.mv * obj_pos;"
|
||||||
|
"\n var mv_norm = ubuf.mv_inv * obj_norm;"
|
||||||
|
"\n out.pos = ubuf.proj * mv_pos;";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string fragmentFnPre;
|
std::string fragmentFnPre;
|
||||||
|
@ -507,6 +516,20 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
||||||
}
|
}
|
||||||
uniBufAttrs += fmt::format(FMT_STRING("\n tevreg{}: vec4<f32>;"), i);
|
uniBufAttrs += fmt::format(FMT_STRING("\n tevreg{}: vec4<f32>;"), i);
|
||||||
fragmentFnPre += fmt::format(FMT_STRING("\n var tevreg{0} = ubuf.tevreg{0};"), i);
|
fragmentFnPre += fmt::format(FMT_STRING("\n var tevreg{0} = ubuf.tevreg{0};"), i);
|
||||||
|
info.uniformSize += 16;
|
||||||
|
}
|
||||||
|
if (info.sampledColorChannels.any()) {
|
||||||
|
uniformPre += "\n"
|
||||||
|
"struct Light {\n"
|
||||||
|
" pos: vec3<f32>;\n"
|
||||||
|
" dir: vec3<f32>;\n"
|
||||||
|
" color: vec4<f32>;\n"
|
||||||
|
" lin_att: vec3<f32>;\n"
|
||||||
|
" ang_att: vec3<f32>;\n"
|
||||||
|
"};";
|
||||||
|
uniBufAttrs += fmt::format(FMT_STRING("\n lights: array<Light, {}>;"), MaxLights);
|
||||||
|
uniBufAttrs += "\n lighting_ambient: vec4<f32>;";
|
||||||
|
info.uniformSize += (80 * MaxLights) + 16;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < info.sampledColorChannels.size(); ++i) {
|
for (int i = 0; i < info.sampledColorChannels.size(); ++i) {
|
||||||
if (!info.sampledColorChannels.test(i)) {
|
if (!info.sampledColorChannels.test(i)) {
|
||||||
|
@ -514,23 +537,46 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
uniBufAttrs += fmt::format(FMT_STRING("\n cc{0}_amb: vec4<f32>;"), i);
|
uniBufAttrs += fmt::format(FMT_STRING("\n cc{0}_amb: vec4<f32>;"), i);
|
||||||
uniBufAttrs += fmt::format(FMT_STRING("\n cc{0}_mat: vec4<f32>;"), i); // TODO not needed for SRC_VTX
|
uniBufAttrs += fmt::format(FMT_STRING("\n cc{0}_mat: vec4<f32>;"), i);
|
||||||
info.uniformSize += 32;
|
info.uniformSize += 32;
|
||||||
|
|
||||||
|
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) cc{}: vec4<f32>;"), locIdx++, i);
|
||||||
|
vtxXfrAttrs += fmt::format(FMT_STRING(R"""(
|
||||||
|
{{
|
||||||
|
var lighting = ubuf.lighting_ambient + ubuf.cc{0}_amb;
|
||||||
|
for (var i = 0; i < {1}; i = i + 1) {{
|
||||||
|
var light = ubuf.lights[i];
|
||||||
|
var delta = mv_pos.xyz - light.pos;
|
||||||
|
var dist = length(delta);
|
||||||
|
var delta_norm = delta / dist;
|
||||||
|
var ang_dot = max(dot(delta_norm, light.dir), 0.0);
|
||||||
|
var lin_att = light.lin_att;
|
||||||
|
var att = 1.0 / (lin_att.z * dist * dist * lin_att.y * dist + lin_att.x);
|
||||||
|
var ang_att = light.ang_att;
|
||||||
|
var ang_att_d = ang_att.z * ang_dot * ang_dot * ang_att.y * ang_dot + ang_att.x;
|
||||||
|
var this_color = light.color.xyz * ang_att_d * att * max(dot(-delta_norm, mv_norm.xyz), 0.0);
|
||||||
|
// if (i == 0 && c_traits.shader.world_shadow == 1u) {{
|
||||||
|
// // TODO ExtTex0 sample
|
||||||
|
// }}
|
||||||
|
lighting = lighting + vec4<f32>(this_color, 0.0);
|
||||||
|
}}
|
||||||
|
out.cc{0} = clamp(lighting, vec4<f32>(0.0), vec4<f32>(1.0));
|
||||||
|
}}
|
||||||
|
)"""), i, MaxLights);
|
||||||
|
|
||||||
if (config.channelMatSrcs[i] == GX::SRC_VTX) {
|
if (config.channelMatSrcs[i] == GX::SRC_VTX) {
|
||||||
if (config.denormalizedVertexAttributes) {
|
if (config.denormalizedVertexAttributes) {
|
||||||
if (!info.usesVtxColor) {
|
if (!info.usesVtxColor) {
|
||||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) clr: vec4<f32>;"), locIdx);
|
vtxInAttrs += fmt::format(FMT_STRING("\n , @location({}) in_clr: vec4<f32>"), locIdx);
|
||||||
vtxInAttrs += fmt::format(FMT_STRING("\n , @location({}) in_clr: vec4<f32>"), ++locIdx);
|
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.cc{} = in_clr;"), i);
|
||||||
vtxXfrAttrs += fmt::format(FMT_STRING("\n out.clr = in_clr;"));
|
|
||||||
}
|
}
|
||||||
fragmentFnPre += fmt::format(FMT_STRING("\n var rast{} = in.clr; // TODO lighting"), i);
|
fragmentFnPre += fmt::format(FMT_STRING("\n var rast{0} = in.cc{0};"), i);
|
||||||
} else {
|
} else {
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("SRC_VTX unsupported with normalized vertex attributes"));
|
Log.report(logvisor::Fatal, FMT_STRING("SRC_VTX unsupported with normalized vertex attributes"));
|
||||||
}
|
}
|
||||||
info.usesVtxColor = true;
|
info.usesVtxColor = true;
|
||||||
} else {
|
} else {
|
||||||
fragmentFnPre += fmt::format(FMT_STRING("\n var rast{0} = ubuf.cc{0}_amb; // TODO lighting"), i);
|
fragmentFnPre += fmt::format(FMT_STRING("\n var rast{0} = in.cc{0};"), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < info.sampledKcolors.size(); ++i) {
|
for (int i = 0; i < info.sampledKcolors.size(); ++i) {
|
||||||
|
@ -540,6 +586,7 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
||||||
uniBufAttrs += fmt::format(FMT_STRING("\n kcolor{}: vec4<f32>;"), i);
|
uniBufAttrs += fmt::format(FMT_STRING("\n kcolor{}: vec4<f32>;"), i);
|
||||||
info.uniformSize += 16;
|
info.uniformSize += 16;
|
||||||
}
|
}
|
||||||
|
size_t texBindIdx = 0;
|
||||||
for (int i = 0; i < info.sampledTextures.size(); ++i) {
|
for (int i = 0; i < info.sampledTextures.size(); ++i) {
|
||||||
if (!info.sampledTextures.test(i)) {
|
if (!info.sampledTextures.test(i)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -547,12 +594,13 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
||||||
uniBufAttrs += fmt::format(FMT_STRING("\n tex{}_lod: f32;"), i);
|
uniBufAttrs += fmt::format(FMT_STRING("\n tex{}_lod: f32;"), i);
|
||||||
info.uniformSize += 4;
|
info.uniformSize += 4;
|
||||||
|
|
||||||
sampBindings += fmt::format(FMT_STRING("\n@group(1) @binding({0})\n"
|
sampBindings += fmt::format(FMT_STRING("\n@group(1) @binding({})\n"
|
||||||
"var tex{0}_samp: sampler;"),
|
"var tex{}_samp: sampler;"),
|
||||||
i);
|
texBindIdx, i);
|
||||||
texBindings += fmt::format(FMT_STRING("\n@group(2) @binding({0})\n"
|
texBindings += fmt::format(FMT_STRING("\n@group(2) @binding({})\n"
|
||||||
"var tex{0}: texture_2d<f32>;"),
|
"var tex{}: texture_2d<f32>;"),
|
||||||
i);
|
texBindIdx, i);
|
||||||
|
++texBindIdx;
|
||||||
|
|
||||||
if (config.denormalizedVertexAttributes) {
|
if (config.denormalizedVertexAttributes) {
|
||||||
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) tex{}_uv: vec2<f32>;"), locIdx, i);
|
vtxOutAttrs += fmt::format(FMT_STRING("\n @location({}) tex{}_uv: vec2<f32>;"), locIdx, i);
|
||||||
|
@ -576,9 +624,11 @@ var<storage, read> v_packed_uvs: Vec2Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto shaderSource =
|
const auto shaderSource =
|
||||||
fmt::format(FMT_STRING(R"""(
|
fmt::format(FMT_STRING(R"""({uniformPre}
|
||||||
struct Uniform {{
|
struct Uniform {{
|
||||||
xf: mat4x4<f32>;{uniBufAttrs}
|
mv: mat4x4<f32>;
|
||||||
|
mv_inv: mat4x4<f32>;
|
||||||
|
proj: mat4x4<f32>;{uniBufAttrs}
|
||||||
}};
|
}};
|
||||||
@group(0) @binding(0)
|
@group(0) @binding(0)
|
||||||
var<uniform> ubuf: Uniform;{uniformBindings}{sampBindings}{texBindings}
|
var<uniform> ubuf: Uniform;{uniformBindings}{sampBindings}{texBindings}
|
||||||
|
@ -602,7 +652,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {{
|
||||||
"uniBufAttrs"_a = uniBufAttrs, "sampBindings"_a = sampBindings, "texBindings"_a = texBindings,
|
"uniBufAttrs"_a = uniBufAttrs, "sampBindings"_a = sampBindings, "texBindings"_a = texBindings,
|
||||||
"vtxOutAttrs"_a = vtxOutAttrs, "vtxInAttrs"_a = vtxInAttrs, "vtxXfrAttrs"_a = vtxXfrAttrs,
|
"vtxOutAttrs"_a = vtxOutAttrs, "vtxInAttrs"_a = vtxInAttrs, "vtxXfrAttrs"_a = vtxXfrAttrs,
|
||||||
"fragmentFn"_a = fragmentFn, "fragmentFnPre"_a = fragmentFnPre, "vtxXfrAttrsPre"_a = vtxXfrAttrsPre,
|
"fragmentFn"_a = fragmentFn, "fragmentFnPre"_a = fragmentFnPre, "vtxXfrAttrsPre"_a = vtxXfrAttrsPre,
|
||||||
"uniformBindings"_a = uniformBindings);
|
"uniformBindings"_a = uniformBindings, "uniformPre"_a = uniformPre);
|
||||||
Log.report(logvisor::Info, FMT_STRING("Generated shader: {}"), shaderSource);
|
Log.report(logvisor::Info, FMT_STRING("Generated shader: {}"), shaderSource);
|
||||||
|
|
||||||
wgpu::ShaderModuleWGSLDescriptor wgslDescriptor{};
|
wgpu::ShaderModuleWGSLDescriptor wgslDescriptor{};
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "dawn/BackendBinding.hpp"
|
#include "dawn/BackendBinding.hpp"
|
||||||
#include "dawn/Hacks.hpp"
|
|
||||||
|
|
||||||
namespace aurora::gpu {
|
namespace aurora::gpu {
|
||||||
static logvisor::Module Log("aurora::gpu");
|
static logvisor::Module Log("aurora::gpu");
|
||||||
|
@ -133,16 +132,41 @@ void initialize(SDL_Window* window) {
|
||||||
g_AdapterProperties.driverDescription);
|
g_AdapterProperties.driverDescription);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
WGPUSupportedLimits supportedLimits{};
|
||||||
|
g_Adapter.GetLimits(&supportedLimits);
|
||||||
|
const wgpu::RequiredLimits requiredLimits{
|
||||||
|
.limits =
|
||||||
|
{
|
||||||
|
.minUniformBufferOffsetAlignment = supportedLimits.limits.minUniformBufferOffsetAlignment,
|
||||||
|
.minStorageBufferOffsetAlignment = supportedLimits.limits.minStorageBufferOffsetAlignment,
|
||||||
|
},
|
||||||
|
};
|
||||||
const std::array<wgpu::FeatureName, 1> requiredFeatures{
|
const std::array<wgpu::FeatureName, 1> requiredFeatures{
|
||||||
wgpu::FeatureName::TextureCompressionBC,
|
wgpu::FeatureName::TextureCompressionBC,
|
||||||
};
|
};
|
||||||
|
const std::array enableToggles {
|
||||||
|
/* clang-format off */
|
||||||
|
#if _WIN32
|
||||||
|
"use_dxc",
|
||||||
|
#endif
|
||||||
|
#ifdef NDEBUG
|
||||||
|
"skip_validation", "disable_robustness",
|
||||||
|
#else
|
||||||
|
"use_user_defined_labels_in_backend",
|
||||||
|
#endif
|
||||||
|
/* clang-format on */
|
||||||
|
};
|
||||||
|
wgpu::DawnTogglesDeviceDescriptor togglesDescriptor{};
|
||||||
|
togglesDescriptor.forceEnabledTogglesCount = enableToggles.size();
|
||||||
|
togglesDescriptor.forceEnabledToggles = enableToggles.data();
|
||||||
const auto deviceDescriptor = wgpu::DeviceDescriptor{
|
const auto deviceDescriptor = wgpu::DeviceDescriptor{
|
||||||
|
.nextInChain = &togglesDescriptor,
|
||||||
.requiredFeaturesCount = requiredFeatures.size(),
|
.requiredFeaturesCount = requiredFeatures.size(),
|
||||||
.requiredFeatures = requiredFeatures.data(),
|
.requiredFeatures = requiredFeatures.data(),
|
||||||
|
.requiredLimits = &requiredLimits,
|
||||||
};
|
};
|
||||||
g_device = wgpu::Device::Acquire(g_Adapter.CreateDevice(&deviceDescriptor));
|
g_device = wgpu::Device::Acquire(g_Adapter.CreateDevice(&deviceDescriptor));
|
||||||
g_device.SetUncapturedErrorCallback(&error_callback, nullptr);
|
g_device.SetUncapturedErrorCallback(&error_callback, nullptr);
|
||||||
hacks::apply_toggles(g_device.Get());
|
|
||||||
}
|
}
|
||||||
g_queue = g_device.GetQueue();
|
g_queue = g_device.GetQueue();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue