mirror of https://github.com/AxioDL/metaforce.git
aurora: Working palette textures
This commit is contained in:
parent
ef771e6489
commit
ef71c009c6
|
@ -748,10 +748,11 @@ enum GXTlutFmt {
|
||||||
GX_MAX_TLUTFMT = 0x3,
|
GX_MAX_TLUTFMT = 0x3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace aurora::gfx {
|
||||||
|
struct TextureRef;
|
||||||
|
} // namespace aurora::gfx
|
||||||
struct GXTlutObj {
|
struct GXTlutObj {
|
||||||
u32 format;
|
std::shared_ptr<aurora::gfx::TextureRef> ref;
|
||||||
u32 addr;
|
|
||||||
u16 entries;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GXTlut {
|
enum GXTlut {
|
||||||
|
@ -806,12 +807,9 @@ enum GXCITexFmt {
|
||||||
GX_TF_C14X2 = GX::TF_C14X2,
|
GX_TF_C14X2 = GX::TF_C14X2,
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace aurora::gfx {
|
|
||||||
struct TextureRef;
|
|
||||||
} // namespace aurora::gfx
|
|
||||||
struct GXTexObj {
|
struct GXTexObj {
|
||||||
std::shared_ptr<aurora::gfx::TextureRef> ref;
|
std::shared_ptr<aurora::gfx::TextureRef> ref;
|
||||||
void* data;
|
const void* data;
|
||||||
u32 dataSize;
|
u32 dataSize;
|
||||||
u16 width;
|
u16 width;
|
||||||
u16 height;
|
u16 height;
|
||||||
|
@ -894,12 +892,13 @@ void GXSetTevSwapModeTable(GX::TevSwapSel id, GX::TevColorChan red, GX::TevColor
|
||||||
GX::TevColorChan alpha) noexcept;
|
GX::TevColorChan alpha) noexcept;
|
||||||
void GXSetTevSwapMode(GX::TevStageID stage, GX::TevSwapSel rasSel, GX::TevSwapSel texSel) noexcept;
|
void GXSetTevSwapMode(GX::TevStageID stage, GX::TevSwapSel rasSel, GX::TevSwapSel texSel) noexcept;
|
||||||
void GXSetLineWidth(u8 width, GX::TexOffset texOffset) noexcept;
|
void GXSetLineWidth(u8 width, GX::TexOffset texOffset) noexcept;
|
||||||
void GXInitTlutObj(GXTlutObj* obj, void* data, GXTlutFmt format, u16 entries) noexcept;
|
void GXInitTlutObj(GXTlutObj* obj, const void* data, GXTlutFmt format, u16 entries) noexcept;
|
||||||
void GXLoadTlut(const GXTlutObj* obj, GXTlut idx) noexcept;
|
void GXLoadTlut(const GXTlutObj* obj, GXTlut idx) noexcept;
|
||||||
void GXInitTexObj(GXTexObj* obj, void* data, u16 width, u16 height, GX::TextureFormat format, GXTexWrapMode wrapS,
|
void GXInitTexObj(GXTexObj* obj, const void* data, u16 width, u16 height, GX::TextureFormat format, GXTexWrapMode wrapS,
|
||||||
GXTexWrapMode wrapT, GXBool mipmap) noexcept;
|
GXTexWrapMode wrapT, GXBool mipmap) noexcept;
|
||||||
// Addition for binding render textures
|
// Addition for binding render textures
|
||||||
void GXInitTexObjResolved(GXTexObj* obj, u32 bindIdx, GX::TextureFormat format, GXTexWrapMode wrapS, GXTexWrapMode wrapT);
|
void GXInitTexObjResolved(GXTexObj* obj, u32 bindIdx, GX::TextureFormat format, GXTexWrapMode wrapS,
|
||||||
|
GXTexWrapMode wrapT);
|
||||||
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilt, GXTexFilter magFilt, float minLod, float maxLod, float lodBias,
|
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilt, GXTexFilter magFilt, float minLod, float maxLod, float lodBias,
|
||||||
GXBool biasClamp, GXBool doEdgeLod, GXAnisotropy maxAniso) noexcept;
|
GXBool biasClamp, GXBool doEdgeLod, GXAnisotropy maxAniso) noexcept;
|
||||||
void GXInitTexObjCI(GXTexObj* obj, void* data, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrapS,
|
void GXInitTexObjCI(GXTexObj* obj, void* data, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrapS,
|
||||||
|
|
|
@ -155,10 +155,10 @@ void CRasterFont::DrawString(const CDrawStringOptions& opts, int x, int y, int&
|
||||||
if (renderBuf != nullptr) {
|
if (renderBuf != nullptr) {
|
||||||
CGraphicsPalette pal(EPaletteFormat::RGB5A3, 4);
|
CGraphicsPalette pal(EPaletteFormat::RGB5A3, 4);
|
||||||
pal.Lock();
|
pal.Lock();
|
||||||
*reinterpret_cast<u16*>(pal.GetPaletteData() + 0) = SBIG(zeus::CColor(0.f, 0.f, 0.f, 0.f).toRGB5A3());
|
*reinterpret_cast<u16*>(pal.GetPaletteData() + 0) = bswap16(zeus::CColor(0.f, 0.f, 0.f, 0.f).toRGB5A3());
|
||||||
*reinterpret_cast<u16*>(pal.GetPaletteData() + 2) = SBIG(opts.x4_colors[0].toRGB5A3());
|
*reinterpret_cast<u16*>(pal.GetPaletteData() + 2) = bswap16(opts.x4_colors[0].toRGB5A3());
|
||||||
*reinterpret_cast<u16*>(pal.GetPaletteData() + 4) = SBIG(opts.x4_colors[1].toRGB5A3());
|
*reinterpret_cast<u16*>(pal.GetPaletteData() + 4) = bswap16(opts.x4_colors[1].toRGB5A3());
|
||||||
*reinterpret_cast<u16*>(pal.GetPaletteData() + 6) = SBIG(zeus::CColor(0.f, 0.f, 0.f, 0.f).toRGB5A3());
|
*reinterpret_cast<u16*>(pal.GetPaletteData() + 6) = bswap16(zeus::CColor(0.f, 0.f, 0.f, 0.f).toRGB5A3());
|
||||||
pal.UnLock();
|
pal.UnLock();
|
||||||
renderBuf->AddPaletteChange(pal);
|
renderBuf->AddPaletteChange(pal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,11 +102,6 @@ u32 CTextRenderBuffer::GetCurLen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTextRenderBuffer::Render(const zeus::CColor& color, float time) {
|
void CTextRenderBuffer::Render(const zeus::CColor& color, float time) {
|
||||||
static const GX::VtxDescList skVtxDesc[3]{
|
|
||||||
{GX::VA_POS, GX::DIRECT},
|
|
||||||
{GX::VA_TEX0, GX::DIRECT},
|
|
||||||
{GX::VA_NULL, GX::NONE},
|
|
||||||
};
|
|
||||||
x4c_activeFont = -1;
|
x4c_activeFont = -1;
|
||||||
x4d_activePalette = -1;
|
x4d_activePalette = -1;
|
||||||
CMemoryInStream in(x34_bytecode.data(), x44_blobSize);
|
CMemoryInStream in(x34_bytecode.data(), x44_blobSize);
|
||||||
|
@ -127,8 +122,8 @@ void CTextRenderBuffer::Render(const zeus::CColor& color, float time) {
|
||||||
x4f_queuedPalette = -1;
|
x4f_queuedPalette = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 offX = in.ReadShort();
|
s16 offX = in.ReadShort();
|
||||||
u16 offY = in.ReadShort();
|
s16 offY = in.ReadShort();
|
||||||
char16_t chr = in.ReadShort();
|
char16_t chr = in.ReadShort();
|
||||||
zeus::CColor chrColor(static_cast<zeus::Comp32>(in.ReadLong()));
|
zeus::CColor chrColor(static_cast<zeus::Comp32>(in.ReadLong()));
|
||||||
if (x4c_activeFont != -1) {
|
if (x4c_activeFont != -1) {
|
||||||
|
@ -151,8 +146,8 @@ void CTextRenderBuffer::Render(const zeus::CColor& color, float time) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (cmd == Command::ImageRender) {
|
} else if (cmd == Command::ImageRender) {
|
||||||
u16 offX = in.ReadShort();
|
s16 offX = in.ReadShort();
|
||||||
u16 offY = in.ReadShort();
|
s16 offY = in.ReadShort();
|
||||||
u8 imageIdx = in.ReadChar();
|
u8 imageIdx = in.ReadChar();
|
||||||
zeus::CColor imageColor(static_cast<zeus::Comp32>(in.ReadLong()));
|
zeus::CColor imageColor(static_cast<zeus::Comp32>(in.ReadLong()));
|
||||||
auto imageDef = x14_images[imageIdx];
|
auto imageDef = x14_images[imageIdx];
|
||||||
|
@ -169,7 +164,12 @@ void CTextRenderBuffer::Render(const zeus::CColor& color, float time) {
|
||||||
CGX::SetTevColorIn(GX::TEVSTAGE0, GX::CC_ZERO, GX::CC_TEXC, GX::CC_KONST, GX::CC_ZERO);
|
CGX::SetTevColorIn(GX::TEVSTAGE0, GX::CC_ZERO, GX::CC_TEXC, GX::CC_KONST, GX::CC_ZERO);
|
||||||
CGX::SetTevAlphaIn(GX::TEVSTAGE0, GX::CA_ZERO, GX::CA_TEXA, GX::CA_KONST, GX::CA_ZERO);
|
CGX::SetTevAlphaIn(GX::TEVSTAGE0, GX::CA_ZERO, GX::CA_TEXA, GX::CA_KONST, GX::CA_ZERO);
|
||||||
CGX::SetStandardTevColorAlphaOp(GX::TEVSTAGE0);
|
CGX::SetStandardTevColorAlphaOp(GX::TEVSTAGE0);
|
||||||
CGX::SetVtxDescv(skVtxDesc);
|
constexpr std::array skVtxDesc{
|
||||||
|
GX::VtxDescList{GX::VA_POS, GX::DIRECT},
|
||||||
|
GX::VtxDescList{GX::VA_TEX0, GX::DIRECT},
|
||||||
|
GX::VtxDescList{},
|
||||||
|
};
|
||||||
|
CGX::SetVtxDescv(skVtxDesc.data());
|
||||||
CGX::SetNumChans(0);
|
CGX::SetNumChans(0);
|
||||||
CGX::SetNumTexGens(1);
|
CGX::SetNumTexGens(1);
|
||||||
CGX::SetNumTevStages(1);
|
CGX::SetNumTevStages(1);
|
||||||
|
|
|
@ -493,7 +493,7 @@ void GXSetIndTexMtx(GX::IndTexMtxID id, const void* mtx, s8 scaleExp) noexcept {
|
||||||
g_gxState.indTexMtxs[id - 1] = {*static_cast<const aurora::Mat3x2<float>*>(mtx), scaleExp};
|
g_gxState.indTexMtxs[id - 1] = {*static_cast<const aurora::Mat3x2<float>*>(mtx), scaleExp};
|
||||||
}
|
}
|
||||||
|
|
||||||
void GXInitTexObj(GXTexObj* obj, void* data, u16 width, u16 height, GX::TextureFormat format, GXTexWrapMode wrapS,
|
void GXInitTexObj(GXTexObj* obj, const void* data, u16 width, u16 height, GX::TextureFormat format, GXTexWrapMode wrapS,
|
||||||
GXTexWrapMode wrapT, GXBool mipmap) noexcept {
|
GXTexWrapMode wrapT, GXBool mipmap) noexcept {
|
||||||
obj->data = data;
|
obj->data = data;
|
||||||
obj->width = width;
|
obj->width = width;
|
||||||
|
@ -550,7 +550,24 @@ void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter minFilt, GXTexFilter magFilt, fl
|
||||||
}
|
}
|
||||||
void GXInitTexObjCI(GXTexObj* obj, void* data, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrapS,
|
void GXInitTexObjCI(GXTexObj* obj, void* data, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrapS,
|
||||||
GXTexWrapMode wrapT, GXBool mipmap, u32 tlut) noexcept {
|
GXTexWrapMode wrapT, GXBool mipmap, u32 tlut) noexcept {
|
||||||
// TODO
|
obj->data = data;
|
||||||
|
obj->width = width;
|
||||||
|
obj->height = height;
|
||||||
|
obj->fmt = static_cast<GX::TextureFormat>(format);
|
||||||
|
obj->wrapS = wrapS;
|
||||||
|
obj->wrapT = wrapT;
|
||||||
|
obj->hasMips = mipmap;
|
||||||
|
obj->tlut = static_cast<GXTlut>(tlut);
|
||||||
|
// TODO default values?
|
||||||
|
obj->minFilter = GX_LINEAR;
|
||||||
|
obj->magFilter = GX_LINEAR;
|
||||||
|
obj->minLod = 0.f;
|
||||||
|
obj->maxLod = 0.f;
|
||||||
|
obj->lodBias = 0.f;
|
||||||
|
obj->biasClamp = false;
|
||||||
|
obj->doEdgeLod = false;
|
||||||
|
obj->maxAniso = GX_ANISO_4;
|
||||||
|
obj->dataInvalidated = true;
|
||||||
}
|
}
|
||||||
void GXInitTexObjData(GXTexObj* obj, void* data) noexcept {
|
void GXInitTexObjData(GXTexObj* obj, void* data) noexcept {
|
||||||
obj->data = data;
|
obj->data = data;
|
||||||
|
@ -573,12 +590,27 @@ void GXLoadTexObj(GXTexObj* obj, GX::TexMapID id) noexcept {
|
||||||
g_gxState.textures[id] = {*obj};
|
g_gxState.textures[id] = {*obj};
|
||||||
}
|
}
|
||||||
|
|
||||||
void GXInitTlutObj(GXTlutObj* obj, void* data, GXTlutFmt format, u16 entries) noexcept {
|
void GXInitTlutObj(GXTlutObj* obj, const void* data, GXTlutFmt format, u16 entries) noexcept {
|
||||||
// TODO
|
GX::TextureFormat texFmt;
|
||||||
|
switch (format) {
|
||||||
|
case GX_TL_IA8:
|
||||||
|
texFmt = GX::TF_IA8;
|
||||||
|
break;
|
||||||
|
case GX_TL_RGB565:
|
||||||
|
texFmt = GX::TF_RGB565;
|
||||||
|
break;
|
||||||
|
case GX_TL_RGB5A3:
|
||||||
|
texFmt = GX::TF_RGB5A3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("invalid tlut format {}"), format);
|
||||||
|
unreachable();
|
||||||
}
|
}
|
||||||
void GXLoadTlut(const GXTlutObj* obj, GXTlut idx) noexcept {
|
obj->ref = aurora::gfx::new_static_texture_2d(
|
||||||
// TODO
|
entries, 1, 1, texFmt, aurora::ArrayRef{static_cast<const u8*>(data), static_cast<size_t>(entries) * 2},
|
||||||
|
"GXInitTlutObj");
|
||||||
}
|
}
|
||||||
|
void GXLoadTlut(const GXTlutObj* obj, GXTlut idx) noexcept { g_gxState.tluts[idx] = *obj; }
|
||||||
|
|
||||||
namespace aurora::gfx {
|
namespace aurora::gfx {
|
||||||
static logvisor::Module Log("aurora::gfx::gx");
|
static logvisor::Module Log("aurora::gfx::gx");
|
||||||
|
@ -869,7 +901,7 @@ void populate_pipeline_config(PipelineConfig& config, GX::Primitive primitive) n
|
||||||
} else {
|
} else {
|
||||||
// Loaded texture object, no conversion necessary
|
// Loaded texture object, no conversion necessary
|
||||||
copyFmt = InvalidTextureFormat;
|
copyFmt = InvalidTextureFormat;
|
||||||
bindFmt = InvalidTextureFormat;
|
bindFmt = bind.texObj.fmt;
|
||||||
}
|
}
|
||||||
config.shaderConfig.textureConfig[i] = {copyFmt, bindFmt, flipUV};
|
config.shaderConfig.textureConfig[i] = {copyFmt, bindFmt, flipUV};
|
||||||
}
|
}
|
||||||
|
@ -1005,7 +1037,6 @@ static absl::flat_hash_map<u32, std::pair<wgpu::BindGroupLayout, wgpu::BindGroup
|
||||||
GXBindGroups build_bind_groups(const ShaderInfo& info, const ShaderConfig& config,
|
GXBindGroups build_bind_groups(const ShaderInfo& info, const ShaderConfig& config,
|
||||||
const BindGroupRanges& ranges) noexcept {
|
const BindGroupRanges& ranges) noexcept {
|
||||||
const auto layouts = build_bind_group_layouts(info, config);
|
const auto layouts = build_bind_group_layouts(info, config);
|
||||||
u32 textureCount = info.sampledTextures.count();
|
|
||||||
|
|
||||||
const std::array uniformEntries{
|
const std::array uniformEntries{
|
||||||
wgpu::BindGroupEntry{
|
wgpu::BindGroupEntry{
|
||||||
|
@ -1039,7 +1070,9 @@ GXBindGroups build_bind_groups(const ShaderInfo& info, const ShaderConfig& confi
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
std::array<wgpu::BindGroupEntry, MaxTextures> samplerEntries;
|
std::array<wgpu::BindGroupEntry, MaxTextures> samplerEntries;
|
||||||
std::array<wgpu::BindGroupEntry, MaxTextures> textureEntries;
|
std::array<wgpu::BindGroupEntry, MaxTextures * 2> textureEntries;
|
||||||
|
u32 samplerCount = 0;
|
||||||
|
u32 textureCount = 0;
|
||||||
for (u32 texIdx = 0, i = 0; texIdx < info.sampledTextures.size(); ++texIdx) {
|
for (u32 texIdx = 0, i = 0; texIdx < info.sampledTextures.size(); ++texIdx) {
|
||||||
if (!info.sampledTextures.test(texIdx)) {
|
if (!info.sampledTextures.test(texIdx)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1053,10 +1086,31 @@ GXBindGroups build_bind_groups(const ShaderInfo& info, const ShaderConfig& confi
|
||||||
.binding = i,
|
.binding = i,
|
||||||
.sampler = sampler_ref(tex.get_descriptor()),
|
.sampler = sampler_ref(tex.get_descriptor()),
|
||||||
};
|
};
|
||||||
|
++samplerCount;
|
||||||
textureEntries[i] = {
|
textureEntries[i] = {
|
||||||
.binding = i,
|
.binding = i,
|
||||||
.textureView = tex.texObj.ref->view,
|
.textureView = tex.texObj.ref->view,
|
||||||
};
|
};
|
||||||
|
// Load palette
|
||||||
|
const auto& texConfig = config.textureConfig[i];
|
||||||
|
if (texConfig.loadFmt == GX::TF_C4 || texConfig.loadFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2) {
|
||||||
|
++i;
|
||||||
|
u32 tlut = tex.texObj.tlut;
|
||||||
|
if (tlut < GX_TLUT0 || tlut > GX_TLUT7) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("tlut out of bounds {}"), tlut);
|
||||||
|
unreachable();
|
||||||
|
} else if (!g_gxState.tluts[tlut].ref) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("tlut unbound {}"), tlut);
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
textureEntries[i] = {
|
||||||
|
.binding = i,
|
||||||
|
.textureView = g_gxState.tluts[tlut].ref->view,
|
||||||
|
};
|
||||||
|
textureCount += 2;
|
||||||
|
} else {
|
||||||
|
++textureCount;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
@ -1069,7 +1123,7 @@ GXBindGroups build_bind_groups(const ShaderInfo& info, const ShaderConfig& confi
|
||||||
.samplerBindGroup = bind_group_ref(wgpu::BindGroupDescriptor{
|
.samplerBindGroup = bind_group_ref(wgpu::BindGroupDescriptor{
|
||||||
.label = "GX Sampler Bind Group",
|
.label = "GX Sampler Bind Group",
|
||||||
.layout = layouts.samplerLayout,
|
.layout = layouts.samplerLayout,
|
||||||
.entryCount = textureCount,
|
.entryCount = samplerCount,
|
||||||
.entries = samplerEntries.data(),
|
.entries = samplerEntries.data(),
|
||||||
}),
|
}),
|
||||||
.textureBindGroup = bind_group_ref(wgpu::BindGroupDescriptor{
|
.textureBindGroup = bind_group_ref(wgpu::BindGroupDescriptor{
|
||||||
|
@ -1146,22 +1200,37 @@ GXBindGroupLayouts build_bind_group_layouts(const ShaderInfo& info, const Shader
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 textureCount = info.sampledTextures.count();
|
u32 textureCount = info.sampledTextures.count();
|
||||||
const auto textureIt = sTextureBindGroupLayouts.find(textureCount);
|
// const auto textureIt = sTextureBindGroupLayouts.find(textureCount);
|
||||||
if (textureIt != sTextureBindGroupLayouts.end()) {
|
// if (textureIt != sTextureBindGroupLayouts.end()) {
|
||||||
const auto& [sl, tl] = textureIt->second;
|
// const auto& [sl, tl] = textureIt->second;
|
||||||
out.samplerLayout = sl;
|
// out.samplerLayout = sl;
|
||||||
out.textureLayout = tl;
|
// out.textureLayout = tl;
|
||||||
} else {
|
// } else {
|
||||||
|
u32 numSamplers = 0;
|
||||||
|
u32 numTextures = 0;
|
||||||
std::array<wgpu::BindGroupLayoutEntry, MaxTextures> samplerEntries;
|
std::array<wgpu::BindGroupLayoutEntry, MaxTextures> samplerEntries;
|
||||||
std::array<wgpu::BindGroupLayoutEntry, MaxTextures> textureEntries;
|
std::array<wgpu::BindGroupLayoutEntry, MaxTextures * 2> textureEntries;
|
||||||
for (u32 i = 0; i < textureCount; ++i) {
|
for (u32 i = 0, t = 0; i < textureCount; ++i, ++t) {
|
||||||
samplerEntries[i] = {
|
samplerEntries[i] = {
|
||||||
.binding = i,
|
.binding = i,
|
||||||
.visibility = wgpu::ShaderStage::Fragment,
|
.visibility = wgpu::ShaderStage::Fragment,
|
||||||
.sampler = {.type = wgpu::SamplerBindingType::Filtering},
|
.sampler = {.type = wgpu::SamplerBindingType::Filtering},
|
||||||
};
|
};
|
||||||
textureEntries[i] = {
|
++numSamplers;
|
||||||
.binding = i,
|
const auto& texConfig = config.textureConfig[i];
|
||||||
|
if (texConfig.loadFmt == GX::TF_C4 || texConfig.loadFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2) {
|
||||||
|
textureEntries[t] = {
|
||||||
|
.binding = t,
|
||||||
|
.visibility = wgpu::ShaderStage::Fragment,
|
||||||
|
.texture =
|
||||||
|
{
|
||||||
|
.sampleType = wgpu::TextureSampleType::Sint,
|
||||||
|
.viewDimension = wgpu::TextureViewDimension::e2D,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
++t;
|
||||||
|
textureEntries[t] = {
|
||||||
|
.binding = t,
|
||||||
.visibility = wgpu::ShaderStage::Fragment,
|
.visibility = wgpu::ShaderStage::Fragment,
|
||||||
.texture =
|
.texture =
|
||||||
{
|
{
|
||||||
|
@ -1169,11 +1238,24 @@ GXBindGroupLayouts build_bind_group_layouts(const ShaderInfo& info, const Shader
|
||||||
.viewDimension = wgpu::TextureViewDimension::e2D,
|
.viewDimension = wgpu::TextureViewDimension::e2D,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
numTextures += 2;
|
||||||
|
} else {
|
||||||
|
textureEntries[t] = {
|
||||||
|
.binding = t,
|
||||||
|
.visibility = wgpu::ShaderStage::Fragment,
|
||||||
|
.texture =
|
||||||
|
{
|
||||||
|
.sampleType = wgpu::TextureSampleType::Float,
|
||||||
|
.viewDimension = wgpu::TextureViewDimension::e2D,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
++numTextures;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const wgpu::BindGroupLayoutDescriptor descriptor{
|
const wgpu::BindGroupLayoutDescriptor descriptor{
|
||||||
.label = "GX Sampler Bind Group",
|
.label = "GX Sampler Bind Group",
|
||||||
.entryCount = textureCount,
|
.entryCount = numSamplers,
|
||||||
.entries = samplerEntries.data(),
|
.entries = samplerEntries.data(),
|
||||||
};
|
};
|
||||||
out.samplerLayout = g_device.CreateBindGroupLayout(&descriptor);
|
out.samplerLayout = g_device.CreateBindGroupLayout(&descriptor);
|
||||||
|
@ -1181,13 +1263,13 @@ GXBindGroupLayouts build_bind_group_layouts(const ShaderInfo& info, const Shader
|
||||||
{
|
{
|
||||||
const wgpu::BindGroupLayoutDescriptor descriptor{
|
const wgpu::BindGroupLayoutDescriptor descriptor{
|
||||||
.label = "GX Texture Bind Group",
|
.label = "GX Texture Bind Group",
|
||||||
.entryCount = textureCount,
|
.entryCount = numTextures,
|
||||||
.entries = textureEntries.data(),
|
.entries = textureEntries.data(),
|
||||||
};
|
};
|
||||||
out.textureLayout = g_device.CreateBindGroupLayout(&descriptor);
|
out.textureLayout = g_device.CreateBindGroupLayout(&descriptor);
|
||||||
}
|
}
|
||||||
sTextureBindGroupLayouts.try_emplace(textureCount, out.samplerLayout, out.textureLayout);
|
// sTextureBindGroupLayouts.try_emplace(textureCount, out.samplerLayout, out.textureLayout);
|
||||||
}
|
// }
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,7 @@ struct GXState {
|
||||||
std::array<Light, GX::MaxLights> lights;
|
std::array<Light, GX::MaxLights> lights;
|
||||||
std::array<TevStage, MaxTevStages> tevStages;
|
std::array<TevStage, MaxTevStages> tevStages;
|
||||||
std::array<TextureBind, MaxTextures> textures;
|
std::array<TextureBind, MaxTextures> textures;
|
||||||
|
std::array<GXTlutObj, MaxTextures> tluts;
|
||||||
std::array<TexMtxVariant, MaxTexMtx> texMtxs;
|
std::array<TexMtxVariant, MaxTexMtx> texMtxs;
|
||||||
std::array<Mat4x4<float>, MaxPTTexMtx> ptTexMtxs;
|
std::array<Mat4x4<float>, MaxPTTexMtx> ptTexMtxs;
|
||||||
std::array<TcgConfig, MaxTexCoord> tcgs;
|
std::array<TcgConfig, MaxTexCoord> tcgs;
|
||||||
|
|
|
@ -562,7 +562,7 @@ static inline std::string vtx_attr(const ShaderConfig& config, GX::Attr attr) {
|
||||||
unreachable();
|
unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline std::string texture_conversion(const TextureConfig& tex, u32 stageIdx) {
|
static inline std::string texture_conversion(const TextureConfig& tex, u32 stageIdx, u32 texMapId) {
|
||||||
std::string out;
|
std::string out;
|
||||||
switch (tex.copyFmt) {
|
switch (tex.copyFmt) {
|
||||||
default:
|
default:
|
||||||
|
@ -572,15 +572,25 @@ static inline std::string texture_conversion(const TextureConfig& tex, u32 stage
|
||||||
out += fmt::format(FMT_STRING("\n sampled{0}.a = 1.0;"), stageIdx);
|
out += fmt::format(FMT_STRING("\n sampled{0}.a = 1.0;"), stageIdx);
|
||||||
break;
|
break;
|
||||||
case GX::TF_I4:
|
case GX::TF_I4:
|
||||||
|
case GX::TF_I8:
|
||||||
// Perform intensity conversion
|
// Perform intensity conversion
|
||||||
out += fmt::format(
|
out += fmt::format(
|
||||||
FMT_STRING("\n {{"
|
FMT_STRING("\n {{"
|
||||||
"\n var intensity = dot(sampled{0}.rgb, vec3(0.257, 0.504, 0.098)) + 16.0 / 255.0;"
|
"\n var intensity = dot(sampled{0}.rgb, vec3(0.257, 0.504, 0.098)) + 16.0 / 255.0;"
|
||||||
"\n sampled{0} = vec4<f32>(intensity);"
|
"\n sampled{0} = vec4<f32>(intensity, 0.f, 0.f, 1.f);"
|
||||||
"\n }}"),
|
"\n }}"),
|
||||||
stageIdx);
|
stageIdx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
switch (tex.loadFmt) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case GX::TF_I4:
|
||||||
|
case GX::TF_I8:
|
||||||
|
// Splat R to RGBA
|
||||||
|
out += fmt::format(FMT_STRING("\n sampled{0} = vec4<f32>(sampled{0}.r);"), stageIdx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,10 +1068,16 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||||
// } else {
|
// } else {
|
||||||
uvIn = fmt::format(FMT_STRING("in.tex{0}_uv"), stage.texCoordId);
|
uvIn = fmt::format(FMT_STRING("in.tex{0}_uv"), stage.texCoordId);
|
||||||
// }
|
// }
|
||||||
|
if (texConfig.loadFmt == GX::TF_C4 || texConfig.loadFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2) {
|
||||||
fragmentFnPre +=
|
fragmentFnPre +=
|
||||||
fmt::format(FMT_STRING("\n var sampled{0} = textureSampleBias(tex{1}, tex{1}_samp, {2}, ubuf.tex{1}_lod);"),
|
fmt::format(FMT_STRING("\n var sampled{0} = textureSamplePalette(tex{1}, tex{1}_samp, {2}, tlut{1});"),
|
||||||
i, stage.texMapId, uvIn);
|
i, stage.texMapId, uvIn);
|
||||||
fragmentFnPre += texture_conversion(texConfig, i);
|
} else {
|
||||||
|
fragmentFnPre += fmt::format(
|
||||||
|
FMT_STRING("\n var sampled{0} = textureSampleBias(tex{1}, tex{1}_samp, {2}, ubuf.tex{1}_lod);"), i,
|
||||||
|
stage.texMapId, uvIn);
|
||||||
|
}
|
||||||
|
fragmentFnPre += texture_conversion(texConfig, i, stage.texMapId);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < info.usesTexMtx.size(); ++i) {
|
for (int i = 0; i < info.usesTexMtx.size(); ++i) {
|
||||||
if (info.usesTexMtx.test(i)) {
|
if (info.usesTexMtx.test(i)) {
|
||||||
|
@ -1135,9 +1151,21 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config, const ShaderInfo& in
|
||||||
sampBindings += fmt::format(FMT_STRING("\n@group(1) @binding({})\n"
|
sampBindings += fmt::format(FMT_STRING("\n@group(1) @binding({})\n"
|
||||||
"var tex{}_samp: sampler;"),
|
"var tex{}_samp: sampler;"),
|
||||||
texBindIdx, i);
|
texBindIdx, i);
|
||||||
|
|
||||||
|
const auto& texConfig = config.textureConfig[i];
|
||||||
|
if (texConfig.loadFmt == GX::TF_C4 || texConfig.loadFmt == GX::TF_C8 || texConfig.loadFmt == GX::TF_C14X2) {
|
||||||
|
texBindings += fmt::format(FMT_STRING("\n@group(2) @binding({})\n"
|
||||||
|
"var tex{}: texture_2d<i32>;"),
|
||||||
|
texBindIdx, i);
|
||||||
|
++texBindIdx;
|
||||||
|
texBindings += fmt::format(FMT_STRING("\n@group(2) @binding({})\n"
|
||||||
|
"var tlut{}: texture_2d<f32>;"),
|
||||||
|
texBindIdx, i);
|
||||||
|
} else {
|
||||||
texBindings += fmt::format(FMT_STRING("\n@group(2) @binding({})\n"
|
texBindings += fmt::format(FMT_STRING("\n@group(2) @binding({})\n"
|
||||||
"var tex{}: texture_2d<f32>;"),
|
"var tex{}: texture_2d<f32>;"),
|
||||||
texBindIdx, i);
|
texBindIdx, i);
|
||||||
|
}
|
||||||
++texBindIdx;
|
++texBindIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,6 +1212,19 @@ struct VertexOutput {{
|
||||||
@builtin(position) pos: vec4<f32>,{vtxOutAttrs}
|
@builtin(position) pos: vec4<f32>,{vtxOutAttrs}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
fn textureSamplePalette(tex: texture_2d<i32>, samp: sampler, uv: vec2<f32>, tlut: texture_2d<f32>) -> vec4<f32> {{
|
||||||
|
var f = fract(uv * vec2<f32>(textureDimensions(tex)) + 0.5);
|
||||||
|
var i = textureGather(0, tex, samp, uv);
|
||||||
|
var sX = textureLoad(tlut, vec2<i32>(i.x, 0), 0);
|
||||||
|
var sY = textureLoad(tlut, vec2<i32>(i.y, 0), 0);
|
||||||
|
var sZ = textureLoad(tlut, vec2<i32>(i.z, 0), 0);
|
||||||
|
var sW = textureLoad(tlut, vec2<i32>(i.w, 0), 0);
|
||||||
|
// Bilinear filtering
|
||||||
|
var tA = mix(sW, sZ, f.x);
|
||||||
|
var tB = mix(sX, sY, f.x);
|
||||||
|
return mix(tA, tB, f.y);
|
||||||
|
}}
|
||||||
|
|
||||||
@stage(vertex)
|
@stage(vertex)
|
||||||
fn vs_main({vtxInAttrs}
|
fn vs_main({vtxInAttrs}
|
||||||
) -> VertexOutput {{
|
) -> VertexOutput {{
|
||||||
|
|
|
@ -22,6 +22,8 @@ static TextureFormatInfo format_info(wgpu::TextureFormat format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case wgpu::TextureFormat::R8Unorm:
|
case wgpu::TextureFormat::R8Unorm:
|
||||||
return {1, 1, 1, false};
|
return {1, 1, 1, false};
|
||||||
|
case wgpu::TextureFormat::R16Sint:
|
||||||
|
return {1, 1, 2, false};
|
||||||
case wgpu::TextureFormat::RGBA8Unorm:
|
case wgpu::TextureFormat::RGBA8Unorm:
|
||||||
case wgpu::TextureFormat::R32Float:
|
case wgpu::TextureFormat::R32Float:
|
||||||
return {1, 1, 4, false};
|
return {1, 1, 4, false};
|
||||||
|
|
|
@ -87,11 +87,11 @@ constexpr T bswap16(T val) noexcept {
|
||||||
|
|
||||||
static ByteBuffer BuildI4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef<uint8_t> data) {
|
static ByteBuffer BuildI4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef<uint8_t> data) {
|
||||||
const size_t texelCount = ComputeMippedTexelCount(width, height, mips);
|
const size_t texelCount = ComputeMippedTexelCount(width, height, mips);
|
||||||
ByteBuffer buf{sizeof(RGBA8) * texelCount};
|
ByteBuffer buf{texelCount};
|
||||||
|
|
||||||
uint32_t w = width;
|
uint32_t w = width;
|
||||||
uint32_t h = height;
|
uint32_t h = height;
|
||||||
auto* targetMip = reinterpret_cast<RGBA8*>(buf.data());
|
u8* targetMip = buf.data();
|
||||||
const uint8_t* in = data.data();
|
const uint8_t* in = data.data();
|
||||||
for (uint32_t mip = 0; mip < mips; ++mip) {
|
for (uint32_t mip = 0; mip < mips; ++mip) {
|
||||||
const uint32_t bwidth = (w + 7) / 8;
|
const uint32_t bwidth = (w + 7) / 8;
|
||||||
|
@ -101,12 +101,9 @@ static ByteBuffer BuildI4FromGCN(uint32_t width, uint32_t height, uint32_t mips,
|
||||||
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
||||||
const uint32_t baseX = bx * 8;
|
const uint32_t baseX = bx * 8;
|
||||||
for (uint32_t y = 0; y < std::min(h, 8u); ++y) {
|
for (uint32_t y = 0; y < std::min(h, 8u); ++y) {
|
||||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
u8* target = targetMip + (baseY + y) * w + baseX;
|
||||||
for (uint32_t x = 0; x < std::min(w, 8u); ++x) {
|
for (uint32_t x = 0; x < std::min(w, 8u); ++x) {
|
||||||
target[x].r = Convert4To8(in[x / 2] >> ((x & 1) ? 0 : 4) & 0xf);
|
target[x] = Convert4To8(in[x / 2] >> ((x & 1) ? 0 : 4) & 0xf);
|
||||||
target[x].g = target[x].r;
|
|
||||||
target[x].b = target[x].r;
|
|
||||||
target[x].a = target[x].r;
|
|
||||||
}
|
}
|
||||||
in += std::min<size_t>(w / 4, 4);
|
in += std::min<size_t>(w / 4, 4);
|
||||||
}
|
}
|
||||||
|
@ -247,13 +244,13 @@ ByteBuffer BuildIA8FromGCN(uint32_t width, uint32_t height, uint32_t mips, Array
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer BuildC4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef<uint8_t> data, RGBA8* palette) {
|
ByteBuffer BuildC4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef<uint8_t> data) {
|
||||||
const size_t texelCount = ComputeMippedTexelCount(width, height, mips);
|
const size_t texelCount = ComputeMippedTexelCount(width, height, mips);
|
||||||
ByteBuffer buf{sizeof(RGBA8) * texelCount};
|
ByteBuffer buf{texelCount * 2};
|
||||||
|
|
||||||
uint32_t w = width;
|
uint32_t w = width;
|
||||||
uint32_t h = height;
|
uint32_t h = height;
|
||||||
auto* targetMip = reinterpret_cast<RGBA8*>(buf.data());
|
u16* targetMip = reinterpret_cast<u16*>(buf.data());
|
||||||
const uint8_t* in = data.data();
|
const uint8_t* in = data.data();
|
||||||
for (uint32_t mip = 0; mip < mips; ++mip) {
|
for (uint32_t mip = 0; mip < mips; ++mip) {
|
||||||
const uint32_t bwidth = (w + 7) / 8;
|
const uint32_t bwidth = (w + 7) / 8;
|
||||||
|
@ -262,13 +259,13 @@ ByteBuffer BuildC4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayR
|
||||||
const uint32_t baseY = by * 8;
|
const uint32_t baseY = by * 8;
|
||||||
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
||||||
const uint32_t baseX = bx * 8;
|
const uint32_t baseX = bx * 8;
|
||||||
for (uint32_t y = 0; y < 8; ++y) {
|
for (uint32_t y = 0; y < std::min(8u, h); ++y) {
|
||||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
u16* target = targetMip + (baseY + y) * w + baseX;
|
||||||
const auto n = std::min(w, 8u);
|
const auto n = std::min(w, 8u);
|
||||||
for (size_t x = 0; x < n; ++x) {
|
for (size_t x = 0; x < n; ++x) {
|
||||||
target[x] = palette[in[x / 2] >> ((x & 1) ? 0 : 4) & 0xf];
|
target[x] = in[x / 2] >> ((x & 1) ? 0 : 4) & 0xf;
|
||||||
}
|
}
|
||||||
in += n;
|
in += n / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,13 +281,13 @@ ByteBuffer BuildC4FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayR
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer BuildC8FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef<uint8_t> data, RGBA8* palette) {
|
ByteBuffer BuildC8FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayRef<uint8_t> data) {
|
||||||
const size_t texelCount = ComputeMippedTexelCount(width, height, mips);
|
const size_t texelCount = ComputeMippedTexelCount(width, height, mips);
|
||||||
ByteBuffer buf{sizeof(RGBA8) * texelCount};
|
ByteBuffer buf{texelCount * 2};
|
||||||
|
|
||||||
uint32_t w = width;
|
uint32_t w = width;
|
||||||
uint32_t h = height;
|
uint32_t h = height;
|
||||||
auto* targetMip = reinterpret_cast<RGBA8*>(buf.data());
|
u16* targetMip = reinterpret_cast<u16*>(buf.data());
|
||||||
const uint8_t* in = data.data();
|
const uint8_t* in = data.data();
|
||||||
for (uint32_t mip = 0; mip < mips; ++mip) {
|
for (uint32_t mip = 0; mip < mips; ++mip) {
|
||||||
const uint32_t bwidth = (w + 7) / 8;
|
const uint32_t bwidth = (w + 7) / 8;
|
||||||
|
@ -300,10 +297,10 @@ ByteBuffer BuildC8FromGCN(uint32_t width, uint32_t height, uint32_t mips, ArrayR
|
||||||
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
||||||
const uint32_t baseX = bx * 8;
|
const uint32_t baseX = bx * 8;
|
||||||
for (uint32_t y = 0; y < 4; ++y) {
|
for (uint32_t y = 0; y < 4; ++y) {
|
||||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
u16* target = targetMip + (baseY + y) * w + baseX;
|
||||||
const auto n = std::min(w, 8u);
|
const auto n = std::min(w, 8u);
|
||||||
for (size_t x = 0; x < n; ++x) {
|
for (size_t x = 0; x < n; ++x) {
|
||||||
target[x] = palette[in[x]];
|
target[x] = in[x];
|
||||||
}
|
}
|
||||||
in += n;
|
in += n;
|
||||||
}
|
}
|
||||||
|
@ -336,9 +333,9 @@ ByteBuffer BuildRGB565FromGCN(uint32_t width, uint32_t height, uint32_t mips, Ar
|
||||||
const uint32_t baseY = by * 4;
|
const uint32_t baseY = by * 4;
|
||||||
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
||||||
const uint32_t baseX = bx * 4;
|
const uint32_t baseX = bx * 4;
|
||||||
for (uint32_t y = 0; y < 4; ++y) {
|
for (uint32_t y = 0; y < std::min(4u, h); ++y) {
|
||||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||||
for (size_t x = 0; x < 4; ++x) {
|
for (size_t x = 0; x < std::min(4u, w); ++x) {
|
||||||
const auto texel = bswap16(in[x]);
|
const auto texel = bswap16(in[x]);
|
||||||
target[x].r = Convert5To8(texel >> 11 & 0x1f);
|
target[x].r = Convert5To8(texel >> 11 & 0x1f);
|
||||||
target[x].g = Convert6To8(texel >> 5 & 0x3f);
|
target[x].g = Convert6To8(texel >> 5 & 0x3f);
|
||||||
|
@ -376,9 +373,9 @@ ByteBuffer BuildRGB5A3FromGCN(uint32_t width, uint32_t height, uint32_t mips, Ar
|
||||||
const uint32_t baseY = by * 4;
|
const uint32_t baseY = by * 4;
|
||||||
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
for (uint32_t bx = 0; bx < bwidth; ++bx) {
|
||||||
const uint32_t baseX = bx * 4;
|
const uint32_t baseX = bx * 4;
|
||||||
for (uint32_t y = 0; y < 4; ++y) {
|
for (uint32_t y = 0; y < std::min(4u, h); ++y) {
|
||||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||||
for (size_t x = 0; x < 4; ++x) {
|
for (size_t x = 0; x < std::min(4u, w); ++x) {
|
||||||
const auto texel = bswap16(in[x]);
|
const auto texel = bswap16(in[x]);
|
||||||
if ((texel & 0x8000) != 0) {
|
if ((texel & 0x8000) != 0) {
|
||||||
target[x].r = Convert5To8(texel >> 10 & 0x1f);
|
target[x].r = Convert5To8(texel >> 10 & 0x1f);
|
||||||
|
@ -599,13 +596,9 @@ ByteBuffer convert_texture(GX::TextureFormat format, uint32_t width, uint32_t he
|
||||||
case GX::TF_IA8:
|
case GX::TF_IA8:
|
||||||
return BuildIA8FromGCN(width, height, mips, data);
|
return BuildIA8FromGCN(width, height, mips, data);
|
||||||
case GX::TF_C4:
|
case GX::TF_C4:
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("convert_texture: C4 unimplemented"));
|
return BuildC4FromGCN(width, height, mips, data);
|
||||||
unreachable();
|
|
||||||
// return BuildC4FromGCN(width, height, mips, data);
|
|
||||||
case GX::TF_C8:
|
case GX::TF_C8:
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("convert_texture: C8 unimplemented"));
|
return BuildC8FromGCN(width, height, mips, data);
|
||||||
unreachable();
|
|
||||||
// return BuildC8FromGCN(width, height, mips, data);
|
|
||||||
case GX::TF_C14X2:
|
case GX::TF_C14X2:
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("convert_texture: C14X2 unimplemented"));
|
Log.report(logvisor::Fatal, FMT_STRING("convert_texture: C14X2 unimplemented"));
|
||||||
unreachable();
|
unreachable();
|
||||||
|
|
|
@ -7,9 +7,13 @@
|
||||||
namespace aurora::gfx {
|
namespace aurora::gfx {
|
||||||
static wgpu::TextureFormat to_wgpu(GX::TextureFormat format) {
|
static wgpu::TextureFormat to_wgpu(GX::TextureFormat format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case GX::TF_C8:
|
case GX::TF_I4:
|
||||||
case GX::TF_I8:
|
case GX::TF_I8:
|
||||||
return wgpu::TextureFormat::R8Unorm;
|
return wgpu::TextureFormat::R8Unorm;
|
||||||
|
case GX::TF_C4:
|
||||||
|
case GX::TF_C8:
|
||||||
|
case GX::TF_C14X2:
|
||||||
|
return wgpu::TextureFormat::R16Sint;
|
||||||
case GX::TF_CMPR:
|
case GX::TF_CMPR:
|
||||||
if (gpu::g_device.HasFeature(wgpu::FeatureName::TextureCompressionBC)) {
|
if (gpu::g_device.HasFeature(wgpu::FeatureName::TextureCompressionBC)) {
|
||||||
return wgpu::TextureFormat::BC1RGBAUnorm;
|
return wgpu::TextureFormat::BC1RGBAUnorm;
|
||||||
|
|
|
@ -285,10 +285,11 @@ void initialize(SDL_Window* window) {
|
||||||
"use_dxc",
|
"use_dxc",
|
||||||
#endif
|
#endif
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
"skip_validation", "disable_robustness",
|
"skip_validation",
|
||||||
#else
|
"disable_robustness",
|
||||||
"use_user_defined_labels_in_backend",
|
|
||||||
#endif
|
#endif
|
||||||
|
"use_user_defined_labels_in_backend",
|
||||||
|
"disable_symbol_renaming",
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
};
|
};
|
||||||
wgpu::DawnTogglesDeviceDescriptor togglesDescriptor{};
|
wgpu::DawnTogglesDeviceDescriptor togglesDescriptor{};
|
||||||
|
|
Loading…
Reference in New Issue