mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-25 18:46:55 +01:00
Latte: Clean up OpenGL relics in shared render code
This commit is contained in:
parent
646835346c
commit
df282ab230
@ -115,7 +115,7 @@ void LatteTC_RegisterTexture(LatteTexture* tex);
|
||||
void LatteTC_UnregisterTexture(LatteTexture* tex);
|
||||
|
||||
uint32 LatteTexture_CalculateTextureDataHash(LatteTexture* hostTexture);
|
||||
void LatteTexture_ReloadData(LatteTexture* hostTexture, uint32 textureUnit);
|
||||
void LatteTexture_ReloadData(LatteTexture* hostTexture);
|
||||
|
||||
bool LatteTC_HasTextureChanged(LatteTexture* hostTexture, bool force = false);
|
||||
void LatteTC_ResetTextureChangeTracker(LatteTexture* hostTexture, bool force = false);
|
||||
|
@ -239,8 +239,6 @@ LatteTextureView* LatteMRT_CreateColorBuffer(MPTR colorBufferPhysMem, uint32 wid
|
||||
textureView = LatteTexture_CreateMapping(colorBufferPhysMem, MPTR_NULL, width, height, viewSlice+1, pitch, tileMode, swizzle, 0, 1, viewSlice, 1, format, Latte::E_DIM::DIM_2D_ARRAY, Latte::E_DIM::DIM_2D, false);
|
||||
else
|
||||
textureView = LatteTexture_CreateMapping(colorBufferPhysMem, MPTR_NULL, width, height, 1, pitch, tileMode, swizzle, 0, 1, viewSlice, 1, format, Latte::E_DIM::DIM_2D, Latte::E_DIM::DIM_2D, false);
|
||||
// unbind texture
|
||||
g_renderer->texture_bindAndActivate(nullptr, 0);
|
||||
return textureView;
|
||||
}
|
||||
|
||||
@ -253,8 +251,6 @@ LatteTextureView* LatteMRT_CreateDepthBuffer(MPTR depthBufferPhysMem, uint32 wid
|
||||
textureView = LatteTexture_CreateMapping(depthBufferPhysMem, MPTR_NULL, width, height, viewSlice+1, pitch, tileMode, swizzle, 0, 1, viewSlice, 1, format, Latte::E_DIM::DIM_2D_ARRAY, Latte::E_DIM::DIM_2D, true);
|
||||
|
||||
LatteMRT::SetDepthAndStencilAttachment(textureView, textureView->baseTexture->hasStencil);
|
||||
// unbind texture
|
||||
g_renderer->texture_bindAndActivate(nullptr, 0);
|
||||
return textureView;
|
||||
}
|
||||
|
||||
|
@ -985,7 +985,7 @@ void LatteTexture_RecreateTextureWithDifferentMipSliceCount(LatteTexture* textur
|
||||
newDim = Latte::E_DIM::DIM_2D_ARRAY;
|
||||
else if (newDim == Latte::E_DIM::DIM_1D && newDepth > 1)
|
||||
newDim = Latte::E_DIM::DIM_1D_ARRAY;
|
||||
LatteTextureView* view = LatteTexture_CreateTexture(0, newDim, texture->physAddress, physMipAddr, texture->format, texture->width, texture->height, newDepth, texture->pitch, newMipCount, texture->swizzle, texture->tileMode, texture->isDepth);
|
||||
LatteTextureView* view = LatteTexture_CreateTexture(newDim, texture->physAddress, physMipAddr, texture->format, texture->width, texture->height, newDepth, texture->pitch, newMipCount, texture->swizzle, texture->tileMode, texture->isDepth);
|
||||
cemu_assert(!(view->baseTexture->mipLevels <= 1 && physMipAddr == MPTR_NULL && newMipCount > 1));
|
||||
// copy data from old texture if its dynamically updated
|
||||
if (texture->isUpdatedOnGPU)
|
||||
@ -1112,7 +1112,7 @@ LatteTextureView* LatteTexture_CreateMapping(MPTR physAddr, MPTR physMipAddr, si
|
||||
// create new texture
|
||||
if (allowCreateNewDataTexture == false)
|
||||
return nullptr;
|
||||
LatteTextureView* view = LatteTexture_CreateTexture(0, dimBase, physAddr, physMipAddr, format, width, height, depth, pitch, firstMip + numMip, swizzle, tileMode, isDepth);
|
||||
LatteTextureView* view = LatteTexture_CreateTexture(dimBase, physAddr, physMipAddr, format, width, height, depth, pitch, firstMip + numMip, swizzle, tileMode, isDepth);
|
||||
LatteTexture* newTexture = view->baseTexture;
|
||||
LatteTexture_GatherTextureRelations(view->baseTexture);
|
||||
LatteTexture_UpdateTextureFromDynamicChanges(view->baseTexture);
|
||||
@ -1191,12 +1191,8 @@ LatteTextureView* LatteTC_GetTextureSliceViewOrTryCreate(MPTR srcImagePtr, MPTR
|
||||
void LatteTexture_UpdateDataToLatest(LatteTexture* texture)
|
||||
{
|
||||
if (LatteTC_HasTextureChanged(texture))
|
||||
{
|
||||
g_renderer->texture_rememberBoundTexture(0);
|
||||
g_renderer->texture_bindAndActivateRawTex(texture, 0);
|
||||
LatteTexture_ReloadData(texture, 0);
|
||||
g_renderer->texture_restoreBoundTexture(0);
|
||||
}
|
||||
LatteTexture_ReloadData(texture);
|
||||
|
||||
if (texture->reloadFromDynamicTextures)
|
||||
{
|
||||
LatteTexture_UpdateCacheFromDynamicTextures(texture);
|
||||
@ -1245,7 +1241,7 @@ std::vector<LatteTexture*>& LatteTexture::GetAllTextures()
|
||||
return sAllTextures;
|
||||
}
|
||||
|
||||
LatteTexture::LatteTexture(uint32 textureUnit, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle,
|
||||
LatteTexture::LatteTexture(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)
|
||||
{
|
||||
_AddTextureToGlobalList(this);
|
||||
|
@ -24,11 +24,9 @@ struct LatteSamplerState
|
||||
class LatteTexture
|
||||
{
|
||||
public:
|
||||
LatteTexture(uint32 textureUnit, 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);
|
||||
LatteTexture(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);
|
||||
virtual ~LatteTexture();
|
||||
|
||||
virtual void InitTextureState() {};
|
||||
|
||||
LatteTextureView* GetOrCreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount)
|
||||
{
|
||||
for (auto& itr : views)
|
||||
@ -307,7 +305,7 @@ std::vector<LatteTextureInformation> LatteTexture_QueryCacheInfo();
|
||||
|
||||
float* LatteTexture_getEffectiveTextureScale(LatteConst::ShaderType shaderType, sint32 texUnit);
|
||||
|
||||
LatteTextureView* LatteTexture_CreateTexture(uint32 textureUnit, 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);
|
||||
LatteTextureView* LatteTexture_CreateTexture(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);
|
||||
void LatteTexture_Delete(LatteTexture* texture);
|
||||
|
||||
void LatteTextureLoader_writeReadbackTextureToMemory(LatteTextureDefinition* textureData, uint32 sliceIndex, uint32 mipIndex, uint8* linearPixelData);
|
||||
|
@ -32,9 +32,9 @@ void LatteTexture_setEffectiveTextureScale(LatteConst::ShaderType shaderType, si
|
||||
t[1] = v;
|
||||
}
|
||||
|
||||
void LatteTextureLoader_UpdateTextureSliceData(LatteTexture* tex, sint32 textureUnit, uint32 sliceIndex, uint32 mipIndex, MPTR physImagePtr, MPTR physMipPtr, Latte::E_DIM dim, uint32 width, uint32 height, uint32 depth, uint32 mipLevels, uint32 pitch, Latte::E_HWTILEMODE tileMode, uint32 swizzle, bool dumpTex);
|
||||
void LatteTextureLoader_UpdateTextureSliceData(LatteTexture* tex, uint32 sliceIndex, uint32 mipIndex, MPTR physImagePtr, MPTR physMipPtr, Latte::E_DIM dim, uint32 width, uint32 height, uint32 depth, uint32 mipLevels, uint32 pitch, Latte::E_HWTILEMODE tileMode, uint32 swizzle, bool dumpTex);
|
||||
|
||||
void LatteTexture_ReloadData(LatteTexture* tex, uint32 textureUnit)
|
||||
void LatteTexture_ReloadData(LatteTexture* tex)
|
||||
{
|
||||
tex->reloadCount++;
|
||||
for(sint32 mip=0; mip<tex->mipLevels; mip++)
|
||||
@ -44,35 +44,35 @@ void LatteTexture_ReloadData(LatteTexture* tex, uint32 textureUnit)
|
||||
{
|
||||
sint32 numSlices = std::max(tex->depth, 1);
|
||||
for(sint32 s=0; s<numSlices; s++)
|
||||
LatteTextureLoader_UpdateTextureSliceData(tex, textureUnit, s, mip, tex->physAddress, tex->physMipAddress, tex->dim, tex->width, tex->height, tex->depth, tex->mipLevels, tex->pitch, tex->tileMode, tex->swizzle, true);
|
||||
LatteTextureLoader_UpdateTextureSliceData(tex, s, mip, tex->physAddress, tex->physMipAddress, tex->dim, tex->width, tex->height, tex->depth, tex->mipLevels, tex->pitch, tex->tileMode, tex->swizzle, true);
|
||||
}
|
||||
else if( tex->dim == Latte::E_DIM::DIM_CUBEMAP )
|
||||
{
|
||||
cemu_assert_debug((tex->depth % 6) == 0);
|
||||
sint32 numFullCubeMaps = tex->depth/6; // number of cubemaps (if numFullCubeMaps is >1 then this texture is a cubemap array)
|
||||
for(sint32 s=0; s<numFullCubeMaps*6; s++)
|
||||
LatteTextureLoader_UpdateTextureSliceData(tex, textureUnit, s, mip, tex->physAddress, tex->physMipAddress, tex->dim, tex->width, tex->height, tex->depth, tex->mipLevels, tex->pitch, tex->tileMode, tex->swizzle, true);
|
||||
LatteTextureLoader_UpdateTextureSliceData(tex, s, mip, tex->physAddress, tex->physMipAddress, tex->dim, tex->width, tex->height, tex->depth, tex->mipLevels, tex->pitch, tex->tileMode, tex->swizzle, true);
|
||||
}
|
||||
else if( tex->dim == Latte::E_DIM::DIM_3D )
|
||||
{
|
||||
sint32 mipDepth = std::max(tex->depth>>mip, 1);
|
||||
for(sint32 s=0; s<mipDepth; s++)
|
||||
{
|
||||
LatteTextureLoader_UpdateTextureSliceData(tex, textureUnit, s, mip, tex->physAddress, tex->physMipAddress, tex->dim, tex->width, tex->height, tex->depth, tex->mipLevels, tex->pitch, tex->tileMode, tex->swizzle, true);
|
||||
LatteTextureLoader_UpdateTextureSliceData(tex, s, mip, tex->physAddress, tex->physMipAddress, tex->dim, tex->width, tex->height, tex->depth, tex->mipLevels, tex->pitch, tex->tileMode, tex->swizzle, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// load slice 0
|
||||
LatteTextureLoader_UpdateTextureSliceData(tex, textureUnit, 0, mip, tex->physAddress, tex->physMipAddress, tex->dim, tex->width, tex->height, tex->depth, tex->mipLevels, tex->pitch, tex->tileMode, tex->swizzle, true);
|
||||
LatteTextureLoader_UpdateTextureSliceData(tex, 0, mip, tex->physAddress, tex->physMipAddress, tex->dim, tex->width, tex->height, tex->depth, tex->mipLevels, tex->pitch, tex->tileMode, tex->swizzle, true);
|
||||
}
|
||||
}
|
||||
tex->lastUpdateEventCounter = LatteTexture_getNextUpdateEventCounter();
|
||||
}
|
||||
|
||||
LatteTextureView* LatteTexture_CreateTexture(uint32 textureUnit, 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)
|
||||
LatteTextureView* LatteTexture_CreateTexture(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)
|
||||
{
|
||||
const auto tex = g_renderer->texture_createTextureEx(textureUnit, dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth);
|
||||
const auto tex = g_renderer->texture_createTextureEx(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth);
|
||||
// init slice/mip info array
|
||||
LatteTexture_InitSliceAndMipInfo(tex);
|
||||
LatteTexture_RegisterTextureMemoryOccupancy(tex);
|
||||
@ -110,7 +110,7 @@ LatteTextureView* LatteTexture_CreateTexture(uint32 textureUnit, Latte::E_DIM di
|
||||
}
|
||||
}
|
||||
}
|
||||
LatteTexture_ReloadData(tex, textureUnit);
|
||||
LatteTexture_ReloadData(tex);
|
||||
LatteTC_MarkTextureStillInUse(tex);
|
||||
LatteTC_RegisterTexture(tex);
|
||||
// create initial view that maps to the whole texture
|
||||
@ -247,7 +247,7 @@ void LatteTexture_updateTexturesForStage(LatteDecompilerShader* shaderContext, u
|
||||
textureView->lastTextureBindIndex = LatteGPUState.textureBindCounter;
|
||||
rendererGL->renderstate_updateTextureSettingsGL(shaderContext, textureView, textureIndex + glBackendBaseTexUnit, word4, textureIndex, isDepthSampler);
|
||||
}
|
||||
g_renderer->texture_bindOnly(textureView, textureIndex + glBackendBaseTexUnit);
|
||||
g_renderer->texture_setLatteTexture(textureView, textureIndex + glBackendBaseTexUnit);
|
||||
// update if data changed
|
||||
bool swizzleChanged = false;
|
||||
if (textureView->baseTexture->swizzle != swizzle)
|
||||
@ -285,9 +285,8 @@ void LatteTexture_updateTexturesForStage(LatteDecompilerShader* shaderContext, u
|
||||
textureView->baseTexture->physMipAddress = physMipAddr;
|
||||
}
|
||||
}
|
||||
g_renderer->texture_bindAndActivateRawTex(textureView->baseTexture, textureIndex + glBackendBaseTexUnit);
|
||||
debug_printf("Reload reason: Data-change when bound as texture (new hash 0x%08x)\n", textureView->baseTexture->texDataHash2);
|
||||
LatteTexture_ReloadData(textureView->baseTexture, textureIndex + glBackendBaseTexUnit);
|
||||
LatteTexture_ReloadData(textureView->baseTexture);
|
||||
}
|
||||
LatteTexture* baseTexture = textureView->baseTexture;
|
||||
if (baseTexture->reloadFromDynamicTextures)
|
||||
|
@ -599,7 +599,7 @@ void LatteTextureLoader_loadTextureDataIntoSlice(LatteTexture* hostTexture, sint
|
||||
}
|
||||
}
|
||||
|
||||
void LatteTextureLoader_UpdateTextureSliceData(LatteTexture* tex, sint32 textureUnit, uint32 sliceIndex, uint32 mipIndex, MPTR physImagePtr, MPTR physMipPtr, Latte::E_DIM dim, uint32 width, uint32 height, uint32 depth, uint32 mipLevels, uint32 pitch, Latte::E_HWTILEMODE tileMode, uint32 swizzle, bool dumpTex)
|
||||
void LatteTextureLoader_UpdateTextureSliceData(LatteTexture* tex, uint32 sliceIndex, uint32 mipIndex, MPTR physImagePtr, MPTR physMipPtr, Latte::E_DIM dim, uint32 width, uint32 height, uint32 depth, uint32 mipLevels, uint32 pitch, Latte::E_HWTILEMODE tileMode, uint32 swizzle, bool dumpTex)
|
||||
{
|
||||
LatteTextureLoaderCtx textureLoader = { 0 };
|
||||
|
||||
|
@ -44,7 +44,7 @@ LatteTextureView* LatteHandleOSScreen_getOrCreateScreenTex(MPTR physAddress, uin
|
||||
LatteTextureView* texView = LatteTextureViewLookupCache::lookup(physAddress, width, height, 1, pitch, 0, 1, 0, 1, Latte::E_GX2SURFFMT::R8_G8_B8_A8_UNORM, Latte::E_DIM::DIM_2D);
|
||||
if (texView)
|
||||
return texView;
|
||||
return LatteTexture_CreateTexture(0, Latte::E_DIM::DIM_2D, physAddress, 0, Latte::E_GX2SURFFMT::R8_G8_B8_A8_UNORM, width, height, 1, pitch, 1, 0, Latte::E_HWTILEMODE::TM_LINEAR_ALIGNED, false);
|
||||
return LatteTexture_CreateTexture(Latte::E_DIM::DIM_2D, physAddress, 0, Latte::E_GX2SURFFMT::R8_G8_B8_A8_UNORM, width, height, 1, pitch, 1, 0, Latte::E_HWTILEMODE::TM_LINEAR_ALIGNED, false);
|
||||
}
|
||||
|
||||
void LatteHandleOSScreen_prepareTextures()
|
||||
@ -71,8 +71,7 @@ bool LatteHandleOSScreen_TV()
|
||||
const uint32 bufferIndexTV = (bufferDisplayTV);
|
||||
const uint32 bufferIndexDRC = bufferDisplayDRC;
|
||||
|
||||
g_renderer->texture_bindAndActivate(osScreenTVTex[bufferIndexTV], 0);
|
||||
LatteTexture_ReloadData(osScreenTVTex[bufferIndexTV]->baseTexture, 0);
|
||||
LatteTexture_ReloadData(osScreenTVTex[bufferIndexTV]->baseTexture);
|
||||
|
||||
// TV screen
|
||||
LatteRenderTarget_copyToBackbuffer(osScreenTVTex[bufferIndexTV]->baseTexture->baseView, false);
|
||||
@ -94,8 +93,7 @@ bool LatteHandleOSScreen_DRC()
|
||||
|
||||
const uint32 bufferIndexDRC = bufferDisplayDRC;
|
||||
|
||||
g_renderer->texture_bindAndActivate(osScreenDRCTex[bufferIndexDRC], 0);
|
||||
LatteTexture_ReloadData(osScreenDRCTex[bufferIndexDRC]->baseTexture, 0);
|
||||
LatteTexture_ReloadData(osScreenDRCTex[bufferIndexDRC]->baseTexture);
|
||||
|
||||
// GamePad screen
|
||||
LatteRenderTarget_copyToBackbuffer(osScreenDRCTex[bufferIndexDRC]->baseTexture->baseView, true);
|
||||
|
@ -19,20 +19,17 @@ static GLuint _genTextureHandleGL()
|
||||
return texIdPool[texIdPoolIndex - 1];
|
||||
}
|
||||
|
||||
LatteTextureGL::LatteTextureGL(uint32 textureUnit, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle,
|
||||
LatteTextureGL::LatteTextureGL(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)
|
||||
: LatteTexture(textureUnit, dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth)
|
||||
: LatteTexture(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth)
|
||||
{
|
||||
GenerateEmptyTextureFromGX2Dim(dim, this->glId_texture, this->glTexTarget);
|
||||
GenerateEmptyTextureFromGX2Dim(dim, this->glId_texture, this->glTexTarget, true);
|
||||
// set format info
|
||||
FormatInfoGL glFormatInfo;
|
||||
GetOpenGLFormatInfo(isDepth, format, dim, &glFormatInfo);
|
||||
this->glInternalFormat = glFormatInfo.glInternalFormat;
|
||||
this->isAlternativeFormat = glFormatInfo.isUsingAlternativeFormat;
|
||||
this->hasStencil = glFormatInfo.hasStencil; // todo - should get this from the GX2 format?
|
||||
// bind texture
|
||||
g_renderer->texture_bindAndActivateRawTex(this, textureUnit);
|
||||
LatteTextureGL::InitTextureState();
|
||||
// set debug name
|
||||
bool useGLDebugNames = false;
|
||||
#ifdef CEMU_DEBUG_ASSERT
|
||||
@ -54,9 +51,8 @@ LatteTextureGL::~LatteTextureGL()
|
||||
catchOpenGLError();
|
||||
}
|
||||
|
||||
void LatteTextureGL::GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& texId, GLint& texTarget)
|
||||
void LatteTextureGL::GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& texId, GLint& texTarget, bool createForTargetType)
|
||||
{
|
||||
texId = _genTextureHandleGL();
|
||||
if (dim == Latte::E_DIM::DIM_2D)
|
||||
texTarget = GL_TEXTURE_2D;
|
||||
else if (dim == Latte::E_DIM::DIM_1D)
|
||||
@ -73,6 +69,10 @@ void LatteTextureGL::GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& te
|
||||
{
|
||||
cemu_assert_unimplemented();
|
||||
}
|
||||
if(createForTargetType)
|
||||
texId = glCreateTextureWrapper(texTarget); // initializes the texture to texTarget (equivalent to calling glGenTextures + glBindTexture)
|
||||
else
|
||||
glGenTextures(1, &texId);
|
||||
}
|
||||
|
||||
LatteTextureView* LatteTextureGL::CreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount)
|
||||
@ -80,18 +80,6 @@ LatteTextureView* LatteTextureGL::CreateView(Latte::E_DIM dim, Latte::E_GX2SURFF
|
||||
return new LatteTextureViewGL(this, dim, format, firstMip, mipCount, firstSlice, sliceCount);
|
||||
}
|
||||
|
||||
void LatteTextureGL::InitTextureState()
|
||||
{
|
||||
// init texture with some default parameters (todo - this shouldn't be necessary if we properly set parameters when a texture is used)
|
||||
catchOpenGLError();
|
||||
glTexParameteri(glTexTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(glTexTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(glTexTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(glTexTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(glTexTarget, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
catchOpenGLError();
|
||||
}
|
||||
|
||||
void LatteTextureGL::GetOpenGLFormatInfo(bool isDepth, Latte::E_GX2SURFFMT format, Latte::E_DIM dim, FormatInfoGL* formatInfoOut)
|
||||
{
|
||||
formatInfoOut->isUsingAlternativeFormat = false;
|
||||
|
@ -6,14 +6,12 @@
|
||||
class LatteTextureGL : public LatteTexture
|
||||
{
|
||||
public:
|
||||
LatteTextureGL(uint32 textureUnit, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels,
|
||||
LatteTextureGL(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);
|
||||
|
||||
~LatteTextureGL();
|
||||
|
||||
static void GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& texId, GLint& texTarget);
|
||||
|
||||
void InitTextureState() override;
|
||||
static void GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& texId, GLint& texTarget, bool createForTargetType);
|
||||
|
||||
protected:
|
||||
LatteTextureView* CreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount) override;
|
||||
|
@ -11,7 +11,7 @@ LatteTextureViewGL::LatteTextureViewGL(LatteTextureGL* texture, Latte::E_DIM dim
|
||||
firstSlice != 0 || firstMip != 0 || mipCount != texture->mipLevels || sliceCount != texture->depth ||
|
||||
forceCreateNewTexId)
|
||||
{
|
||||
LatteTextureGL::GenerateEmptyTextureFromGX2Dim(dim, glTexId, glTexTarget);
|
||||
LatteTextureGL::GenerateEmptyTextureFromGX2Dim(dim, glTexId, glTexTarget, false);
|
||||
this->glInternalFormat = 0;
|
||||
InitAliasView();
|
||||
}
|
||||
|
@ -77,8 +77,6 @@ static const GLenum glAlphaTestFunc[] =
|
||||
GL_ALWAYS
|
||||
};
|
||||
|
||||
|
||||
|
||||
OpenGLRenderer::OpenGLRenderer()
|
||||
{
|
||||
glRendererState.useTextureUploadBuffer = false;
|
||||
@ -571,7 +569,7 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
||||
glViewportIndexedf(0, imageX, imageY, imageWidth, imageHeight);
|
||||
|
||||
LatteTextureViewGL* texViewGL = (LatteTextureViewGL*)texView;
|
||||
g_renderer->texture_bindAndActivate(texView, 0);
|
||||
texture_bindAndActivate(texView, 0);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, useLinearTexFilter ? GL_LINEAR : GL_NEAREST);
|
||||
texViewGL->samplerState.filterMag = 0xFFFFFFFF;
|
||||
@ -586,7 +584,7 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
// unbind texture
|
||||
g_renderer->texture_bindAndActivate(nullptr, 0);
|
||||
texture_bindAndActivate(nullptr, 0);
|
||||
|
||||
catchOpenGLError();
|
||||
|
||||
@ -990,8 +988,9 @@ void OpenGLRenderer::texture_destroy(LatteTexture* hostTexture)
|
||||
delete hostTexture;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::texture_reserveTextureOnGPU(LatteTexture* hostTexture)
|
||||
void OpenGLRenderer::texture_reserveTextureOnGPU(LatteTexture* hostTextureGeneric)
|
||||
{
|
||||
auto hostTexture = (LatteTextureGL*)hostTextureGeneric;
|
||||
cemu_assert_debug(hostTexture->isDataDefined == false);
|
||||
sint32 effectiveBaseWidth = hostTexture->width;
|
||||
sint32 effectiveBaseHeight = hostTexture->height;
|
||||
@ -1012,25 +1011,25 @@ void OpenGLRenderer::texture_reserveTextureOnGPU(LatteTexture* hostTexture)
|
||||
if (hostTexture->dim == Latte::E_DIM::DIM_2D || hostTexture->dim == Latte::E_DIM::DIM_2D_MSAA)
|
||||
{
|
||||
cemu_assert_debug(effectiveBaseDepth == 1);
|
||||
glTexStorage2D(GL_TEXTURE_2D, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth, effectiveBaseHeight);
|
||||
glTextureStorage2DWrapper(GL_TEXTURE_2D, hostTexture->glId_texture, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth, effectiveBaseHeight);
|
||||
}
|
||||
else if (hostTexture->dim == Latte::E_DIM::DIM_1D)
|
||||
{
|
||||
cemu_assert_debug(effectiveBaseHeight == 1);
|
||||
cemu_assert_debug(effectiveBaseDepth == 1);
|
||||
glTexStorage1D(GL_TEXTURE_1D, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth);
|
||||
glTextureStorage1DWrapper(GL_TEXTURE_1D, hostTexture->glId_texture, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth);
|
||||
}
|
||||
else if (hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY || hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY_MSAA)
|
||||
{
|
||||
glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, std::max(1, effectiveBaseDepth));
|
||||
glTextureStorage3DWrapper(GL_TEXTURE_2D_ARRAY, hostTexture->glId_texture, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, std::max(1, effectiveBaseDepth));
|
||||
}
|
||||
else if (hostTexture->dim == Latte::E_DIM::DIM_3D)
|
||||
{
|
||||
glTexStorage3D(GL_TEXTURE_3D, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, std::max(1, effectiveBaseDepth));
|
||||
glTextureStorage3DWrapper(GL_TEXTURE_3D, hostTexture->glId_texture, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, std::max(1, effectiveBaseDepth));
|
||||
}
|
||||
else if (hostTexture->dim == Latte::E_DIM::DIM_CUBEMAP)
|
||||
{
|
||||
glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, effectiveBaseDepth);
|
||||
glTextureStorage3DWrapper(GL_TEXTURE_CUBE_MAP_ARRAY, hostTexture->glId_texture, mipLevels, glFormatInfo.glInternalFormat, effectiveBaseWidth, effectiveBaseHeight, effectiveBaseDepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1042,7 +1041,6 @@ void OpenGLRenderer::texture_reserveTextureOnGPU(LatteTexture* hostTexture)
|
||||
void OpenGLRenderer_texture_loadSlice_normal(LatteTexture* hostTextureGeneric, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 imageSize)
|
||||
{
|
||||
auto hostTexture = (LatteTextureGL*)hostTextureGeneric;
|
||||
|
||||
sint32 effectiveWidth = width;
|
||||
sint32 effectiveHeight = height;
|
||||
sint32 effectiveDepth = depth;
|
||||
@ -1053,58 +1051,37 @@ void OpenGLRenderer_texture_loadSlice_normal(LatteTexture* hostTextureGeneric, s
|
||||
LatteTextureGL::GetOpenGLFormatInfo(hostTexture->isDepth, hostTexture->overwriteInfo.hasFormatOverwrite ? (Latte::E_GX2SURFFMT)hostTexture->overwriteInfo.format : hostTexture->format, hostTexture->dim, &glFormatInfo);
|
||||
// upload slice
|
||||
catchOpenGLError();
|
||||
if (mipIndex >= hostTexture->maxPossibleMipLevels)
|
||||
{
|
||||
cemuLog_logDebug(LogType::Force, "2D texture mip level allocated out of range");
|
||||
return;
|
||||
}
|
||||
if (hostTexture->dim == Latte::E_DIM::DIM_2D || hostTexture->dim == Latte::E_DIM::DIM_2D_MSAA)
|
||||
{
|
||||
if (glFormatInfo.glIsCompressed)
|
||||
{
|
||||
if (glCompressedTextureSubImage2D)
|
||||
glCompressedTextureSubImage2D(hostTexture->glId_texture, mipIndex, 0, 0, effectiveWidth, effectiveHeight, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||
else
|
||||
glCompressedTexSubImage2D(GL_TEXTURE_2D, mipIndex, 0, 0, effectiveWidth, effectiveHeight, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||
}
|
||||
glCompressedTextureSubImage2DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, mipIndex, 0, 0, effectiveWidth, effectiveHeight, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||
else
|
||||
{
|
||||
if (mipIndex < hostTexture->maxPossibleMipLevels)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, mipIndex, 0, 0, effectiveWidth, effectiveHeight, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
||||
else
|
||||
cemuLog_logDebug(LogType::Force, "2D texture mip level allocated out of range");
|
||||
}
|
||||
glTextureSubImage2DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, mipIndex, 0, 0, effectiveWidth, effectiveHeight, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
||||
}
|
||||
else if (hostTexture->dim == Latte::E_DIM::DIM_1D)
|
||||
{
|
||||
if (glFormatInfo.glIsCompressed == true)
|
||||
cemu_assert_unimplemented();
|
||||
glTexSubImage1D(GL_TEXTURE_1D, mipIndex, 0, width, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
||||
if (glFormatInfo.glIsCompressed)
|
||||
glCompressedTextureSubImage1DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, mipIndex, 0, width, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||
else
|
||||
glTextureSubImage1DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, mipIndex, 0, width, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
||||
}
|
||||
else if (hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY || hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY_MSAA)
|
||||
else if (hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY || hostTexture->dim == Latte::E_DIM::DIM_2D_ARRAY_MSAA ||
|
||||
hostTexture->dim == Latte::E_DIM::DIM_3D ||
|
||||
hostTexture->dim == Latte::E_DIM::DIM_CUBEMAP)
|
||||
{
|
||||
if (glFormatInfo.glIsCompressed)
|
||||
glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, mipIndex, 0, 0, sliceIndex, effectiveWidth, effectiveHeight, 1, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||
glCompressedTextureSubImage3DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, mipIndex, 0, 0, sliceIndex, effectiveWidth, effectiveHeight, 1, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||
else
|
||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, mipIndex, 0, 0, sliceIndex, effectiveWidth, effectiveHeight, 1, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
||||
}
|
||||
else if (hostTexture->dim == Latte::E_DIM::DIM_3D)
|
||||
{
|
||||
if (glFormatInfo.glIsCompressed)
|
||||
glCompressedTexSubImage3D(GL_TEXTURE_3D, mipIndex, 0, 0, sliceIndex, effectiveWidth, effectiveHeight, 1, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||
else
|
||||
glTexSubImage3D(GL_TEXTURE_3D, mipIndex, 0, 0, sliceIndex, effectiveWidth, effectiveHeight, 1, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
||||
}
|
||||
else if (hostTexture->dim == Latte::E_DIM::DIM_CUBEMAP)
|
||||
{
|
||||
if (glFormatInfo.glIsCompressed)
|
||||
glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipIndex, 0, 0, sliceIndex, width, height, 1, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||
else
|
||||
glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipIndex, 0, 0, sliceIndex, width, height, 1, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
||||
}
|
||||
else
|
||||
{
|
||||
cemu_assert_debug(false);
|
||||
glTextureSubImage3DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, mipIndex, 0, 0, sliceIndex, effectiveWidth, effectiveHeight, 1, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
||||
}
|
||||
catchOpenGLError();
|
||||
}
|
||||
|
||||
|
||||
// use persistent buffers to upload data
|
||||
void OpenGLRenderer_texture_loadSlice_viaBuffers(LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 imageSize)
|
||||
{
|
||||
@ -1220,10 +1197,10 @@ void OpenGLRenderer::texture_clearSlice(LatteTexture* hostTextureGeneric, sint32
|
||||
glClearTexSubImage(hostTexture->glId_texture, mipIndex, 0, 0, sliceIndex, effectiveWidth, effectiveHeight, 1, formatInfoGL.glSuppliedFormat, formatInfoGL.glSuppliedFormatType, NULL);
|
||||
}
|
||||
|
||||
LatteTexture* OpenGLRenderer::texture_createTextureEx(uint32 textureUnit, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels,
|
||||
LatteTexture* OpenGLRenderer::texture_createTextureEx(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)
|
||||
{
|
||||
return new LatteTextureGL(textureUnit, dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth);
|
||||
return new LatteTextureGL(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth);
|
||||
|
||||
}
|
||||
|
||||
@ -1239,42 +1216,18 @@ void OpenGLRenderer::texture_setActiveTextureUnit(sint32 index)
|
||||
void OpenGLRenderer::texture_bindAndActivate(LatteTextureView* textureView, uint32 textureUnit)
|
||||
{
|
||||
const auto textureViewGL = (LatteTextureViewGL*)textureView;
|
||||
cemu_assert_debug(textureUnit < (sizeof(LatteBoundTexturesBackup) / sizeof(LatteBoundTexturesBackup[0])));
|
||||
// don't call glBindTexture if the texture is already bound
|
||||
if (LatteBoundTextures[textureUnit] == textureViewGL)
|
||||
if (m_latteBoundTextures[textureUnit] == textureViewGL)
|
||||
{
|
||||
texture_setActiveTextureUnit(textureUnit);
|
||||
return; // already bound
|
||||
}
|
||||
// bind
|
||||
LatteBoundTextures[textureUnit] = textureViewGL;
|
||||
m_latteBoundTextures[textureUnit] = textureViewGL;
|
||||
texture_setActiveTextureUnit(textureUnit);
|
||||
if (textureViewGL)
|
||||
{
|
||||
glBindTexture(textureViewGL->glTexTarget, textureViewGL->glTexId);
|
||||
texUnitTexId[textureUnit] = textureViewGL->glTexId;
|
||||
texUnitTexTarget[textureUnit] = textureViewGL->glTexTarget;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLRenderer::texture_bindAndActivateRawTex(LatteTexture* texture, uint32 textureUnit)
|
||||
{
|
||||
cemu_assert_debug(textureUnit < (sizeof(LatteBoundTexturesBackup) / sizeof(LatteBoundTexturesBackup[0])));
|
||||
// don't call glBindTexture if the texture is already bound
|
||||
if (LatteBoundTextures[textureUnit] == texture)
|
||||
{
|
||||
texture_setActiveTextureUnit(textureUnit);
|
||||
return; // already bound
|
||||
}
|
||||
// bind
|
||||
LatteBoundTextures[textureUnit] = texture;
|
||||
texture_setActiveTextureUnit(textureUnit);
|
||||
if (texture)
|
||||
{
|
||||
auto textureGL = (LatteTextureGL*)texture;
|
||||
glBindTexture(textureGL->glTexTarget, textureGL->glId_texture);
|
||||
texUnitTexId[textureUnit] = textureGL->glId_texture;
|
||||
texUnitTexTarget[textureUnit] = textureGL->glTexTarget;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1282,18 +1235,18 @@ void OpenGLRenderer::texture_notifyDelete(LatteTextureView* textureView)
|
||||
{
|
||||
for (uint32 i = 0; i < Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3; i++)
|
||||
{
|
||||
if (LatteBoundTextures[i] == textureView)
|
||||
LatteBoundTextures[i] = nullptr;
|
||||
if (m_latteBoundTextures[i] == textureView)
|
||||
m_latteBoundTextures[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// similar to _bindAndActivate() but doesn't call _setActiveTextureUnit() if texture is already bound
|
||||
void OpenGLRenderer::texture_bindOnly(LatteTextureView* textureView1, uint32 textureUnit)
|
||||
// set Latte texture, on the OpenGL renderer this behaves like _bindAndActivate() but doesn't call _setActiveTextureUnit() if the texture is already bound
|
||||
void OpenGLRenderer::texture_setLatteTexture(LatteTextureView* textureView1, uint32 textureUnit)
|
||||
{
|
||||
auto textureView = ((LatteTextureViewGL*)textureView1);
|
||||
|
||||
cemu_assert_debug(textureUnit < Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3);
|
||||
if (LatteBoundTextures[textureUnit] == textureView)
|
||||
if (m_latteBoundTextures[textureUnit] == textureView)
|
||||
return;
|
||||
if (textureView == nullptr)
|
||||
return;
|
||||
@ -1301,45 +1254,17 @@ void OpenGLRenderer::texture_bindOnly(LatteTextureView* textureView1, uint32 tex
|
||||
if (glBindTextureUnit)
|
||||
{
|
||||
glBindTextureUnit(textureUnit, textureView->glTexId);
|
||||
LatteBoundTextures[textureUnit] = textureView;
|
||||
texUnitTexId[textureUnit] = textureView->glTexId;
|
||||
texUnitTexTarget[textureUnit] = textureView->glTexTarget;
|
||||
m_latteBoundTextures[textureUnit] = textureView;
|
||||
activeTextureUnit = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture_setActiveTextureUnit(textureUnit);
|
||||
glBindTexture(textureView->glTexTarget, textureView->glTexId);
|
||||
LatteBoundTextures[textureUnit] = textureView;
|
||||
texUnitTexId[textureUnit] = textureView->glTexId;
|
||||
texUnitTexTarget[textureUnit] = textureView->glTexTarget;
|
||||
m_latteBoundTextures[textureUnit] = textureView;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLRenderer::texture_rememberBoundTexture(uint32 textureUnit)
|
||||
{
|
||||
cemu_assert_debug(texUnitBackupSlotUsed[textureUnit] == false);
|
||||
texUnitBackupSlotUsed[textureUnit] = true;
|
||||
LatteBoundTexturesBackup[textureUnit] = LatteBoundTextures[textureUnit];
|
||||
texUnitTexIdBackup[textureUnit] = texUnitTexId[textureUnit];
|
||||
texUnitTexTargetBackup[textureUnit] = texUnitTexTarget[textureUnit];
|
||||
}
|
||||
|
||||
void OpenGLRenderer::texture_restoreBoundTexture(uint32 textureUnit)
|
||||
{
|
||||
cemu_assert_debug(texUnitBackupSlotUsed[textureUnit] == true);
|
||||
texUnitBackupSlotUsed[textureUnit] = false;
|
||||
if (LatteBoundTextures[textureUnit] == LatteBoundTexturesBackup[textureUnit])
|
||||
{
|
||||
return; // already bound
|
||||
}
|
||||
LatteBoundTextures[textureUnit] = LatteBoundTexturesBackup[textureUnit];
|
||||
texUnitTexId[textureUnit] = texUnitTexIdBackup[textureUnit];
|
||||
texUnitTexTarget[textureUnit] = texUnitTexTargetBackup[textureUnit];
|
||||
texture_setActiveTextureUnit(textureUnit);
|
||||
glBindTexture(texUnitTexTargetBackup[textureUnit], texUnitTexIdBackup[textureUnit]);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::texture_copyImageSubData(LatteTexture* src, sint32 srcMip, sint32 effectiveSrcX, sint32 effectiveSrcY, sint32 srcSlice, LatteTexture* dst, sint32 dstMip, sint32 effectiveDstX, sint32 effectiveDstY,
|
||||
sint32 dstSlice, sint32 effectiveCopyWidth, sint32 effectiveCopyHeight, sint32 srcDepth)
|
||||
{
|
||||
|
@ -79,13 +79,10 @@ public:
|
||||
void texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) override;
|
||||
void texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sliceIndex, sint32 mipIndex, bool clearDepth, bool clearStencil, float depthValue, uint32 stencilValue) override;
|
||||
|
||||
LatteTexture* texture_createTextureEx(uint32 textureUnit, 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) override;
|
||||
LatteTexture* texture_createTextureEx(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) override;
|
||||
|
||||
void texture_bindAndActivate(LatteTextureView* textureView, uint32 textureUnit) override;
|
||||
void texture_bindAndActivateRawTex(LatteTexture* texture, uint32 textureUnit) override;
|
||||
void texture_bindOnly(LatteTextureView* textureView, uint32 textureUnit) override;
|
||||
void texture_rememberBoundTexture(uint32 textureUnit) override;
|
||||
void texture_restoreBoundTexture(uint32 textureUnit) override;
|
||||
void texture_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit) override;
|
||||
void texture_bindAndActivate(LatteTextureView* textureView, uint32 textureUnit);
|
||||
void texture_copyImageSubData(LatteTexture* src, sint32 srcMip, sint32 effectiveSrcX, sint32 effectiveSrcY, sint32 srcSlice, LatteTexture* dst, sint32 dstMip, sint32 effectiveDstX, sint32 effectiveDstY, sint32 dstSlice, sint32 effectiveCopyWidth, sint32 effectiveCopyHeight, sint32 srcDepth) override;
|
||||
|
||||
void texture_notifyDelete(LatteTextureView* textureView);
|
||||
@ -188,14 +185,7 @@ private:
|
||||
bool m_isXfbActive = false;
|
||||
|
||||
sint32 activeTextureUnit = 0;
|
||||
void* LatteBoundTextures[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3]{};
|
||||
GLuint texUnitTexId[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3]{};
|
||||
GLenum texUnitTexTarget[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3]{};
|
||||
|
||||
void* LatteBoundTexturesBackup[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3]{};
|
||||
GLuint texUnitTexIdBackup[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3]{};
|
||||
GLenum texUnitTexTargetBackup[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3]{};
|
||||
bool texUnitBackupSlotUsed[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3]{};
|
||||
void* m_latteBoundTextures[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3]{};
|
||||
|
||||
// attribute stream
|
||||
GLuint glAttributeCacheAB{};
|
||||
|
@ -1342,7 +1342,7 @@ uint32 _correctTextureCompSelGL(Latte::E_GX2SURFFMT format, uint32 compSel)
|
||||
return compSel;
|
||||
}
|
||||
|
||||
#define quickBindTexture() if( textureIsActive == false ) { g_renderer->texture_bindAndActivate(hostTextureView, hostTextureUnit); textureIsActive = true; }
|
||||
#define quickBindTexture() if( textureIsActive == false ) { texture_bindAndActivate(hostTextureView, hostTextureUnit); textureIsActive = true; }
|
||||
|
||||
uint32 _getGLMinFilter(Latte::LATTE_SQ_TEX_SAMPLER_WORD0_0::E_XY_FILTER filterMin, Latte::LATTE_SQ_TEX_SAMPLER_WORD0_0::E_Z_FILTER filterMip)
|
||||
{
|
||||
@ -1365,11 +1365,9 @@ uint32 _getGLMinFilter(Latte::LATTE_SQ_TEX_SAMPLER_WORD0_0::E_XY_FILTER filterMi
|
||||
/*
|
||||
* Update channel swizzling and other texture settings for a texture unit
|
||||
* hostTextureView is the texture unit view used on the host side
|
||||
* The baseGX2TexUnit parameter is used to identify the shader stage in which this texture is accessed
|
||||
*/
|
||||
void OpenGLRenderer::renderstate_updateTextureSettingsGL(LatteDecompilerShader* shaderContext, LatteTextureView* _hostTextureView, uint32 hostTextureUnit, const Latte::LATTE_SQ_TEX_RESOURCE_WORD4_N texUnitWord4, uint32 texUnitIndex, bool isDepthSampler)
|
||||
{
|
||||
// todo - this is OpenGL-specific, decouple this from the renderer-neutral backend
|
||||
auto hostTextureView = (LatteTextureViewGL*)_hostTextureView;
|
||||
|
||||
LatteTexture* baseTexture = hostTextureView->baseTexture;
|
||||
|
@ -52,7 +52,7 @@ void OpenGLRenderer::surfaceCopy_copySurfaceWithFormatConversion(LatteTexture* s
|
||||
LatteTextureView* sourceView = sourceTexture->GetOrCreateView(srcMip, 1, srcSlice, 1);
|
||||
LatteTextureView* destinationView = destinationTexture->GetOrCreateView(dstMip, 1, dstSlice, 1);
|
||||
|
||||
g_renderer->texture_bindAndActivate(sourceView, 0);
|
||||
texture_bindAndActivate(sourceView, 0);
|
||||
catchOpenGLError();
|
||||
// setup texture attributes
|
||||
_setDepthCompareMode((LatteTextureViewGL*)sourceView, 0);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.h"
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/OpenGLTextureReadback.h"
|
||||
#include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h"
|
||||
|
||||
@ -93,8 +94,7 @@ LatteTextureReadbackInfoGL::~LatteTextureReadbackInfoGL()
|
||||
void LatteTextureReadbackInfoGL::StartTransfer()
|
||||
{
|
||||
cemu_assert(m_textureView);
|
||||
|
||||
g_renderer->texture_bindAndActivate(m_textureView, 0);
|
||||
((OpenGLRenderer*)g_renderer.get())->texture_bindAndActivate(m_textureView, 0);
|
||||
// create unsynchronized buffer
|
||||
glGenBuffers(1, &texImageBufferGL);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, texImageBufferGL);
|
||||
|
@ -110,13 +110,9 @@ public:
|
||||
virtual void texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) = 0;
|
||||
virtual void texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sliceIndex, sint32 mipIndex, bool clearDepth, bool clearStencil, float depthValue, uint32 stencilValue) = 0;
|
||||
|
||||
virtual LatteTexture* texture_createTextureEx(uint32 textureUnit, 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) = 0;
|
||||
virtual LatteTexture* texture_createTextureEx(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) = 0;
|
||||
|
||||
virtual void texture_bindAndActivate(LatteTextureView* textureView, uint32 textureUnit) = 0;
|
||||
virtual void texture_bindAndActivateRawTex(LatteTexture* texture, uint32 textureUnit) = 0;
|
||||
virtual void texture_bindOnly(LatteTextureView* textureView, uint32 textureUnit) = 0;
|
||||
virtual void texture_rememberBoundTexture(uint32 textureUnit) = 0;
|
||||
virtual void texture_restoreBoundTexture(uint32 textureUnit) = 0;
|
||||
virtual void texture_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit) = 0;
|
||||
virtual void texture_copyImageSubData(LatteTexture* src, sint32 srcMip, sint32 effectiveSrcX, sint32 effectiveSrcY, sint32 srcSlice, LatteTexture* dst, sint32 dstMip, sint32 effectiveDstX, sint32 effectiveDstY, sint32 dstSlice, sint32 effectiveCopyWidth, sint32 effectiveCopyHeight, sint32 srcDepth) = 0;
|
||||
|
||||
virtual LatteTextureReadbackInfo* texture_createReadback(LatteTextureView* textureView) = 0;
|
||||
|
@ -3,9 +3,9 @@
|
||||
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
|
||||
|
||||
LatteTextureVk::LatteTextureVk(class VulkanRenderer* vkRenderer, uint32 textureUnit, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle,
|
||||
LatteTextureVk::LatteTextureVk(class VulkanRenderer* 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)
|
||||
: LatteTexture(textureUnit, dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth), m_vkr(vkRenderer)
|
||||
: LatteTexture(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth), m_vkr(vkRenderer)
|
||||
{
|
||||
vkObjTex = new VKRObjectTexture();
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
class LatteTextureVk : public LatteTexture
|
||||
{
|
||||
public:
|
||||
LatteTextureVk(class VulkanRenderer* vkRenderer, uint32 textureUnit, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels,
|
||||
LatteTextureVk(class VulkanRenderer* 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);
|
||||
|
||||
~LatteTextureVk();
|
||||
|
@ -3326,18 +3326,13 @@ void VulkanRenderer::texture_loadSlice(LatteTexture* hostTexture, sint32 width,
|
||||
barrier_image<ANY_TRANSFER, ANY_TRANSFER | IMAGE_READ | IMAGE_WRITE>(vkTexture, barrierSubresourceRange, VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
|
||||
LatteTexture* VulkanRenderer::texture_createTextureEx(uint32 textureUnit, Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels,
|
||||
LatteTexture* VulkanRenderer::texture_createTextureEx(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)
|
||||
{
|
||||
return new LatteTextureVk(this, textureUnit, dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth);
|
||||
return new LatteTextureVk(this, dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth);
|
||||
}
|
||||
|
||||
void VulkanRenderer::texture_bindAndActivate(LatteTextureView* textureView, uint32 textureUnit)
|
||||
{
|
||||
m_state.boundTexture[textureUnit] = static_cast<LatteTextureViewVk*>(textureView);
|
||||
}
|
||||
|
||||
void VulkanRenderer::texture_bindOnly(LatteTextureView* textureView, uint32 textureUnit)
|
||||
void VulkanRenderer::texture_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit)
|
||||
{
|
||||
m_state.boundTexture[textureUnit] = static_cast<LatteTextureViewVk*>(textureView);
|
||||
}
|
||||
|
@ -300,15 +300,10 @@ public:
|
||||
|
||||
void texture_loadSlice(LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 compressedImageSize) override;
|
||||
|
||||
LatteTexture* texture_createTextureEx(uint32 textureUnit, 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) override;
|
||||
LatteTexture* texture_createTextureEx(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) override;
|
||||
|
||||
void texture_bindAndActivate(LatteTextureView* textureView, uint32 textureUnit) override;
|
||||
void texture_bindOnly(LatteTextureView* textureView, uint32 textureUnit) override;
|
||||
void texture_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit) override;
|
||||
|
||||
void texture_bindAndActivateRawTex(LatteTexture* texture, uint32 textureUnit) override {};
|
||||
|
||||
void texture_rememberBoundTexture(uint32 textureUnit) override {};
|
||||
void texture_restoreBoundTexture(uint32 textureUnit) override {};
|
||||
void texture_copyImageSubData(LatteTexture* src, sint32 srcMip, sint32 effectiveSrcX, sint32 effectiveSrcY, sint32 srcSlice, LatteTexture* dst, sint32 dstMip, sint32 effectiveDstX, sint32 effectiveDstY, sint32 dstSlice, sint32 effectiveCopyWidth, sint32 effectiveCopyHeight, sint32 srcDepth) override;
|
||||
LatteTextureReadbackInfo* texture_createReadback(LatteTextureView* textureView) override;
|
||||
|
||||
|
@ -42,6 +42,177 @@ typedef struct __GLXFBConfigRec *GLXFBConfig;
|
||||
#undef GLFUNC
|
||||
#undef EGLFUNC
|
||||
|
||||
// DSA-style helpers with fallback to legacy API if DSA is not supported
|
||||
|
||||
#define DSA_FORCE_DISABLE false // set to true to simulate DSA not being supported
|
||||
|
||||
static GLenum GetGLBindingFromTextureTarget(GLenum texTarget)
|
||||
{
|
||||
switch(texTarget)
|
||||
{
|
||||
case GL_TEXTURE_1D: return GL_TEXTURE_BINDING_1D;
|
||||
case GL_TEXTURE_2D: return GL_TEXTURE_BINDING_2D;
|
||||
case GL_TEXTURE_3D: return GL_TEXTURE_BINDING_3D;
|
||||
case GL_TEXTURE_2D_ARRAY: return GL_TEXTURE_BINDING_2D_ARRAY;
|
||||
case GL_TEXTURE_CUBE_MAP: return GL_TEXTURE_BINDING_CUBE_MAP;
|
||||
case GL_TEXTURE_CUBE_MAP_ARRAY: return GL_TEXTURE_BINDING_CUBE_MAP_ARRAY;
|
||||
default:
|
||||
cemu_assert_unimplemented();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint glCreateTextureWrapper(GLenum target)
|
||||
{
|
||||
GLuint tex;
|
||||
if (glCreateTextures && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glCreateTextures(target, 1, &tex);
|
||||
return tex;
|
||||
}
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(GetGLBindingFromTextureTarget(target), &originalTexture);
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(target, tex);
|
||||
glBindTexture(target, originalTexture);
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void glTextureStorage1DWrapper(GLenum target, GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width)
|
||||
{
|
||||
if (glTextureStorage1D && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glTextureStorage1D(texture, levels, internalformat, width);
|
||||
return;
|
||||
}
|
||||
GLenum binding = GetGLBindingFromTextureTarget(target);
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(binding, &originalTexture);
|
||||
glBindTexture(target, texture);
|
||||
glTexStorage1D(target, levels, internalformat, width);
|
||||
glBindTexture(target, originalTexture);
|
||||
}
|
||||
|
||||
static void glTextureStorage2DWrapper(GLenum target, GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
|
||||
{
|
||||
if (glTextureStorage2D && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glTextureStorage2D(texture, levels, internalformat, width, height);
|
||||
return;
|
||||
}
|
||||
GLenum binding = GetGLBindingFromTextureTarget(target);
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(binding, &originalTexture);
|
||||
glBindTexture(target, texture);
|
||||
glTexStorage2D(target, levels, internalformat, width, height);
|
||||
glBindTexture(target, originalTexture);
|
||||
}
|
||||
|
||||
static void glTextureStorage3DWrapper(GLenum target, GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
|
||||
{
|
||||
if (glTextureStorage3D && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glTextureStorage3D(texture, levels, internalformat, width, height, depth);
|
||||
return;
|
||||
}
|
||||
GLenum binding = GetGLBindingFromTextureTarget(target);
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(binding, &originalTexture);
|
||||
glBindTexture(target, texture);
|
||||
glTexStorage3D(target, levels, internalformat, width, height, depth);
|
||||
glBindTexture(target, originalTexture);
|
||||
}
|
||||
|
||||
static void glTextureSubImage1DWrapper(GLenum target, GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels)
|
||||
{
|
||||
if (glTextureSubImage1D && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glTextureSubImage1D(texture, level, xoffset, width, format, type, pixels);
|
||||
return;
|
||||
}
|
||||
GLenum binding = GetGLBindingFromTextureTarget(target);
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(binding, &originalTexture);
|
||||
glBindTexture(target, texture);
|
||||
glTexSubImage1D(target, level, xoffset, width, format, type, pixels);
|
||||
glBindTexture(target, originalTexture);
|
||||
}
|
||||
|
||||
static void glCompressedTextureSubImage1DWrapper(GLenum target, GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data)
|
||||
{
|
||||
if (glCompressedTextureSubImage1D && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glCompressedTextureSubImage1D(texture, level, xoffset, width, format, imageSize, data);
|
||||
return;
|
||||
}
|
||||
GLenum binding = GetGLBindingFromTextureTarget(target);
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(binding, &originalTexture);
|
||||
glBindTexture(target, texture);
|
||||
glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, data);
|
||||
glBindTexture(target, originalTexture);
|
||||
}
|
||||
|
||||
static void glTextureSubImage2DWrapper(GLenum target, GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels)
|
||||
{
|
||||
if (glTextureSubImage2D && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glTextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, type, pixels);
|
||||
return;
|
||||
}
|
||||
GLenum binding = GetGLBindingFromTextureTarget(target);
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(binding, &originalTexture);
|
||||
glBindTexture(target, texture);
|
||||
glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
||||
glBindTexture(target, originalTexture);
|
||||
}
|
||||
|
||||
static void glCompressedTextureSubImage2DWrapper(GLenum target, GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
|
||||
{
|
||||
if (glCompressedTextureSubImage2D && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glCompressedTextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, imageSize, data);
|
||||
return;
|
||||
}
|
||||
GLenum binding = GetGLBindingFromTextureTarget(target);
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(binding, &originalTexture);
|
||||
glBindTexture(target, texture);
|
||||
glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
|
||||
glBindTexture(target, originalTexture);
|
||||
}
|
||||
|
||||
static void glTextureSubImage3DWrapper(GLenum target, GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels)
|
||||
{
|
||||
if(glTextureSubImage3D && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
|
||||
return;
|
||||
}
|
||||
GLenum binding = GetGLBindingFromTextureTarget(target);
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(binding, &originalTexture);
|
||||
glBindTexture(target, texture);
|
||||
glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
|
||||
glBindTexture(target, originalTexture);
|
||||
}
|
||||
|
||||
static void glCompressedTextureSubImage3DWrapper(GLenum target, GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data)
|
||||
{
|
||||
if(glCompressedTextureSubImage3D && !DSA_FORCE_DISABLE)
|
||||
{
|
||||
glCompressedTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
|
||||
return;
|
||||
}
|
||||
GLenum binding = GetGLBindingFromTextureTarget(target);
|
||||
GLint originalTexture;
|
||||
glGetIntegerv(binding, &originalTexture);
|
||||
glBindTexture(target, texture);
|
||||
glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
|
||||
glBindTexture(target, originalTexture);
|
||||
}
|
||||
|
||||
// this prevents Windows GL.h from being included:
|
||||
#define __gl_h_
|
||||
#define __GL_H__
|
||||
|
@ -171,10 +171,13 @@ GLFUNC(PFNGLTEXSTORAGE2DPROC, glTexStorage2D)
|
||||
GLFUNC(PFNGLTEXSTORAGE3DPROC, glTexStorage3D)
|
||||
GLFUNC(PFNGLTEXIMAGE3DPROC, glTexImage3D)
|
||||
GLFUNC(PFNGLTEXSUBIMAGE3DPROC, glTexSubImage3D)
|
||||
GLFUNC(PFNGLCOMPRESSEDTEXIMAGE1DPROC, glCompressedTexImage1D)
|
||||
GLFUNC(PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D)
|
||||
GLFUNC(PFNGLCOMPRESSEDTEXIMAGE3DPROC, glCompressedTexImage3D)
|
||||
GLFUNC(PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC, glCompressedTexSubImage1D)
|
||||
GLFUNC(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, glCompressedTexSubImage2D)
|
||||
GLFUNC(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedTexSubImage3D)
|
||||
GLFUNC(PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC, glCompressedTextureSubImage1D)
|
||||
GLFUNC(PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC, glCompressedTextureSubImage2D)
|
||||
GLFUNC(PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC, glCompressedTextureSubImage3D)
|
||||
GLFUNC(PFNGLCOPYIMAGESUBDATAPROC, glCopyImageSubData)
|
||||
@ -184,12 +187,17 @@ GLFUNC(PFNGLINVALIDATETEXIMAGEPROC, glInvalidateTexImage)
|
||||
|
||||
// texture DSA
|
||||
|
||||
GLFUNC(PFNGLCREATETEXTURESPROC, glCreateTextures)
|
||||
GLFUNC(PFNGLBINDTEXTUREUNITPROC, glBindTextureUnit)
|
||||
GLFUNC(PFNGLGETTEXTURELEVELPARAMETERIVPROC, glGetTextureLevelParameteriv)
|
||||
GLFUNC(PFNGLTEXTUREPARAMETERIPROC, glTextureParameteri)
|
||||
GLFUNC(PFNGLGETTEXTURESUBIMAGEPROC, glGetTextureSubImage)
|
||||
GLFUNC(PFNGLTEXTURESUBIMAGE1DPROC, glTextureSubImage1D)
|
||||
GLFUNC(PFNGLTEXTURESUBIMAGE2DPROC, glTextureSubImage2D);
|
||||
GLFUNC(PFNGLTEXTURESUBIMAGE3DPROC, glTextureSubImage3D)
|
||||
GLFUNC(PFNGLTEXTURESTORAGE1DPROC, glTextureStorage1D)
|
||||
GLFUNC(PFNGLTEXTURESTORAGE2DPROC, glTextureStorage2D)
|
||||
GLFUNC(PFNGLTEXTURESTORAGE3DPROC, glTextureStorage3D)
|
||||
|
||||
// instancing / draw
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user