7#include "ps2gl/texture.h"
11#include "ps2gl/debug.h"
12#include "ps2gl/dlgmanager.h"
13#include "ps2gl/dlist.h"
14#include "ps2gl/glcontext.h"
15#include "ps2gl/immgmanager.h"
16#include "ps2gl/metrics.h"
27 , InsideDListDef(false)
31 , TexMode(GS::TexMode::kModulate)
34 for (
int i = 0; i < NumTexNames; i++)
39 CurTexture = DefaultTex;
42CTexManager::~CTexManager()
48 for (
int i = 0; i < NumTexNames; i++) {
64 pGLContext->GetTexManager().SetTexEnabled(IsEnabled);
65 return CDListCmd::GetNextCmd(
this);
69void CTexManager::SetTexEnabled(
bool yesNo)
71 if (!InsideDListDef) {
72 if (IsTexEnabled != yesNo) {
73 GLContext.TexEnabledChanged();
74 GLContext.GetImmGeomManager().GetRendererManager().TexEnabledChanged(yesNo);
78 CDList& dlist = GLContext.GetDListManager().GetOpenDList();
80 GLContext.TexEnabledChanged();
94 pGLContext->GetTexManager().SetTexMode(Mode);
95 return CDListCmd::GetNextCmd(
this);
99void CTexManager::SetTexMode(GS::tTexMode mode)
104 CDList& dlist = GLContext.GetDListManager().GetOpenDList();
109void CTexManager::GenTextures(GLsizei numNewTexNames, GLuint* newTexNames)
111 for (
int curTexName = 0; curTexName < numNewTexNames; curTexName++) {
114 for (i = 0; i < NumTexNames; i++) {
116 if (Cursor != 0 && TexNames[Cursor] == NULL)
122 if (i == NumTexNames) {
123 mError(
"No free texture names. Time to write a less braindead tex manager.");
126 while (i < NumTexNames) {
131 newTexNames[curTexName] = Cursor;
137void CTexManager::UseCurTexture(CVifSCDmaPacket& renderPacket)
140 GS::tPSM psm = CurTexture->GetPSM();
142 if (psm == GS::kPsm8 || psm == GS::kPsm8h) {
143 mErrorIf(CurClut == NULL,
144 "Trying to use an indexed-color texture with no color table given!");
145 CurClut->Load(renderPacket);
148 CurTexture->SetTexMode(TexMode);
149 if (CurTexture->GetPSM() == GS::kPsm8
150 || CurTexture->GetPSM() == GS::kPsm8h)
151 CurTexture->SetClut(*CurClut);
152 CurTexture->Use(renderPacket);
157 unsigned int TexName;
166 pGLContext->GetTexManager().BindTexture(TexName);
167 return CDListCmd::GetNextCmd(
this);
171void CTexManager::BindTexture(GLuint texNameToBind)
173 GLContext.TextureChanged();
175 if (!InsideDListDef) {
176 if (texNameToBind == 0) {
178 CurTexture = DefaultTex;
180 if (TexNames[texNameToBind] == NULL)
181 TexNames[texNameToBind] =
new CMMTexture(GS::kContext1);
182 CurTexture = TexNames[texNameToBind];
185 pglAddToMetric(kMetricsBindTexture);
187 CDList& dlist = GLContext.GetDListManager().GetOpenDList();
192void CTexManager::DeleteTextures(GLsizei numToDelete,
const GLuint* texNames)
194 for (
int i = 0; i < numToDelete; i++) {
195 mErrorIf(TexNames[texNames[i]] == NULL,
196 "Trying to delete a texture that doesn't exist!");
197 GLuint texName = texNames[i];
198 if (CurTexture == TexNames[texName])
199 CurTexture = DefaultTex;
200 delete TexNames[texName];
201 TexNames[texName] = NULL;
217 pGLContext->GetTexManager().SetCurTexParam(PName, Param);
218 return CDListCmd::GetNextCmd(
this);
222void CTexManager::SetCurTexParam(GLenum pname, GLint param)
224 if (!InsideDListDef) {
228 case GL_TEXTURE_MIN_FILTER:
229 tex.SetMinMode((GS::tMinMode)(param & 0xf));
231 case GL_TEXTURE_MAG_FILTER:
232 tex.SetMagMode((GS::tMagMode)(param & 0xf));
234 case GL_TEXTURE_MIN_LOD:
235 case GL_TEXTURE_MAX_LOD:
236 case GL_TEXTURE_BASE_LEVEL:
237 case GL_TEXTURE_MAX_LEVEL:
238 case GL_TEXTURE_PRIORITY:
239 case GL_TEXTURE_BORDER_COLOR:
242 case GL_TEXTURE_WRAP_S:
243 tex.SetWrapModeS((GS::tTexWrapMode)(param & 0xf));
245 case GL_TEXTURE_WRAP_T:
246 tex.SetWrapModeT((GS::tTexWrapMode)(param & 0xf));
248 case GL_TEXTURE_WRAP_R:
249 mNotImplemented(
"Sorry, only 2d textures.");
253 CDList& dlist = GLContext.GetDListManager().GetOpenDList();
260 unsigned int Width, Height;
274 pGLContext->GetTexManager().SetCurTexImage(Image, Width, Height, Psm);
275 return CDListCmd::GetNextCmd(
this);
279void CTexManager::SetCurTexImage(tU128* imagePtr, tU32 w, tU32 h,
282 GLContext.TextureChanged();
284 if (!InsideDListDef) {
285 CurTexture->
SetImage(imagePtr, w, h, psm);
286 if (psm != GS::kPsm24)
287 CurTexture->SetUseTexAlpha(
true);
289 CurTexture->SetUseTexAlpha(
false);
293 CDList& dlist = GLContext.GetDListManager().GetOpenDList();
305 , NumEntries(numEntries)
310 pGLContext->GetTexManager().SetCurClut(Clut, NumEntries);
311 return CDListCmd::GetNextCmd(
this);
315void CTexManager::SetCurClut(
const void* clut,
int numEntries)
317 GLContext.TextureChanged();
319 if (!InsideDListDef) {
325 CDList& dlist = GLContext.GetDListManager().GetOpenDList();
331 GS::CMemArea& Texture;
340 pGLContext->GetTexManager().SetGsTexture(Texture);
341 return CDListCmd::GetNextCmd(
this);
345void CTexManager::SetGsTexture(GS::CMemArea& area)
347 GLContext.TextureChanged();
352 CDList& dlist = GLContext.GetDListManager().GetOpenDList();
361CMMTexture::CMMTexture(GS::tContext context)
371 SetClutLoadConditions(1);
374CMMTexture::~CMMTexture()
390 CTexture::SetImage(imagePtr, w, h, psm, NULL);
393 tU32 bufWidth = gsrTex0.tb_width * 64;
394 pImageMem =
new GS::CMemArea(bufWidth, h, psm, GS::kAlignBlock);
405 CTexEnv::SetPSM(area.GetPixFormat());
406 CTexEnv::SetDimensions(area.GetWidth(), area.GetHeight());
407 SetImageGsAddr(area.GetWordAddr());
412void CMMTexture::ChangePsm(GS::tPSM psm)
420 if (GS::GetBitsPerPixel(psm) == GS::GetBitsPerPixel(GetPSM())) {
422 CTexEnv::SetPSM(psm);
423 pImageUploadPkt->ChangePsm(psm);
427 int bpp = GS::GetBitsPerPixel(GetPSM());
428 if (bpp == 8 && GetPSM() == GS::kPsm8h) {
430 ChangePsm(GS::kPsm8);
431 }
else if (bpp == 4 && GetPSM() != GS::kPsm4) {
433 ChangePsm(GS::kPsm4);
440void CMMTexture::Load(
bool waitForEnd)
442 mErrorIf(pImageMem == NULL,
443 "Trying to load a texture that hasn't been defined!");
445 if (!pImageMem->IsAllocated()) {
447 if (GetPSM() != pImageMem->GetPixFormat())
448 ChangePsm(pImageMem->GetPixFormat());
449 SetImageGsAddr(pImageMem->GetWordAddr());
455 SendImage(waitForEnd, Packet::kDontFlushCache);
458 pglAddToMetric(kMetricsTextureUploadCount);
464void CMMTexture::Load(CSCDmaPacket& packet)
466 mErrorIf(pImageMem == NULL,
467 "Trying to load a texture that hasn't been defined!");
468 if (!pImageMem->IsAllocated()) {
470 if (GetPSM() != pImageMem->GetPixFormat())
471 ChangePsm(pImageMem->GetPixFormat());
472 SetImageGsAddr(pImageMem->GetWordAddr());
479 pglAddToMetric(kMetricsTextureUploadCount);
482void CMMTexture::Load(CVifSCDmaPacket& packet)
484 mErrorIf(pImageMem == NULL,
485 "Trying to load a texture that hasn't been defined!");
486 if (!pImageMem->IsAllocated()) {
488 if (GetPSM() != pImageMem->GetPixFormat())
489 ChangePsm(pImageMem->GetPixFormat());
490 SetImageGsAddr(pImageMem->GetWordAddr());
500 pglAddToMetric(kMetricsTextureUploadCount);
506void CMMTexture::Use(
bool waitForEnd)
510 SendSettings(waitForEnd, Packet::kDontFlushCache);
512void CMMTexture::Use(CSCDmaPacket& packet)
516 SendSettings(packet);
518void CMMTexture::Use(CVifSCDmaPacket& packet)
522 SendSettings(packet);
525void CMMTexture::Free(
void)
531void CMMTexture::BindToSlot(GS::CMemSlot& slot)
544void CMMClut::Load(CVifSCDmaPacket& packet)
546 if (!GsMem.IsAllocated()) {
548 SetGsAddr(GsMem.GetWordAddr());
551 pglAddToMetric(kMetricsClutUploadCount);
559void glGenTextures(GLsizei numNewTexNames, GLuint* newTexNames)
561 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
563 CTexManager& texManager = pGLContext->GetTexManager();
564 texManager.GenTextures(numNewTexNames, newTexNames);
567void glBindTexture(GLenum target, GLuint texName)
569 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
571 mErrorIf(target != GL_TEXTURE_2D,
"There are only 2D textures in ps2gl");
573 CTexManager& texManager = pGLContext->GetTexManager();
574 texManager.BindTexture(texName);
577void glDeleteTextures(GLsizei numToDelete,
const GLuint* texNames)
579 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
581 CTexManager& texManager = pGLContext->GetTexManager();
582 texManager.DeleteTextures(numToDelete, texNames);
585void glTexImage2D(GLenum target,
587 GLint internalFormat,
593 const GLvoid* pixels)
595 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
597 if (target == GL_PROXY_TEXTURE_2D) {
602 mNotImplemented(
"mipmapping");
606 mNotImplemented(
"texture borders");
609 if ((
unsigned int)pixels & 0xf) {
610 mNotImplemented(
"texture data needs to be aligned to at least 16 bytes, "
611 "preferably 9 quads");
614 GS::tPSM psm = GS::kInvalidPsm;
617 if (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8)
619 else if (type == GL_UNSIGNED_SHORT_5_5_5_1)
622 mNotImplemented(
"RGBA textures should have a type of GL_UNSIGNED_BYTE, "
623 "GL_UNSIGNED_INT_8_8_8_8, or GL_UNSIGNED_SHORT_5_5_5_1");
627 if (type == GL_UNSIGNED_BYTE)
630 mNotImplemented(
"RGB textures should have a type of GL_UNSIGNED_BYTE");
634 if (type == GL_UNSIGNED_BYTE)
637 mNotImplemented(
"indexed textures should have a type of GL_UNSIGNED_BYTE");
641 mError(
"Unknown texture format");
644 if (psm != GS::kInvalidPsm) {
646 tm.SetCurTexImage((tU128*)pixels, width, height, psm);
650void glColorTable(GLenum target, GLenum internalFormat,
651 GLsizei width, GLenum format, GLenum type,
654 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
656 mWarnIf(target != GL_COLOR_TABLE,
657 "glColorTable only supports GL_COLOR_TABLE");
659 mErrorIf(width != 16 && width != 256,
660 "A color table must contain either 16 or 256 entries");
661 mErrorIf(format != GL_RGB && format != GL_RGBA,
662 "The pixel format of color tables must be either GL_RGB or GL_RGBA");
663 mWarnIf(type != GL_UNSIGNED_INT && type != GL_UNSIGNED_INT_8_8_8_8,
664 "The type of color table data must be either GL_UNSIGNED_INT or"
665 "GL_UNSIGNED_INT_8_8_8_8");
666 mErrorIf((
unsigned int)table & (16 - 1),
667 "Color tables in ps2gl need to be 16-byte aligned in memory..");
670 tm.SetCurClut(table, width);
673void glTexParameteri(GLenum target, GLenum pname, GLint param)
675 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
677 if (target != GL_TEXTURE_2D) {
678 mNotImplemented(
"Sorry, only 2d textures.");
682 pGLContext->GetTexManager().SetCurTexParam(pname, param);
685void glTexParameterf(GLenum target, GLenum pname, GLfloat param)
687 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
689 glTexParameteri(target, pname, (GLint)param);
692void glTexParameteriv(GLenum target, GLenum pname, GLint* param)
694 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
696 glTexParameteri(target, pname, *param);
699void glTexParameterfv(GLenum target, GLenum pname,
const GLfloat* param)
701 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
703 glTexParameteri(target, pname, (GLint)*param);
706void glTexEnvi(GLenum target, GLenum pname, GLint param)
708 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
714 tm.SetTexMode((GS::tTexMode)(param & 0xf));
717 mWarn(
"GL_DECAL functions exactly as GL_REPLACE right now.");
719 tm.SetTexMode((GS::tTexMode)(param & 0xf));
727void glTexEnvf(GLenum target, GLenum pname, GLfloat param)
729 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
731 glTexEnvi(target, pname, (GLint)param);
734void glTexEnvfv(GLenum target, GLenum pname, GLfloat* param)
736 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
738 glTexEnvi(target, pname, (GLint)*param);
741void glTexEnviv(GLenum target, GLenum pname, GLint* param)
743 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
745 glTexEnvi(target, pname, *param);
748void glTexSubImage2D(GLenum target,
int level,
749 int xoffset,
int yoffset,
int width,
int height,
750 GLenum format, GLenum type,
753 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
758void glCopyTexImage2D(GLenum target,
int level,
760 int x,
int y,
int width,
int height,
763 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
768void glCopyTexSubImage2D(GLenum target,
int level,
769 int xoffset,
int yoffset,
int x,
int y,
770 int width,
int height)
772 GL_FUNC_DEBUG(
"%s\n", __FUNCTION__);
792 CTexManager& texManager = pGLContext->GetTexManager();
793 CMMTexture& texture = texManager.GetNamedTexture(texId);
804 CTexManager& texManager = pGLContext->GetTexManager();
805 CMMTexture& texture = texManager.GetNamedTexture(texId);
806 texture.BindToSlot(*
reinterpret_cast<GS::CMemSlot*
>(mem_slot));
816 CTexManager& texManager = pGLContext->GetTexManager();
817 GS::CMemArea* texArea =
reinterpret_cast<GS::CMemArea*
>(tex_area_handle);
818 texManager.SetGsTexture(*texArea);
void SetImage(const GS::CMemArea &area)
void pglTextureFromGsMemArea(pgl_area_handle_t tex_area_handle)
void pglFreeTexture(GLuint texId)
void pglBindTextureToSlot(GLuint texId, pgl_slot_handle_t mem_slot)