mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-04-25 20:26:19 -06:00
condense attribute pointer cache functions and move handleSpecialState8_clearAsDepth to common renderer
This commit is contained in:
parent
828ddea0a8
commit
4be30f6ef9
@ -1,4 +1,12 @@
|
||||
#include "CommonRendererCore.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||
#include "Cafe/HW/Latte/ISA/RegDefines.h"
|
||||
#include "config/CemuConfig.h"
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
#include "Common/GLInclude/glFunctions.h"
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h"
|
||||
#endif
|
||||
|
||||
indexState_t indexState = { 0 };
|
||||
AttributePointerCacheEntry_t activeAttributePointer[LATTE_VS_ATTRIBUTE_LIMIT] = { 0 };
|
||||
@ -8,54 +16,35 @@ indexDataCacheEntry2_t* indexDataCacheFirst = nullptr; // points to least recent
|
||||
indexDataCacheEntry2_t* indexDataCacheLast = nullptr; // points to most recently used item
|
||||
sint32 indexDataCacheEntryCount = 0;
|
||||
|
||||
uint8* CommonRenderer_getAttributePointerCacheVboOutput(uint32 attributeShaderLoc)
|
||||
void CommonRenderer_resetAttributePointerCache()
|
||||
{
|
||||
return activeAttributePointer[attributeShaderLoc].vboOutput;
|
||||
for (sint32 i = 0; i < LATTE_VS_ATTRIBUTE_LIMIT; i++)
|
||||
{
|
||||
activeAttributePointer[i].vboOutput = (uint8*)-1;
|
||||
activeAttributePointer[i].vboStride = (uint32)-1;
|
||||
}
|
||||
}
|
||||
|
||||
void CommonRenderer_setAttributePointerCacheVboOutput(uint32 attributeShaderLoc, uint8* vboOutput)
|
||||
bool CommonRenderer_checkIfAttributePointerCacheChanged(uint32 attributeShaderLoc, uint8* vboOutput, uint32 vboStride, uint8 dataFormat, uint8 nfa, bool isSigned)
|
||||
{
|
||||
// don't call glVertexAttribPointer if parameters have not changed
|
||||
if (
|
||||
activeAttributePointer[attributeShaderLoc].vboOutput == vboOutput &&
|
||||
activeAttributePointer[attributeShaderLoc].vboStride == vboStride &&
|
||||
activeAttributePointer[attributeShaderLoc].dataFormat == dataFormat &&
|
||||
activeAttributePointer[attributeShaderLoc].nfa == nfa &&
|
||||
activeAttributePointer[attributeShaderLoc].isSigned == isSigned
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
activeAttributePointer[attributeShaderLoc].vboOutput = vboOutput;
|
||||
}
|
||||
|
||||
uint32 CommonRenderer_getAttributePointerCacheVboStride(uint32 attributeShaderLoc)
|
||||
{
|
||||
return activeAttributePointer[attributeShaderLoc].vboStride;
|
||||
}
|
||||
|
||||
void CommonRenderer_setAttributePointerCacheVboStride(uint32 attributeShaderLoc, uint32 vboStride)
|
||||
{
|
||||
activeAttributePointer[attributeShaderLoc].vboStride = vboStride;
|
||||
}
|
||||
|
||||
uint8 CommonRenderer_getAttributePointerCacheDataFormat(uint32 attributeShaderLoc)
|
||||
{
|
||||
return activeAttributePointer[attributeShaderLoc].dataFormat;
|
||||
}
|
||||
|
||||
void CommonRenderer_setAttributePointerCacheDataFormat(uint32 attributeShaderLoc, uint8 dataFormat)
|
||||
{
|
||||
activeAttributePointer[attributeShaderLoc].dataFormat = dataFormat;
|
||||
}
|
||||
|
||||
uint8 CommonRenderer_getAttributePointerCacheNfa(uint32 attributeShaderLoc)
|
||||
{
|
||||
return activeAttributePointer[attributeShaderLoc].nfa;
|
||||
}
|
||||
|
||||
void CommonRenderer_setAttributePointerCacheNfa(uint32 attributeShaderLoc, uint8 nfa)
|
||||
{
|
||||
activeAttributePointer[attributeShaderLoc].nfa = nfa;
|
||||
}
|
||||
|
||||
bool CommonRenderer_getAttributePointerCacheIsSigned(uint32 attributeShaderLoc)
|
||||
{
|
||||
return activeAttributePointer[attributeShaderLoc].isSigned;
|
||||
}
|
||||
|
||||
void CommonRenderer_setAttributePointerCacheIsSigned(uint32 attributeShaderLoc, bool isSigned)
|
||||
{
|
||||
activeAttributePointer[attributeShaderLoc].isSigned = isSigned;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
indexState_t* CommonRenderer_getIndexState()
|
||||
@ -152,4 +141,74 @@ void LatteDraw_cleanupAfterFrame()
|
||||
CommonRenderer_removeFromBucket(entry);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LatteDraw_handleSpecialState8_clearAsDepth()
|
||||
{
|
||||
if (LatteGPUState.contextNew.GetSpecialStateValues()[0] == 0)
|
||||
cemuLog_logDebug(LogType::Force, "Special state 8 requires special state 0 but it is not set?");
|
||||
// get depth buffer information
|
||||
uint32 regDepthBuffer = LatteGPUState.contextRegister[mmDB_HTILE_DATA_BASE];
|
||||
uint32 regDepthSize = LatteGPUState.contextRegister[mmDB_DEPTH_SIZE];
|
||||
uint32 regDepthBufferInfo = LatteGPUState.contextRegister[mmDB_DEPTH_INFO];
|
||||
// get format and tileMode from info reg
|
||||
uint32 depthBufferTileMode = (regDepthBufferInfo >> 15) & 0xF;
|
||||
|
||||
MPTR depthBufferPhysMem = regDepthBuffer << 8;
|
||||
uint32 depthBufferPitch = (((regDepthSize >> 0) & 0x3FF) + 1);
|
||||
uint32 depthBufferHeight = ((((regDepthSize >> 10) & 0xFFFFF) + 1) / depthBufferPitch);
|
||||
depthBufferPitch <<= 3;
|
||||
depthBufferHeight <<= 3;
|
||||
uint32 depthBufferWidth = depthBufferPitch;
|
||||
|
||||
sint32 sliceIndex = 0; // todo
|
||||
sint32 mipIndex = 0;
|
||||
|
||||
// clear all color buffers that match the format of the depth buffer
|
||||
sint32 searchIndex = 0;
|
||||
bool targetFound = false;
|
||||
while (true)
|
||||
{
|
||||
LatteTextureView* view = LatteTC_LookupTextureByData(depthBufferPhysMem, depthBufferWidth, depthBufferHeight, depthBufferPitch, 0, 1, sliceIndex, 1, &searchIndex);
|
||||
if (!view)
|
||||
{
|
||||
// should we clear in RAM instead?
|
||||
break;
|
||||
}
|
||||
sint32 effectiveClearWidth = view->baseTexture->width;
|
||||
sint32 effectiveClearHeight = view->baseTexture->height;
|
||||
LatteTexture_scaleToEffectiveSize(view->baseTexture, &effectiveClearWidth, &effectiveClearHeight, 0);
|
||||
|
||||
// hacky way to get clear color
|
||||
float* regClearColor = (float*)(LatteGPUState.contextRegister + 0xC000 + 0); // REG_BASE_ALU_CONST
|
||||
|
||||
uint8 clearColor[4] = { 0 };
|
||||
clearColor[0] = (uint8)(regClearColor[0] * 255.0f);
|
||||
clearColor[1] = (uint8)(regClearColor[1] * 255.0f);
|
||||
clearColor[2] = (uint8)(regClearColor[2] * 255.0f);
|
||||
clearColor[3] = (uint8)(regClearColor[3] * 255.0f);
|
||||
|
||||
// todo - use fragment shader software emulation (evoke for one pixel) to determine clear color
|
||||
// todo - dont clear entire slice, use effectiveClearWidth, effectiveClearHeight
|
||||
|
||||
switch (g_renderer->GetType())
|
||||
{
|
||||
#ifdef ENABLE_OPENGL
|
||||
case RendererAPI::OpenGL:
|
||||
{
|
||||
//cemu_assert_debug(false); // implement g_renderer->texture_clearColorSlice properly for OpenGL renderer
|
||||
if (glClearTexSubImage)
|
||||
glClearTexSubImage(((LatteTextureViewGL*)view)->glTexId, mipIndex, 0, 0, 0, effectiveClearWidth, effectiveClearHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, clearColor);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
if (view->baseTexture->isDepth)
|
||||
g_renderer->texture_clearDepthSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, true, view->baseTexture->hasStencil, 0.0f, 0);
|
||||
else
|
||||
g_renderer->texture_clearColorSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -77,16 +77,9 @@ typedef struct _indexDataCacheEntry_t
|
||||
_indexDataCacheEntry_t* prevInMostRecentUsage; // points to element which was used less recently
|
||||
}indexDataCacheEntry2_t;
|
||||
|
||||
uint8* CommonRenderer_getAttributePointerCacheVboOutput(uint32 attributeShaderLoc);
|
||||
void CommonRenderer_setAttributePointerCacheVboOutput(uint32 attributeShaderLoc, uint8* vboOutput);
|
||||
uint32 CommonRenderer_getAttributePointerCacheVboStride(uint32 attributeShaderLoc);
|
||||
void CommonRenderer_setAttributePointerCacheVboStride(uint32 attributeShaderLoc, uint32 vboStride);
|
||||
uint8 CommonRenderer_getAttributePointerCacheDataFormat(uint32 attributeShaderLoc);
|
||||
void CommonRenderer_setAttributePointerCacheDataFormat(uint32 attributeShaderLoc, uint8 dataFormat);
|
||||
uint8 CommonRenderer_getAttributePointerCacheNfa(uint32 attributeShaderLoc);
|
||||
void CommonRenderer_setAttributePointerCacheNfa(uint32 attributeShaderLoc, uint8 nfa);
|
||||
bool CommonRenderer_getAttributePointerCacheIsSigned(uint32 attributeShaderLoc);
|
||||
void CommonRenderer_setAttributePointerCacheIsSigned(uint32 attributeShaderLoc, bool isSigned);
|
||||
void CommonRenderer_resetAttributePointerCache();
|
||||
bool CommonRenderer_checkIfAttributePointerCacheChanged(uint32 attributeShaderLoc, uint8* vboOutput, uint32 vboStride, uint8 dataFormat, uint8 nfa, bool isSigned);
|
||||
|
||||
indexState_t* CommonRenderer_getIndexState();
|
||||
indexDataCacheEntry2_t** CommonRenderer_getIndexDataCacheFirst();
|
||||
indexDataCacheEntry2_t** CommonRenderer_getIndexDataCacheBucket(uint32 bucketIdx);
|
||||
@ -95,4 +88,5 @@ sint32* CommonRenderer_getIndexDataCacheEntryCount();
|
||||
void CommonRenderer_appendToUsageLinkedList(indexDataCacheEntry2_t* entry);
|
||||
void CommonRenderer_removeFromUsageLinkedList(indexDataCacheEntry2_t* entry);
|
||||
void CommonRenderer_removeFromBucket(indexDataCacheEntry2_t* entry);
|
||||
void LatteDraw_cleanupAfterFrame();
|
||||
void LatteDraw_cleanupAfterFrame();
|
||||
void LatteDraw_handleSpecialState8_clearAsDepth();
|
||||
@ -33,7 +33,7 @@ extern bool hasValidFramebufferAttached;
|
||||
|
||||
float supportBufferData[512 * 4];
|
||||
|
||||
// Defined in the OpenGL renderer
|
||||
// Defined in the Common renderer
|
||||
void LatteDraw_handleSpecialState8_clearAsDepth();
|
||||
|
||||
std::vector<MetalRenderer::DeviceInfo> MetalRenderer::GetDevices()
|
||||
|
||||
@ -27,11 +27,7 @@ extern bool hasValidFramebufferAttached;
|
||||
|
||||
void LatteDraw_resetAttributePointerCache()
|
||||
{
|
||||
for (sint32 i = 0; i < LATTE_VS_ATTRIBUTE_LIMIT; i++)
|
||||
{
|
||||
CommonRenderer_setAttributePointerCacheVboOutput(i, (uint8*)-1);
|
||||
CommonRenderer_setAttributePointerCacheVboStride(i, (uint32)-1);
|
||||
}
|
||||
CommonRenderer_resetAttributePointerCache();
|
||||
}
|
||||
|
||||
void _setAttributeBufferPointerRaw(uint32 attributeShaderLoc, uint8* buffer, uint32 bufferSize, uint32 stride, LatteParsedFetchShaderAttribute_t* attrib, uint8* vboOutput, uint32 vboStride)
|
||||
@ -40,21 +36,11 @@ void _setAttributeBufferPointerRaw(uint32 attributeShaderLoc, uint8* buffer, uin
|
||||
bool isSigned = attrib->isSigned != 0;
|
||||
uint8 nfa = attrib->nfa;
|
||||
// don't call glVertexAttribIPointer if parameters have not changed
|
||||
if (
|
||||
CommonRenderer_getAttributePointerCacheVboOutput(attributeShaderLoc) == vboOutput &&
|
||||
CommonRenderer_getAttributePointerCacheVboStride(attributeShaderLoc) == vboStride &&
|
||||
CommonRenderer_getAttributePointerCacheDataFormat(attributeShaderLoc) == dataFormat &&
|
||||
CommonRenderer_getAttributePointerCacheNfa(attributeShaderLoc) == nfa &&
|
||||
CommonRenderer_getAttributePointerCacheIsSigned(attributeShaderLoc) == isSigned
|
||||
)
|
||||
{
|
||||
bool attributePointerChanged = CommonRenderer_checkIfAttributePointerCacheChanged(attributeShaderLoc, vboOutput, vboStride, dataFormat, nfa, isSigned);
|
||||
if (!attributePointerChanged) {
|
||||
return;
|
||||
}
|
||||
CommonRenderer_setAttributePointerCacheVboOutput(attributeShaderLoc, vboOutput);
|
||||
CommonRenderer_setAttributePointerCacheVboStride(attributeShaderLoc, vboStride);
|
||||
CommonRenderer_setAttributePointerCacheDataFormat(attributeShaderLoc, dataFormat);
|
||||
CommonRenderer_setAttributePointerCacheNfa(attributeShaderLoc, nfa);
|
||||
CommonRenderer_setAttributePointerCacheIsSigned(attributeShaderLoc, isSigned);
|
||||
|
||||
// setup attribute pointer
|
||||
if (dataFormat == FMT_32_32_32_32_FLOAT || dataFormat == FMT_32_32_32_32)
|
||||
{
|
||||
@ -385,70 +371,6 @@ void LatteDrawGL_prepareIndicesWithGPUCache(MPTR indexDataMPTR, _INDEX_TYPE inde
|
||||
indexState->indexData = (uint8*)(size_t)cacheEntry->heapEntry->startOffset;
|
||||
}
|
||||
|
||||
void LatteDraw_handleSpecialState8_clearAsDepth()
|
||||
{
|
||||
if (LatteGPUState.contextNew.GetSpecialStateValues()[0] == 0)
|
||||
cemuLog_logDebug(LogType::Force, "Special state 8 requires special state 0 but it is not set?");
|
||||
// get depth buffer information
|
||||
uint32 regDepthBuffer = LatteGPUState.contextRegister[mmDB_HTILE_DATA_BASE];
|
||||
uint32 regDepthSize = LatteGPUState.contextRegister[mmDB_DEPTH_SIZE];
|
||||
uint32 regDepthBufferInfo = LatteGPUState.contextRegister[mmDB_DEPTH_INFO];
|
||||
// get format and tileMode from info reg
|
||||
uint32 depthBufferTileMode = (regDepthBufferInfo >> 15) & 0xF;
|
||||
|
||||
MPTR depthBufferPhysMem = regDepthBuffer << 8;
|
||||
uint32 depthBufferPitch = (((regDepthSize >> 0) & 0x3FF) + 1);
|
||||
uint32 depthBufferHeight = ((((regDepthSize >> 10) & 0xFFFFF) + 1) / depthBufferPitch);
|
||||
depthBufferPitch <<= 3;
|
||||
depthBufferHeight <<= 3;
|
||||
uint32 depthBufferWidth = depthBufferPitch;
|
||||
|
||||
sint32 sliceIndex = 0; // todo
|
||||
sint32 mipIndex = 0;
|
||||
|
||||
// clear all color buffers that match the format of the depth buffer
|
||||
sint32 searchIndex = 0;
|
||||
bool targetFound = false;
|
||||
while (true)
|
||||
{
|
||||
LatteTextureView* view = LatteTC_LookupTextureByData(depthBufferPhysMem, depthBufferWidth, depthBufferHeight, depthBufferPitch, 0, 1, sliceIndex, 1, &searchIndex);
|
||||
if (!view)
|
||||
{
|
||||
// should we clear in RAM instead?
|
||||
break;
|
||||
}
|
||||
sint32 effectiveClearWidth = view->baseTexture->width;
|
||||
sint32 effectiveClearHeight = view->baseTexture->height;
|
||||
LatteTexture_scaleToEffectiveSize(view->baseTexture, &effectiveClearWidth, &effectiveClearHeight, 0);
|
||||
|
||||
// hacky way to get clear color
|
||||
float* regClearColor = (float*)(LatteGPUState.contextRegister + 0xC000 + 0); // REG_BASE_ALU_CONST
|
||||
|
||||
uint8 clearColor[4] = { 0 };
|
||||
clearColor[0] = (uint8)(regClearColor[0] * 255.0f);
|
||||
clearColor[1] = (uint8)(regClearColor[1] * 255.0f);
|
||||
clearColor[2] = (uint8)(regClearColor[2] * 255.0f);
|
||||
clearColor[3] = (uint8)(regClearColor[3] * 255.0f);
|
||||
|
||||
// todo - use fragment shader software emulation (evoke for one pixel) to determine clear color
|
||||
// todo - dont clear entire slice, use effectiveClearWidth, effectiveClearHeight
|
||||
|
||||
if (g_renderer->GetType() == RendererAPI::OpenGL)
|
||||
{
|
||||
//cemu_assert_debug(false); // implement g_renderer->texture_clearColorSlice properly for OpenGL renderer
|
||||
if (glClearTexSubImage)
|
||||
glClearTexSubImage(((LatteTextureViewGL*)view)->glTexId, mipIndex, 0, 0, 0, effectiveClearWidth, effectiveClearHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, clearColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (view->baseTexture->isDepth)
|
||||
g_renderer->texture_clearDepthSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, true, view->baseTexture->hasStencil, 0.0f, 0);
|
||||
else
|
||||
g_renderer->texture_clearColorSlice(view->baseTexture, sliceIndex + view->firstSlice, mipIndex + view->firstMip, clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LatteDrawGL_doDraw(_INDEX_TYPE indexType, uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count)
|
||||
{
|
||||
indexState_t* indexState = CommonRenderer_getIndexState();
|
||||
|
||||
@ -1221,6 +1221,7 @@ void VulkanRenderer::draw_endRenderPass()
|
||||
m_state.activeRenderpassFBO = nullptr;
|
||||
}
|
||||
|
||||
// Defined in the Common renderer
|
||||
void LatteDraw_handleSpecialState8_clearAsDepth();
|
||||
|
||||
// transfer depth buffer data to color buffer
|
||||
|
||||
Loading…
Reference in New Issue
Block a user