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);
|
void LatteTC_UnregisterTexture(LatteTexture* tex);
|
||||||
|
|
||||||
uint32 LatteTexture_CalculateTextureDataHash(LatteTexture* hostTexture);
|
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);
|
bool LatteTC_HasTextureChanged(LatteTexture* hostTexture, bool force = false);
|
||||||
void LatteTC_ResetTextureChangeTracker(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);
|
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
|
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);
|
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;
|
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);
|
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);
|
LatteMRT::SetDepthAndStencilAttachment(textureView, textureView->baseTexture->hasStencil);
|
||||||
// unbind texture
|
|
||||||
g_renderer->texture_bindAndActivate(nullptr, 0);
|
|
||||||
return textureView;
|
return textureView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -985,7 +985,7 @@ void LatteTexture_RecreateTextureWithDifferentMipSliceCount(LatteTexture* textur
|
|||||||
newDim = Latte::E_DIM::DIM_2D_ARRAY;
|
newDim = Latte::E_DIM::DIM_2D_ARRAY;
|
||||||
else if (newDim == Latte::E_DIM::DIM_1D && newDepth > 1)
|
else if (newDim == Latte::E_DIM::DIM_1D && newDepth > 1)
|
||||||
newDim = Latte::E_DIM::DIM_1D_ARRAY;
|
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));
|
cemu_assert(!(view->baseTexture->mipLevels <= 1 && physMipAddr == MPTR_NULL && newMipCount > 1));
|
||||||
// copy data from old texture if its dynamically updated
|
// copy data from old texture if its dynamically updated
|
||||||
if (texture->isUpdatedOnGPU)
|
if (texture->isUpdatedOnGPU)
|
||||||
@ -1112,7 +1112,7 @@ LatteTextureView* LatteTexture_CreateMapping(MPTR physAddr, MPTR physMipAddr, si
|
|||||||
// create new texture
|
// create new texture
|
||||||
if (allowCreateNewDataTexture == false)
|
if (allowCreateNewDataTexture == false)
|
||||||
return nullptr;
|
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* newTexture = view->baseTexture;
|
||||||
LatteTexture_GatherTextureRelations(view->baseTexture);
|
LatteTexture_GatherTextureRelations(view->baseTexture);
|
||||||
LatteTexture_UpdateTextureFromDynamicChanges(view->baseTexture);
|
LatteTexture_UpdateTextureFromDynamicChanges(view->baseTexture);
|
||||||
@ -1191,12 +1191,8 @@ LatteTextureView* LatteTC_GetTextureSliceViewOrTryCreate(MPTR srcImagePtr, MPTR
|
|||||||
void LatteTexture_UpdateDataToLatest(LatteTexture* texture)
|
void LatteTexture_UpdateDataToLatest(LatteTexture* texture)
|
||||||
{
|
{
|
||||||
if (LatteTC_HasTextureChanged(texture))
|
if (LatteTC_HasTextureChanged(texture))
|
||||||
{
|
LatteTexture_ReloadData(texture);
|
||||||
g_renderer->texture_rememberBoundTexture(0);
|
|
||||||
g_renderer->texture_bindAndActivateRawTex(texture, 0);
|
|
||||||
LatteTexture_ReloadData(texture, 0);
|
|
||||||
g_renderer->texture_restoreBoundTexture(0);
|
|
||||||
}
|
|
||||||
if (texture->reloadFromDynamicTextures)
|
if (texture->reloadFromDynamicTextures)
|
||||||
{
|
{
|
||||||
LatteTexture_UpdateCacheFromDynamicTextures(texture);
|
LatteTexture_UpdateCacheFromDynamicTextures(texture);
|
||||||
@ -1245,7 +1241,7 @@ std::vector<LatteTexture*>& LatteTexture::GetAllTextures()
|
|||||||
return sAllTextures;
|
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)
|
Latte::E_HWTILEMODE tileMode, bool isDepth)
|
||||||
{
|
{
|
||||||
_AddTextureToGlobalList(this);
|
_AddTextureToGlobalList(this);
|
||||||
|
@ -24,11 +24,9 @@ struct LatteSamplerState
|
|||||||
class LatteTexture
|
class LatteTexture
|
||||||
{
|
{
|
||||||
public:
|
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 ~LatteTexture();
|
||||||
|
|
||||||
virtual void InitTextureState() {};
|
|
||||||
|
|
||||||
LatteTextureView* GetOrCreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount)
|
LatteTextureView* GetOrCreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount)
|
||||||
{
|
{
|
||||||
for (auto& itr : views)
|
for (auto& itr : views)
|
||||||
@ -307,7 +305,7 @@ std::vector<LatteTextureInformation> LatteTexture_QueryCacheInfo();
|
|||||||
|
|
||||||
float* LatteTexture_getEffectiveTextureScale(LatteConst::ShaderType shaderType, sint32 texUnit);
|
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 LatteTexture_Delete(LatteTexture* texture);
|
||||||
|
|
||||||
void LatteTextureLoader_writeReadbackTextureToMemory(LatteTextureDefinition* textureData, uint32 sliceIndex, uint32 mipIndex, uint8* linearPixelData);
|
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;
|
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++;
|
tex->reloadCount++;
|
||||||
for(sint32 mip=0; mip<tex->mipLevels; mip++)
|
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);
|
sint32 numSlices = std::max(tex->depth, 1);
|
||||||
for(sint32 s=0; s<numSlices; s++)
|
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 )
|
else if( tex->dim == Latte::E_DIM::DIM_CUBEMAP )
|
||||||
{
|
{
|
||||||
cemu_assert_debug((tex->depth % 6) == 0);
|
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)
|
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++)
|
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 )
|
else if( tex->dim == Latte::E_DIM::DIM_3D )
|
||||||
{
|
{
|
||||||
sint32 mipDepth = std::max(tex->depth>>mip, 1);
|
sint32 mipDepth = std::max(tex->depth>>mip, 1);
|
||||||
for(sint32 s=0; s<mipDepth; s++)
|
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
|
else
|
||||||
{
|
{
|
||||||
// load slice 0
|
// 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();
|
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
|
// init slice/mip info array
|
||||||
LatteTexture_InitSliceAndMipInfo(tex);
|
LatteTexture_InitSliceAndMipInfo(tex);
|
||||||
LatteTexture_RegisterTextureMemoryOccupancy(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_MarkTextureStillInUse(tex);
|
||||||
LatteTC_RegisterTexture(tex);
|
LatteTC_RegisterTexture(tex);
|
||||||
// create initial view that maps to the whole texture
|
// create initial view that maps to the whole texture
|
||||||
@ -247,7 +247,7 @@ void LatteTexture_updateTexturesForStage(LatteDecompilerShader* shaderContext, u
|
|||||||
textureView->lastTextureBindIndex = LatteGPUState.textureBindCounter;
|
textureView->lastTextureBindIndex = LatteGPUState.textureBindCounter;
|
||||||
rendererGL->renderstate_updateTextureSettingsGL(shaderContext, textureView, textureIndex + glBackendBaseTexUnit, word4, textureIndex, isDepthSampler);
|
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
|
// update if data changed
|
||||||
bool swizzleChanged = false;
|
bool swizzleChanged = false;
|
||||||
if (textureView->baseTexture->swizzle != swizzle)
|
if (textureView->baseTexture->swizzle != swizzle)
|
||||||
@ -285,9 +285,8 @@ void LatteTexture_updateTexturesForStage(LatteDecompilerShader* shaderContext, u
|
|||||||
textureView->baseTexture->physMipAddress = physMipAddr;
|
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);
|
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;
|
LatteTexture* baseTexture = textureView->baseTexture;
|
||||||
if (baseTexture->reloadFromDynamicTextures)
|
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 };
|
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);
|
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)
|
if (texView)
|
||||||
return 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()
|
void LatteHandleOSScreen_prepareTextures()
|
||||||
@ -71,8 +71,7 @@ bool LatteHandleOSScreen_TV()
|
|||||||
const uint32 bufferIndexTV = (bufferDisplayTV);
|
const uint32 bufferIndexTV = (bufferDisplayTV);
|
||||||
const uint32 bufferIndexDRC = bufferDisplayDRC;
|
const uint32 bufferIndexDRC = bufferDisplayDRC;
|
||||||
|
|
||||||
g_renderer->texture_bindAndActivate(osScreenTVTex[bufferIndexTV], 0);
|
LatteTexture_ReloadData(osScreenTVTex[bufferIndexTV]->baseTexture);
|
||||||
LatteTexture_ReloadData(osScreenTVTex[bufferIndexTV]->baseTexture, 0);
|
|
||||||
|
|
||||||
// TV screen
|
// TV screen
|
||||||
LatteRenderTarget_copyToBackbuffer(osScreenTVTex[bufferIndexTV]->baseTexture->baseView, false);
|
LatteRenderTarget_copyToBackbuffer(osScreenTVTex[bufferIndexTV]->baseTexture->baseView, false);
|
||||||
@ -94,8 +93,7 @@ bool LatteHandleOSScreen_DRC()
|
|||||||
|
|
||||||
const uint32 bufferIndexDRC = bufferDisplayDRC;
|
const uint32 bufferIndexDRC = bufferDisplayDRC;
|
||||||
|
|
||||||
g_renderer->texture_bindAndActivate(osScreenDRCTex[bufferIndexDRC], 0);
|
LatteTexture_ReloadData(osScreenDRCTex[bufferIndexDRC]->baseTexture);
|
||||||
LatteTexture_ReloadData(osScreenDRCTex[bufferIndexDRC]->baseTexture, 0);
|
|
||||||
|
|
||||||
// GamePad screen
|
// GamePad screen
|
||||||
LatteRenderTarget_copyToBackbuffer(osScreenDRCTex[bufferIndexDRC]->baseTexture->baseView, true);
|
LatteRenderTarget_copyToBackbuffer(osScreenDRCTex[bufferIndexDRC]->baseTexture->baseView, true);
|
||||||
|
@ -19,20 +19,17 @@ static GLuint _genTextureHandleGL()
|
|||||||
return texIdPool[texIdPoolIndex - 1];
|
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)
|
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
|
// set format info
|
||||||
FormatInfoGL glFormatInfo;
|
FormatInfoGL glFormatInfo;
|
||||||
GetOpenGLFormatInfo(isDepth, format, dim, &glFormatInfo);
|
GetOpenGLFormatInfo(isDepth, format, dim, &glFormatInfo);
|
||||||
this->glInternalFormat = glFormatInfo.glInternalFormat;
|
this->glInternalFormat = glFormatInfo.glInternalFormat;
|
||||||
this->isAlternativeFormat = glFormatInfo.isUsingAlternativeFormat;
|
this->isAlternativeFormat = glFormatInfo.isUsingAlternativeFormat;
|
||||||
this->hasStencil = glFormatInfo.hasStencil; // todo - should get this from the GX2 format?
|
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
|
// set debug name
|
||||||
bool useGLDebugNames = false;
|
bool useGLDebugNames = false;
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
@ -54,9 +51,8 @@ LatteTextureGL::~LatteTextureGL()
|
|||||||
catchOpenGLError();
|
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)
|
if (dim == Latte::E_DIM::DIM_2D)
|
||||||
texTarget = GL_TEXTURE_2D;
|
texTarget = GL_TEXTURE_2D;
|
||||||
else if (dim == Latte::E_DIM::DIM_1D)
|
else if (dim == Latte::E_DIM::DIM_1D)
|
||||||
@ -73,6 +69,10 @@ void LatteTextureGL::GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& te
|
|||||||
{
|
{
|
||||||
cemu_assert_unimplemented();
|
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)
|
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);
|
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)
|
void LatteTextureGL::GetOpenGLFormatInfo(bool isDepth, Latte::E_GX2SURFFMT format, Latte::E_DIM dim, FormatInfoGL* formatInfoOut)
|
||||||
{
|
{
|
||||||
formatInfoOut->isUsingAlternativeFormat = false;
|
formatInfoOut->isUsingAlternativeFormat = false;
|
||||||
|
@ -6,14 +6,12 @@
|
|||||||
class LatteTextureGL : public LatteTexture
|
class LatteTextureGL : public LatteTexture
|
||||||
{
|
{
|
||||||
public:
|
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);
|
uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth);
|
||||||
|
|
||||||
~LatteTextureGL();
|
~LatteTextureGL();
|
||||||
|
|
||||||
static void GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& texId, GLint& texTarget);
|
static void GenerateEmptyTextureFromGX2Dim(Latte::E_DIM dim, GLuint& texId, GLint& texTarget, bool createForTargetType);
|
||||||
|
|
||||||
void InitTextureState() override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LatteTextureView* CreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount) override;
|
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 ||
|
firstSlice != 0 || firstMip != 0 || mipCount != texture->mipLevels || sliceCount != texture->depth ||
|
||||||
forceCreateNewTexId)
|
forceCreateNewTexId)
|
||||||
{
|
{
|
||||||
LatteTextureGL::GenerateEmptyTextureFromGX2Dim(dim, glTexId, glTexTarget);
|
LatteTextureGL::GenerateEmptyTextureFromGX2Dim(dim, glTexId, glTexTarget, false);
|
||||||
this->glInternalFormat = 0;
|
this->glInternalFormat = 0;
|
||||||
InitAliasView();
|
InitAliasView();
|
||||||
}
|
}
|
||||||
|
@ -77,8 +77,6 @@ static const GLenum glAlphaTestFunc[] =
|
|||||||
GL_ALWAYS
|
GL_ALWAYS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
OpenGLRenderer::OpenGLRenderer()
|
OpenGLRenderer::OpenGLRenderer()
|
||||||
{
|
{
|
||||||
glRendererState.useTextureUploadBuffer = false;
|
glRendererState.useTextureUploadBuffer = false;
|
||||||
@ -571,7 +569,7 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
|||||||
glViewportIndexedf(0, imageX, imageY, imageWidth, imageHeight);
|
glViewportIndexedf(0, imageX, imageY, imageWidth, imageHeight);
|
||||||
|
|
||||||
LatteTextureViewGL* texViewGL = (LatteTextureViewGL*)texView;
|
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);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, useLinearTexFilter ? GL_LINEAR : GL_NEAREST);
|
||||||
texViewGL->samplerState.filterMag = 0xFFFFFFFF;
|
texViewGL->samplerState.filterMag = 0xFFFFFFFF;
|
||||||
@ -586,7 +584,7 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
|||||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
|
|
||||||
// unbind texture
|
// unbind texture
|
||||||
g_renderer->texture_bindAndActivate(nullptr, 0);
|
texture_bindAndActivate(nullptr, 0);
|
||||||
|
|
||||||
catchOpenGLError();
|
catchOpenGLError();
|
||||||
|
|
||||||
@ -990,8 +988,9 @@ void OpenGLRenderer::texture_destroy(LatteTexture* hostTexture)
|
|||||||
delete 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);
|
cemu_assert_debug(hostTexture->isDataDefined == false);
|
||||||
sint32 effectiveBaseWidth = hostTexture->width;
|
sint32 effectiveBaseWidth = hostTexture->width;
|
||||||
sint32 effectiveBaseHeight = hostTexture->height;
|
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)
|
if (hostTexture->dim == Latte::E_DIM::DIM_2D || hostTexture->dim == Latte::E_DIM::DIM_2D_MSAA)
|
||||||
{
|
{
|
||||||
cemu_assert_debug(effectiveBaseDepth == 1);
|
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)
|
else if (hostTexture->dim == Latte::E_DIM::DIM_1D)
|
||||||
{
|
{
|
||||||
cemu_assert_debug(effectiveBaseHeight == 1);
|
cemu_assert_debug(effectiveBaseHeight == 1);
|
||||||
cemu_assert_debug(effectiveBaseDepth == 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)
|
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)
|
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)
|
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
|
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)
|
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;
|
auto hostTexture = (LatteTextureGL*)hostTextureGeneric;
|
||||||
|
|
||||||
sint32 effectiveWidth = width;
|
sint32 effectiveWidth = width;
|
||||||
sint32 effectiveHeight = height;
|
sint32 effectiveHeight = height;
|
||||||
sint32 effectiveDepth = depth;
|
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);
|
LatteTextureGL::GetOpenGLFormatInfo(hostTexture->isDepth, hostTexture->overwriteInfo.hasFormatOverwrite ? (Latte::E_GX2SURFFMT)hostTexture->overwriteInfo.format : hostTexture->format, hostTexture->dim, &glFormatInfo);
|
||||||
// upload slice
|
// upload slice
|
||||||
catchOpenGLError();
|
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 (hostTexture->dim == Latte::E_DIM::DIM_2D || hostTexture->dim == Latte::E_DIM::DIM_2D_MSAA)
|
||||||
{
|
{
|
||||||
if (glFormatInfo.glIsCompressed)
|
if (glFormatInfo.glIsCompressed)
|
||||||
{
|
glCompressedTextureSubImage2DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, mipIndex, 0, 0, effectiveWidth, effectiveHeight, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||||
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);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
glTextureSubImage2DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, mipIndex, 0, 0, effectiveWidth, effectiveHeight, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (hostTexture->dim == Latte::E_DIM::DIM_1D)
|
else if (hostTexture->dim == Latte::E_DIM::DIM_1D)
|
||||||
{
|
{
|
||||||
if (glFormatInfo.glIsCompressed == true)
|
if (glFormatInfo.glIsCompressed)
|
||||||
cemu_assert_unimplemented();
|
glCompressedTextureSubImage1DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, mipIndex, 0, width, glFormatInfo.glInternalFormat, imageSize, pixelData);
|
||||||
glTexSubImage1D(GL_TEXTURE_1D, mipIndex, 0, width, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, 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)
|
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
|
else
|
||||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, mipIndex, 0, 0, sliceIndex, effectiveWidth, effectiveHeight, 1, glFormatInfo.glSuppliedFormat, glFormatInfo.glSuppliedFormatType, pixelData);
|
glTextureSubImage3DWrapper(hostTexture->glTexTarget, hostTexture->glId_texture, 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);
|
|
||||||
}
|
}
|
||||||
catchOpenGLError();
|
catchOpenGLError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// use persistent buffers to upload data
|
// 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)
|
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);
|
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)
|
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)
|
void OpenGLRenderer::texture_bindAndActivate(LatteTextureView* textureView, uint32 textureUnit)
|
||||||
{
|
{
|
||||||
const auto textureViewGL = (LatteTextureViewGL*)textureView;
|
const auto textureViewGL = (LatteTextureViewGL*)textureView;
|
||||||
cemu_assert_debug(textureUnit < (sizeof(LatteBoundTexturesBackup) / sizeof(LatteBoundTexturesBackup[0])));
|
|
||||||
// don't call glBindTexture if the texture is already bound
|
// don't call glBindTexture if the texture is already bound
|
||||||
if (LatteBoundTextures[textureUnit] == textureViewGL)
|
if (m_latteBoundTextures[textureUnit] == textureViewGL)
|
||||||
{
|
{
|
||||||
texture_setActiveTextureUnit(textureUnit);
|
texture_setActiveTextureUnit(textureUnit);
|
||||||
return; // already bound
|
return; // already bound
|
||||||
}
|
}
|
||||||
// bind
|
// bind
|
||||||
LatteBoundTextures[textureUnit] = textureViewGL;
|
m_latteBoundTextures[textureUnit] = textureViewGL;
|
||||||
texture_setActiveTextureUnit(textureUnit);
|
texture_setActiveTextureUnit(textureUnit);
|
||||||
if (textureViewGL)
|
if (textureViewGL)
|
||||||
{
|
{
|
||||||
glBindTexture(textureViewGL->glTexTarget, textureViewGL->glTexId);
|
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++)
|
for (uint32 i = 0; i < Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3; i++)
|
||||||
{
|
{
|
||||||
if (LatteBoundTextures[i] == textureView)
|
if (m_latteBoundTextures[i] == textureView)
|
||||||
LatteBoundTextures[i] = nullptr;
|
m_latteBoundTextures[i] = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// similar to _bindAndActivate() but doesn't call _setActiveTextureUnit() if texture is already bound
|
// 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_bindOnly(LatteTextureView* textureView1, uint32 textureUnit)
|
void OpenGLRenderer::texture_setLatteTexture(LatteTextureView* textureView1, uint32 textureUnit)
|
||||||
{
|
{
|
||||||
auto textureView = ((LatteTextureViewGL*)textureView1);
|
auto textureView = ((LatteTextureViewGL*)textureView1);
|
||||||
|
|
||||||
cemu_assert_debug(textureUnit < Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3);
|
cemu_assert_debug(textureUnit < Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3);
|
||||||
if (LatteBoundTextures[textureUnit] == textureView)
|
if (m_latteBoundTextures[textureUnit] == textureView)
|
||||||
return;
|
return;
|
||||||
if (textureView == nullptr)
|
if (textureView == nullptr)
|
||||||
return;
|
return;
|
||||||
@ -1301,45 +1254,17 @@ void OpenGLRenderer::texture_bindOnly(LatteTextureView* textureView1, uint32 tex
|
|||||||
if (glBindTextureUnit)
|
if (glBindTextureUnit)
|
||||||
{
|
{
|
||||||
glBindTextureUnit(textureUnit, textureView->glTexId);
|
glBindTextureUnit(textureUnit, textureView->glTexId);
|
||||||
LatteBoundTextures[textureUnit] = textureView;
|
m_latteBoundTextures[textureUnit] = textureView;
|
||||||
texUnitTexId[textureUnit] = textureView->glTexId;
|
|
||||||
texUnitTexTarget[textureUnit] = textureView->glTexTarget;
|
|
||||||
activeTextureUnit = -1;
|
activeTextureUnit = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
texture_setActiveTextureUnit(textureUnit);
|
texture_setActiveTextureUnit(textureUnit);
|
||||||
glBindTexture(textureView->glTexTarget, textureView->glTexId);
|
glBindTexture(textureView->glTexTarget, textureView->glTexId);
|
||||||
LatteBoundTextures[textureUnit] = textureView;
|
m_latteBoundTextures[textureUnit] = textureView;
|
||||||
texUnitTexId[textureUnit] = textureView->glTexId;
|
|
||||||
texUnitTexTarget[textureUnit] = textureView->glTexTarget;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
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)
|
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_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;
|
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_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit) override;
|
||||||
void texture_bindAndActivateRawTex(LatteTexture* texture, uint32 textureUnit) override;
|
void texture_bindAndActivate(LatteTextureView* textureView, uint32 textureUnit);
|
||||||
void texture_bindOnly(LatteTextureView* textureView, 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;
|
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);
|
void texture_notifyDelete(LatteTextureView* textureView);
|
||||||
@ -188,14 +185,7 @@ private:
|
|||||||
bool m_isXfbActive = false;
|
bool m_isXfbActive = false;
|
||||||
|
|
||||||
sint32 activeTextureUnit = 0;
|
sint32 activeTextureUnit = 0;
|
||||||
void* LatteBoundTextures[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 3]{};
|
void* m_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]{};
|
|
||||||
|
|
||||||
// attribute stream
|
// attribute stream
|
||||||
GLuint glAttributeCacheAB{};
|
GLuint glAttributeCacheAB{};
|
||||||
|
@ -1342,7 +1342,7 @@ uint32 _correctTextureCompSelGL(Latte::E_GX2SURFFMT format, uint32 compSel)
|
|||||||
return 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)
|
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
|
* Update channel swizzling and other texture settings for a texture unit
|
||||||
* hostTextureView is the texture unit view used on the host side
|
* 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)
|
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;
|
auto hostTextureView = (LatteTextureViewGL*)_hostTextureView;
|
||||||
|
|
||||||
LatteTexture* baseTexture = hostTextureView->baseTexture;
|
LatteTexture* baseTexture = hostTextureView->baseTexture;
|
||||||
|
@ -52,7 +52,7 @@ void OpenGLRenderer::surfaceCopy_copySurfaceWithFormatConversion(LatteTexture* s
|
|||||||
LatteTextureView* sourceView = sourceTexture->GetOrCreateView(srcMip, 1, srcSlice, 1);
|
LatteTextureView* sourceView = sourceTexture->GetOrCreateView(srcMip, 1, srcSlice, 1);
|
||||||
LatteTextureView* destinationView = destinationTexture->GetOrCreateView(dstMip, 1, dstSlice, 1);
|
LatteTextureView* destinationView = destinationTexture->GetOrCreateView(dstMip, 1, dstSlice, 1);
|
||||||
|
|
||||||
g_renderer->texture_bindAndActivate(sourceView, 0);
|
texture_bindAndActivate(sourceView, 0);
|
||||||
catchOpenGLError();
|
catchOpenGLError();
|
||||||
// setup texture attributes
|
// setup texture attributes
|
||||||
_setDepthCompareMode((LatteTextureViewGL*)sourceView, 0);
|
_setDepthCompareMode((LatteTextureViewGL*)sourceView, 0);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
#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/OpenGLTextureReadback.h"
|
||||||
#include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h"
|
#include "Cafe/HW/Latte/Renderer/OpenGL/LatteTextureViewGL.h"
|
||||||
|
|
||||||
@ -93,8 +94,7 @@ LatteTextureReadbackInfoGL::~LatteTextureReadbackInfoGL()
|
|||||||
void LatteTextureReadbackInfoGL::StartTransfer()
|
void LatteTextureReadbackInfoGL::StartTransfer()
|
||||||
{
|
{
|
||||||
cemu_assert(m_textureView);
|
cemu_assert(m_textureView);
|
||||||
|
((OpenGLRenderer*)g_renderer.get())->texture_bindAndActivate(m_textureView, 0);
|
||||||
g_renderer->texture_bindAndActivate(m_textureView, 0);
|
|
||||||
// create unsynchronized buffer
|
// create unsynchronized buffer
|
||||||
glGenBuffers(1, &texImageBufferGL);
|
glGenBuffers(1, &texImageBufferGL);
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 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_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 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_setLatteTexture(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_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 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;
|
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/VulkanRenderer.h"
|
||||||
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.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)
|
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();
|
vkObjTex = new VKRObjectTexture();
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
class LatteTextureVk : public LatteTexture
|
class LatteTextureVk : public LatteTexture
|
||||||
{
|
{
|
||||||
public:
|
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);
|
uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth);
|
||||||
|
|
||||||
~LatteTextureVk();
|
~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);
|
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)
|
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)
|
void VulkanRenderer::texture_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit)
|
||||||
{
|
|
||||||
m_state.boundTexture[textureUnit] = static_cast<LatteTextureViewVk*>(textureView);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VulkanRenderer::texture_bindOnly(LatteTextureView* textureView, uint32 textureUnit)
|
|
||||||
{
|
{
|
||||||
m_state.boundTexture[textureUnit] = static_cast<LatteTextureViewVk*>(textureView);
|
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;
|
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_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit) override;
|
||||||
void texture_bindOnly(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;
|
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;
|
LatteTextureReadbackInfo* texture_createReadback(LatteTextureView* textureView) override;
|
||||||
|
|
||||||
|
@ -42,6 +42,177 @@ typedef struct __GLXFBConfigRec *GLXFBConfig;
|
|||||||
#undef GLFUNC
|
#undef GLFUNC
|
||||||
#undef EGLFUNC
|
#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:
|
// this prevents Windows GL.h from being included:
|
||||||
#define __gl_h_
|
#define __gl_h_
|
||||||
#define __GL_H__
|
#define __GL_H__
|
||||||
|
@ -171,10 +171,13 @@ GLFUNC(PFNGLTEXSTORAGE2DPROC, glTexStorage2D)
|
|||||||
GLFUNC(PFNGLTEXSTORAGE3DPROC, glTexStorage3D)
|
GLFUNC(PFNGLTEXSTORAGE3DPROC, glTexStorage3D)
|
||||||
GLFUNC(PFNGLTEXIMAGE3DPROC, glTexImage3D)
|
GLFUNC(PFNGLTEXIMAGE3DPROC, glTexImage3D)
|
||||||
GLFUNC(PFNGLTEXSUBIMAGE3DPROC, glTexSubImage3D)
|
GLFUNC(PFNGLTEXSUBIMAGE3DPROC, glTexSubImage3D)
|
||||||
|
GLFUNC(PFNGLCOMPRESSEDTEXIMAGE1DPROC, glCompressedTexImage1D)
|
||||||
GLFUNC(PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D)
|
GLFUNC(PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D)
|
||||||
GLFUNC(PFNGLCOMPRESSEDTEXIMAGE3DPROC, glCompressedTexImage3D)
|
GLFUNC(PFNGLCOMPRESSEDTEXIMAGE3DPROC, glCompressedTexImage3D)
|
||||||
|
GLFUNC(PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC, glCompressedTexSubImage1D)
|
||||||
GLFUNC(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, glCompressedTexSubImage2D)
|
GLFUNC(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, glCompressedTexSubImage2D)
|
||||||
GLFUNC(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedTexSubImage3D)
|
GLFUNC(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedTexSubImage3D)
|
||||||
|
GLFUNC(PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC, glCompressedTextureSubImage1D)
|
||||||
GLFUNC(PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC, glCompressedTextureSubImage2D)
|
GLFUNC(PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC, glCompressedTextureSubImage2D)
|
||||||
GLFUNC(PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC, glCompressedTextureSubImage3D)
|
GLFUNC(PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC, glCompressedTextureSubImage3D)
|
||||||
GLFUNC(PFNGLCOPYIMAGESUBDATAPROC, glCopyImageSubData)
|
GLFUNC(PFNGLCOPYIMAGESUBDATAPROC, glCopyImageSubData)
|
||||||
@ -184,12 +187,17 @@ GLFUNC(PFNGLINVALIDATETEXIMAGEPROC, glInvalidateTexImage)
|
|||||||
|
|
||||||
// texture DSA
|
// texture DSA
|
||||||
|
|
||||||
|
GLFUNC(PFNGLCREATETEXTURESPROC, glCreateTextures)
|
||||||
GLFUNC(PFNGLBINDTEXTUREUNITPROC, glBindTextureUnit)
|
GLFUNC(PFNGLBINDTEXTUREUNITPROC, glBindTextureUnit)
|
||||||
GLFUNC(PFNGLGETTEXTURELEVELPARAMETERIVPROC, glGetTextureLevelParameteriv)
|
GLFUNC(PFNGLGETTEXTURELEVELPARAMETERIVPROC, glGetTextureLevelParameteriv)
|
||||||
GLFUNC(PFNGLTEXTUREPARAMETERIPROC, glTextureParameteri)
|
GLFUNC(PFNGLTEXTUREPARAMETERIPROC, glTextureParameteri)
|
||||||
GLFUNC(PFNGLGETTEXTURESUBIMAGEPROC, glGetTextureSubImage)
|
GLFUNC(PFNGLGETTEXTURESUBIMAGEPROC, glGetTextureSubImage)
|
||||||
|
GLFUNC(PFNGLTEXTURESUBIMAGE1DPROC, glTextureSubImage1D)
|
||||||
GLFUNC(PFNGLTEXTURESUBIMAGE2DPROC, glTextureSubImage2D);
|
GLFUNC(PFNGLTEXTURESUBIMAGE2DPROC, glTextureSubImage2D);
|
||||||
GLFUNC(PFNGLTEXTURESUBIMAGE3DPROC, glTextureSubImage3D)
|
GLFUNC(PFNGLTEXTURESUBIMAGE3DPROC, glTextureSubImage3D)
|
||||||
|
GLFUNC(PFNGLTEXTURESTORAGE1DPROC, glTextureStorage1D)
|
||||||
|
GLFUNC(PFNGLTEXTURESTORAGE2DPROC, glTextureStorage2D)
|
||||||
|
GLFUNC(PFNGLTEXTURESTORAGE3DPROC, glTextureStorage3D)
|
||||||
|
|
||||||
// instancing / draw
|
// instancing / draw
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user