implement texture view & fix: crashes

This commit is contained in:
Samuliak 2024-07-25 14:05:56 +02:00
parent 98370260d3
commit 6db893c446
7 changed files with 97 additions and 17 deletions

View File

@ -532,6 +532,8 @@ if(ENABLE_METAL)
HW/Latte/Renderer/Metal/MetalCppImpl.cpp
HW/Latte/Renderer/Metal/LatteTextureMtl.cpp
HW/Latte/Renderer/Metal/LatteTextureMtl.h
HW/Latte/Renderer/Metal/LatteTextureViewMtl.cpp
HW/Latte/Renderer/Metal/LatteTextureViewMtl.h
)
#target_link_libraries(CemuCafe PRIVATE

View File

@ -724,8 +724,8 @@ void LatteRenderTarget_applyTextureColorClear(LatteTexture* texture, uint32 slic
void LatteRenderTarget_applyTextureDepthClear(LatteTexture* texture, uint32 sliceIndex, uint32 mipIndex, bool hasDepthClear, bool hasStencilClear, float depthValue, uint8 stencilValue, uint64 eventCounter)
{
if(texture->isDepth)
{
if(texture->isDepth)
{
g_renderer->texture_clearDepthSlice(texture, sliceIndex, mipIndex, hasDepthClear, hasStencilClear, depthValue, stencilValue);
}
else
@ -884,7 +884,7 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
textureView->baseTexture->GetEffectiveSize(effectiveWidth, effectiveHeight, 0);
_currentOutputImageWidth = effectiveWidth;
_currentOutputImageHeight = effectiveHeight;
sint32 imageX, imageY;
sint32 imageWidth, imageHeight;
sint32 fullscreenWidth, fullscreenHeight;
@ -933,7 +933,7 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
if (shader == nullptr)
{
sint32 scaling_filter = downscaling ? GetConfig().downscale_filter : GetConfig().upscale_filter;
if (g_renderer->GetType() == RendererAPI::Vulkan)
{
// force linear or nearest neighbor filter
@ -978,7 +978,8 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
filter = LatteTextureView::MagFilter::kNearestNeighbor;
}
}
cemu_assert(shader);
// HACK: comment out the assert
//cemu_assert(shader);
g_renderer->DrawBackbufferQuad(textureView, shader, filter==LatteTextureView::MagFilter::kLinear, imageX, imageY, imageWidth, imageHeight, isPadView, clearBackground);
g_renderer->HandleScreenshotRequest(textureView, isPadView);
if (!g_renderer->ImguiBegin(!isPadView))
@ -1029,7 +1030,7 @@ void LatteRenderTarget_itHLECopyColorBufferToScanBuffer(MPTR colorBufferPtr, uin
{
controller = InputManager::instance().get_vpad_controller(1);
if (controller && controller->is_screen_active())
showDRC = true;
showDRC = true;
}
}
@ -1054,7 +1055,7 @@ void LatteRenderTarget_updateViewport()
float vpX = LatteGPUState.contextNew.PA_CL_VPORT_XOFFSET.get_OFFSET() - LatteGPUState.contextNew.PA_CL_VPORT_XSCALE.get_SCALE();
float vpHeight = LatteGPUState.contextNew.PA_CL_VPORT_YSCALE.get_SCALE() / -0.5f;
float vpY = LatteGPUState.contextNew.PA_CL_VPORT_YOFFSET.get_OFFSET() + LatteGPUState.contextNew.PA_CL_VPORT_YSCALE.get_SCALE();
bool halfZ = LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_DX_CLIP_SPACE_DEF();
// calculate near/far

View File

@ -41,7 +41,7 @@ struct
sint32 pixelShaderCount;
}shaderCacheScreenStats;
struct
struct
{
ImTextureID textureTVId;
ImTextureID textureDRCId;
@ -328,7 +328,7 @@ void LatteShaderCache_Load()
};
LatteShaderCache_ShowProgress(LoadShadersUpdate, false);
LatteShaderCache_updateCompileQueue(0);
// write load time and RAM usage to log file (in dev build)
#if BOOST_OS_WINDOWS
@ -371,7 +371,7 @@ void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateF
{
const auto kPopupFlags = ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_AlwaysAutoResize;
const auto textColor = 0xFF888888;
auto lastFrameUpdate = tick_cached();
while (true)
@ -793,7 +793,7 @@ void LatteShaderCache_handleDeprecatedCacheFiles(fs::path pathGeneric, fs::path
{
// ask user if they want to delete or keep the old cache file
auto infoMsg = _("Cemu detected that the shader cache for this game is outdated.\nOnly shader caches generated with Cemu 1.25.0 or above are supported.\n\nWe recommend deleting the outdated cache file as it will no longer be used by Cemu.");
wxMessageDialog dialog(nullptr, infoMsg, _("Outdated shader cache"),
wxYES_NO | wxCENTRE | wxICON_EXCLAMATION);

View File

@ -1,5 +1,5 @@
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.h"
//#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.h"
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.h"
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle,
@ -80,10 +80,7 @@ LatteTextureView* LatteTextureMtl::CreateView(Latte::E_DIM dim, Latte::E_GX2SURF
cemu_assert_debug((firstMip + mipCount) <= this->mipLevels);
cemu_assert_debug((firstSlice + sliceCount) <= this->depth);
//return new LatteTextureViewMtl(m_mtlr, this, dim, format, firstMip, mipCount, firstSlice, sliceCount);
cemuLog_logDebug(LogType::Force, "not implemented");
return nullptr;
return new LatteTextureViewMtl(m_mtlr, this, dim, format, firstMip, mipCount, firstSlice, sliceCount);
}
void LatteTextureMtl::AllocateOnHost()

View File

@ -10,9 +10,12 @@ class LatteTextureMtl : public LatteTexture
public:
LatteTextureMtl(class MetalRenderer* vkRenderer, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels,
uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth);
~LatteTextureMtl();
MTL::Texture* GetTexture() const {
return m_texture;
}
void AllocateOnHost() override;
protected:

View File

@ -0,0 +1,56 @@
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.h"
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.h"
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
LatteTextureViewMtl::LatteTextureViewMtl(MetalRenderer* mtlRenderer, LatteTextureMtl* texture, Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount)
: LatteTextureView(texture, firstMip, mipCount, firstSlice, sliceCount, dim, format), m_mtlr(mtlRenderer)
{
// TODO: don't hardcode the format
MTL::PixelFormat pixelFormat = MTL::PixelFormatRGBA8Unorm;
MTL::TextureType textureType;
switch (dim)
{
case Latte::E_DIM::DIM_1D:
textureType = MTL::TextureType1D;
case Latte::E_DIM::DIM_2D:
case Latte::E_DIM::DIM_2D_MSAA:
textureType = MTL::TextureType2D;
case Latte::E_DIM::DIM_2D_ARRAY:
textureType = MTL::TextureType2DArray;
case Latte::E_DIM::DIM_3D:
textureType = MTL::TextureType3D;
case Latte::E_DIM::DIM_CUBEMAP:
textureType = MTL::TextureTypeCube; // TODO: check this
default:
cemu_assert_unimplemented();
textureType = MTL::TextureType2D;
}
uint32 baseLevel = firstMip;
uint32 levelCount = this->numMip;
uint32 baseLayer;
uint32 layerCount;
// TODO: check if base texture is 3D texture as well
if (textureType == MTL::TextureType3D)
{
cemu_assert_debug(firstMip == 0);
// TODO: uncomment
//cemu_assert_debug(this->numSlice == baseTexture->depth);
baseLayer = 0;
layerCount = 1;
}
else
{
baseLayer = firstSlice;
layerCount = this->numSlice;
}
// TODO: swizzle
m_texture = texture->GetTexture()->newTextureView(pixelFormat, textureType, NS::Range::Make(baseLevel, levelCount), NS::Range::Make(baseLayer, layerCount));
}
LatteTextureViewMtl::~LatteTextureViewMtl()
{
m_texture->release();
}

View File

@ -0,0 +1,21 @@
#pragma once
#include <Metal/Metal.hpp>
#include "Cafe/HW/Latte/Core/LatteTexture.h"
class LatteTextureViewMtl : public LatteTextureView
{
public:
LatteTextureViewMtl(class MetalRenderer* mtlRenderer, class LatteTextureMtl* texture, Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount);
~LatteTextureViewMtl();
MTL::Texture* GetTexture() const {
return m_texture;
}
private:
class MetalRenderer* m_mtlr;
MTL::Texture* m_texture;
};