mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #3367 from unknownbrackets/gpu-minor
More gstate accessors / typesafety
This commit is contained in:
commit
e860abdd6d
18 changed files with 138 additions and 151 deletions
|
@ -475,7 +475,7 @@ void FramebufferManager::SetRenderFrameBuffer() {
|
|||
// As there are no clear "framebuffer width" and "framebuffer height" registers,
|
||||
// we need to infer the size of the current framebuffer somehow. Let's try the viewport.
|
||||
|
||||
GEBufferFormat fmt = static_cast<GEBufferFormat>(gstate.framebufpixformat & 3);
|
||||
GEBufferFormat fmt = gstate.FrameBufFormat();
|
||||
|
||||
int drawing_width, drawing_height;
|
||||
GuessDrawingSize(drawing_width, drawing_height);
|
||||
|
|
|
@ -662,7 +662,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
|
|||
}
|
||||
|
||||
if (!Memory::IsValidAddress(gstate_c.vertexAddr)) {
|
||||
ERROR_LOG(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr);
|
||||
ERROR_LOG_REPORT(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -672,12 +672,18 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
|
|||
void *inds = 0;
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {
|
||||
if (!Memory::IsValidAddress(gstate_c.indexAddr)) {
|
||||
ERROR_LOG(G3D, "Bad index address %08x!", gstate_c.indexAddr);
|
||||
ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr);
|
||||
break;
|
||||
}
|
||||
inds = Memory::GetPointer(gstate_c.indexAddr);
|
||||
}
|
||||
|
||||
#ifndef USING_GLES2
|
||||
if (prim > GE_PRIM_RECTANGLES) {
|
||||
ERROR_LOG_REPORT_ONCE(reportPrim, G3D, "Unexpected prim type: %d", prim);
|
||||
}
|
||||
#endif
|
||||
|
||||
int bytesRead;
|
||||
transformDraw_.SubmitPrim(verts, inds, prim, count, gstate.vertType, -1, &bytesRead);
|
||||
|
||||
|
@ -714,14 +720,14 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
|
|||
void *indices = NULL;
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {
|
||||
if (!Memory::IsValidAddress(gstate_c.indexAddr)) {
|
||||
ERROR_LOG(G3D, "Bad index address %08x!", gstate_c.indexAddr);
|
||||
ERROR_LOG_REPORT(G3D, "Bad index address %08x!", gstate_c.indexAddr);
|
||||
break;
|
||||
}
|
||||
indices = Memory::GetPointer(gstate_c.indexAddr);
|
||||
}
|
||||
|
||||
if (gstate.getPatchPrimitiveType() != GE_PATCHPRIM_TRIANGLES) {
|
||||
ERROR_LOG(G3D, "Unsupported patch primitive %x", gstate.patchprimitive&3);
|
||||
ERROR_LOG_REPORT(G3D, "Unsupported patch primitive %x", gstate.getPatchPrimitiveType());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -729,7 +735,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
|
|||
int sp_vcount = (data >> 8) & 0xFF;
|
||||
int sp_utype = (data >> 16) & 0x3;
|
||||
int sp_vtype = (data >> 18) & 0x3;
|
||||
int patchPrim = gstate.patchprimitive & 3;
|
||||
GEPatchPrimType patchPrim = gstate.getPatchPrimitiveType();
|
||||
transformDraw_.SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, patchPrim, gstate.vertType);
|
||||
}
|
||||
break;
|
||||
|
@ -1300,22 +1306,22 @@ void GLES_GPU::DoBlockTransfer() {
|
|||
//
|
||||
// etc....
|
||||
|
||||
u32 srcBasePtr = (gstate.transfersrc & 0xFFFFF0) | ((gstate.transfersrcw & 0xFF0000) << 8);
|
||||
u32 srcStride = gstate.transfersrcw & 0x3F8;
|
||||
u32 srcBasePtr = gstate.getTransferSrcAddress();
|
||||
u32 srcStride = gstate.getTransferSrcStride();
|
||||
|
||||
u32 dstBasePtr = (gstate.transferdst & 0xFFFFF0) | ((gstate.transferdstw & 0xFF0000) << 8);
|
||||
u32 dstStride = gstate.transferdstw & 0x3F8;
|
||||
u32 dstBasePtr = gstate.getTransferDstAddress();
|
||||
u32 dstStride = gstate.getTransferDstStride();
|
||||
|
||||
int srcX = gstate.transfersrcpos & 0x3FF;
|
||||
int srcY = (gstate.transfersrcpos >> 10) & 0x3FF;
|
||||
int srcX = gstate.getTransferSrcX();
|
||||
int srcY = gstate.getTransferSrcY();
|
||||
|
||||
int dstX = gstate.transferdstpos & 0x3FF;
|
||||
int dstY = (gstate.transferdstpos >> 10) & 0x3FF;
|
||||
int dstX = gstate.getTransferDstX();
|
||||
int dstY = gstate.getTransferDstY();
|
||||
|
||||
int width = (gstate.transfersize & 0x3FF) + 1;
|
||||
int height = ((gstate.transfersize >> 10) & 0x3FF) + 1;
|
||||
int width = gstate.getTransferWidth();
|
||||
int height = gstate.getTransferHeight();
|
||||
|
||||
int bpp = (gstate.transferstart & 1) ? 4 : 2;
|
||||
int bpp = gstate.getTransferBpp();
|
||||
|
||||
DEBUG_LOG(G3D, "Block transfer: %08x/%x -> %08x/%x, %ix%ix%i (%i,%i)->(%i,%i)", srcBasePtr, srcStride, dstBasePtr, dstStride, width, height, bpp, srcX, srcY, dstX, dstY);
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ LinkedShader::LinkedShader(Shader *vs, Shader *fs, bool useHWTransform)
|
|||
u_view = glGetUniformLocation(program, "u_view");
|
||||
u_world = glGetUniformLocation(program, "u_world");
|
||||
u_texmtx = glGetUniformLocation(program, "u_texmtx");
|
||||
if (gstate.getWeightMask() != 0)
|
||||
if (gstate.getWeightMask() != GE_VTYPE_WEIGHT_NONE)
|
||||
numBones = TranslateNumBones(gstate.getNumBoneWeights());
|
||||
else
|
||||
numBones = 0;
|
||||
|
@ -338,7 +338,7 @@ void LinkedShader::updateUniforms() {
|
|||
// Not sure what GE_TEXMAP_UNKNOWN is, but seen in Riviera. Treating the same as GE_TEXMAP_TEXTURE_COORDS works.
|
||||
if (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_COORDS || gstate.getUVGenMode() == GE_TEXMAP_UNKNOWN) {
|
||||
static const float rescale[4] = {1.0f, 2*127.5f/128.f, 2*32767.5f/32768.f, 1.0f};
|
||||
float factor = rescale[(gstate.vertType & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT];
|
||||
float factor = rescale[gstate.getTexCoordMask() >> GE_VTYPE_TC_SHIFT];
|
||||
uvscaleoff[0] = gstate_c.uv.uScale * factor * widthFactor;
|
||||
uvscaleoff[1] = gstate_c.uv.vScale * factor * heightFactor;
|
||||
uvscaleoff[2] = gstate_c.uv.uOff * widthFactor;
|
||||
|
|
|
@ -57,7 +57,7 @@ void TransformDrawEngine::DrawBezier(int ucount, int vcount) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!(gstate.vertType & GE_VTYPE_TC_MASK)) {
|
||||
if (!gstate.getTexCoordMask()) {
|
||||
VertexDecoder *dec = GetVertexDecoder(gstate.vertType);
|
||||
dec->SetVertexType(gstate.vertType);
|
||||
u32 newVertType = dec->InjectUVs(decoded2, Memory::GetPointer(gstate_c.vertexAddr), customUV, 16);
|
||||
|
@ -92,7 +92,7 @@ void CopyTriangle(u8 *&dest, u8 *v1, u8 *v2, u8 * v3, int vertexSize) {
|
|||
dest += vertexSize;
|
||||
}
|
||||
|
||||
void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type)
|
||||
void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type)
|
||||
{
|
||||
Flush();
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
|
|||
renderHeightFactor = renderHeight / 272.0f;
|
||||
}
|
||||
|
||||
bool throughmode = (gstate.vertType & GE_VTYPE_THROUGH_MASK) != 0;
|
||||
bool throughmode = gstate.isModeThrough();
|
||||
|
||||
// Scissor
|
||||
int scissorX1 = gstate.getScissorX1();
|
||||
|
|
|
@ -254,13 +254,6 @@ void TextureCache::NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffe
|
|||
}
|
||||
}
|
||||
|
||||
static u32 GetClutIndex(u32 index) {
|
||||
const u32 clutBase = gstate.getClutIndexStartPos();
|
||||
const u32 clutMask = gstate.getClutIndexMask();
|
||||
const u8 clutShift = gstate.getClutIndexShift();
|
||||
return ((index >> clutShift) & clutMask) | clutBase;
|
||||
}
|
||||
|
||||
void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u32 level) {
|
||||
const u32 rowWidth = (bytesPerPixel > 0) ? (bufw * bytesPerPixel) : (bufw / 2);
|
||||
const u32 pitch = rowWidth / 4;
|
||||
|
@ -346,7 +339,7 @@ inline void DeIndexTexture(ClutT *dest, const IndexT *indexed, int length, const
|
|||
}
|
||||
} else {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
*dest++ = clut[GetClutIndex(*indexed++)];
|
||||
*dest++ = clut[gstate.transformClutIndex(*indexed++)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -371,8 +364,8 @@ inline void DeIndexTexture4(ClutT *dest, const u8 *indexed, int length, const Cl
|
|||
} else {
|
||||
for (int i = 0; i < length; i += 2) {
|
||||
u8 index = *indexed++;
|
||||
dest[i + 0] = clut[GetClutIndex((index >> 0) & 0xf)];
|
||||
dest[i + 1] = clut[GetClutIndex((index >> 4) & 0xf)];
|
||||
dest[i + 0] = clut[gstate.transformClutIndex((index >> 0) & 0xf)];
|
||||
dest[i + 1] = clut[gstate.transformClutIndex((index >> 4) & 0xf)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -424,7 +417,7 @@ void *TextureCache::readIndexedTex(int level, u32 texaddr, int bytesPerIndex, GL
|
|||
tmpTexBuf16.resize(std::max(bufw, w) * h);
|
||||
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
|
||||
const u16 *clut = GetCurrentClut<u16>();
|
||||
if (!(gstate.texmode & 1)) {
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
switch (bytesPerIndex) {
|
||||
case 1:
|
||||
DeIndexTexture<u8>(tmpTexBuf16.data(), texaddr, length, clut);
|
||||
|
@ -464,7 +457,7 @@ void *TextureCache::readIndexedTex(int level, u32 texaddr, int bytesPerIndex, GL
|
|||
tmpTexBuf32.resize(std::max(bufw, w) * h);
|
||||
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
|
||||
const u32 *clut = GetCurrentClut<u32>();
|
||||
if (!(gstate.texmode & 1)) {
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
switch (bytesPerIndex) {
|
||||
case 1:
|
||||
DeIndexTexture<u8>(tmpTexBuf32.data(), texaddr, length, clut);
|
||||
|
@ -550,8 +543,8 @@ static const GLuint MagFiltGL[2] = {
|
|||
void TextureCache::UpdateSamplingParams(TexCacheEntry &entry, bool force) {
|
||||
int minFilt = gstate.texfilter & 0x7;
|
||||
int magFilt = (gstate.texfilter>>8) & 1;
|
||||
bool sClamp = gstate.texwrap & 1;
|
||||
bool tClamp = (gstate.texwrap>>8) & 1;
|
||||
bool sClamp = gstate.isTexCoordClampedS();
|
||||
bool tClamp = gstate.isTexCoordClampedT();
|
||||
|
||||
bool noMip = (gstate.texlevel & 0xFFFFFF) == 0x000001 || (gstate.texlevel & 0xFFFFFF) == 0x100001 ; // Fix texlevel at 0
|
||||
|
||||
|
@ -873,8 +866,8 @@ inline bool TextureCache::TexCacheEntry::Matches(u16 dim2, u8 format2, int maxLe
|
|||
}
|
||||
|
||||
void TextureCache::LoadClut() {
|
||||
u32 clutAddr = ((gstate.clutaddr & 0xFFFFFF) | ((gstate.clutaddrupper << 8) & 0x0F000000));
|
||||
clutTotalBytes_ = (gstate.loadclut & 0x3f) * 32;
|
||||
u32 clutAddr = gstate.getClutAddress();
|
||||
clutTotalBytes_ = gstate.getClutLoadBytes();
|
||||
if (Memory::IsValidAddress(clutAddr)) {
|
||||
Memory::MemcpyUnchecked(clutBufRaw_, clutAddr, clutTotalBytes_);
|
||||
} else {
|
||||
|
@ -1285,7 +1278,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
|
|||
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
|
||||
const u16 *clut = GetCurrentClut<u16>() + clutSharingOffset;
|
||||
texByteAlign = 2;
|
||||
if (!(gstate.texmode & 1)) {
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
if (clutAlphaLinear_ && mipmapShareClut) {
|
||||
DeIndexTexture4Optimal(tmpTexBuf16.data(), texaddr, bufw * h, clutAlphaLinearColor_);
|
||||
} else {
|
||||
|
@ -1309,7 +1302,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
|
|||
tmpTexBuf32.resize(std::max(bufw, w) * h);
|
||||
tmpTexBufRearrange.resize(std::max(bufw, w) * h);
|
||||
const u32 *clut = GetCurrentClut<u32>() + clutSharingOffset;
|
||||
if (!(gstate.texmode & 1)) {
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
DeIndexTexture4(tmpTexBuf32.data(), texaddr, bufw * h, clut);
|
||||
finalBuf = tmpTexBuf32.data();
|
||||
} else {
|
||||
|
@ -1366,7 +1359,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
|
|||
dstFmt = GL_UNSIGNED_SHORT_5_6_5;
|
||||
texByteAlign = 2;
|
||||
|
||||
if (!(gstate.texmode & 1)) {
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
int len = std::max(bufw, w) * h;
|
||||
tmpTexBuf16.resize(len);
|
||||
tmpTexBufRearrange.resize(len);
|
||||
|
@ -1383,7 +1376,7 @@ void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat c
|
|||
if (bufw < 4)
|
||||
bufw = 4;
|
||||
dstFmt = GL_UNSIGNED_BYTE;
|
||||
if (!(gstate.texmode & 1)) {
|
||||
if (!gstate.isTextureSwizzled()) {
|
||||
// Special case: if we don't need to deal with packing, we don't need to copy.
|
||||
if (w == bufw) {
|
||||
finalBuf = Memory::GetPointer(texaddr);
|
||||
|
|
|
@ -150,7 +150,7 @@ private:
|
|||
};
|
||||
|
||||
Lighter::Lighter() {
|
||||
doShadeMapping_ = (gstate.texmapmode & 0x3) == 2;
|
||||
doShadeMapping_ = gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP;
|
||||
materialEmissive.GetFromRGB(gstate.materialemissive);
|
||||
materialEmissive.a = 0.0f;
|
||||
globalAmbient.GetFromRGB(gstate.ambientcolor);
|
||||
|
@ -677,16 +677,17 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
|
|||
((clearColor & 0xFF0000) >> 16) / 255.0f,
|
||||
((clearColor & 0xFF000000) >> 24) / 255.0f,
|
||||
};
|
||||
int target = 0;
|
||||
if ((gstate.clearmode >> 8) & 3) target |= GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
||||
if ((gstate.clearmode >> 10) & 1) target |= GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
bool colorMask = (gstate.clearmode >> 8) & 1;
|
||||
bool alphaMask = (gstate.clearmode >> 9) & 1;
|
||||
bool colorMask = gstate.isClearModeColorMask();
|
||||
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||
glstate.colorMask.set(colorMask, colorMask, colorMask, alphaMask);
|
||||
glstate.stencilTest.set(false);
|
||||
glstate.scissorTest.set(false);
|
||||
bool depthMask = (gstate.clearmode >> 10) & 1;
|
||||
bool depthMask = gstate.isClearModeDepthMask();
|
||||
|
||||
int target = 0;
|
||||
if (colorMask || alphaMask) target |= GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
|
||||
if (depthMask) target |= GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
glClearColor(col[0], col[1], col[2], col[3]);
|
||||
#ifdef USING_GLES2
|
||||
|
|
|
@ -98,7 +98,7 @@ public:
|
|||
virtual ~TransformDrawEngine();
|
||||
void SubmitPrim(void *verts, void *inds, int prim, int vertexCount, u32 vertexType, int forceIndexType, int *bytesRead);
|
||||
void DrawBezier(int ucount, int vcount);
|
||||
void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type);
|
||||
void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type);
|
||||
|
||||
void DecodeVerts();
|
||||
void SetShaderManager(ShaderManager *shaderManager) {
|
||||
|
|
|
@ -336,7 +336,7 @@ void VertexDecoder::Step_NormalS8() const
|
|||
{
|
||||
s8 *normal = (s8 *)(decoded_ + decFmt.nrmoff);
|
||||
u8 xorval = 0;
|
||||
if (gstate.reversenormals & 1)
|
||||
if (gstate.areNormalsReversed())
|
||||
xorval = 0xFF; // Using xor instead of - to handle -128
|
||||
const s8 *sv = (const s8*)(ptr_ + nrmoff);
|
||||
for (int j = 0; j < 3; j++)
|
||||
|
@ -348,7 +348,7 @@ void VertexDecoder::Step_NormalS16() const
|
|||
{
|
||||
s16 *normal = (s16 *)(decoded_ + decFmt.nrmoff);
|
||||
u16 xorval = 0;
|
||||
if (gstate.reversenormals & 1)
|
||||
if (gstate.areNormalsReversed())
|
||||
xorval = 0xFFFF;
|
||||
const s16 *sv = (const s16*)(ptr_ + nrmoff);
|
||||
for (int j = 0; j < 3; j++)
|
||||
|
@ -360,7 +360,7 @@ void VertexDecoder::Step_NormalFloat() const
|
|||
{
|
||||
float *normal = (float *)(decoded_ + decFmt.nrmoff);
|
||||
float multiplier = 1.0f;
|
||||
if (gstate.reversenormals & 1)
|
||||
if (gstate.areNormalsReversed())
|
||||
multiplier = -multiplier;
|
||||
const float *fv = (const float*)(ptr_ + nrmoff);
|
||||
for (int j = 0; j < 3; j++)
|
||||
|
@ -374,7 +374,7 @@ void VertexDecoder::Step_NormalS8Morph() const
|
|||
for (int n = 0; n < morphcount; n++)
|
||||
{
|
||||
float multiplier = gstate_c.morphWeights[n];
|
||||
if (gstate.reversenormals & 1) {
|
||||
if (gstate.areNormalsReversed()) {
|
||||
multiplier = -multiplier;
|
||||
}
|
||||
const s8 *bv = (const s8*)(ptr_ + onesize_*n + nrmoff);
|
||||
|
@ -391,7 +391,7 @@ void VertexDecoder::Step_NormalS16Morph() const
|
|||
for (int n = 0; n < morphcount; n++)
|
||||
{
|
||||
float multiplier = gstate_c.morphWeights[n];
|
||||
if (gstate.reversenormals & 1) {
|
||||
if (gstate.areNormalsReversed()) {
|
||||
multiplier = -multiplier;
|
||||
}
|
||||
const s16 *sv = (const s16 *)(ptr_ + onesize_*n + nrmoff);
|
||||
|
@ -408,7 +408,7 @@ void VertexDecoder::Step_NormalFloatMorph() const
|
|||
for (int n = 0; n < morphcount; n++)
|
||||
{
|
||||
float multiplier = gstate_c.morphWeights[n];
|
||||
if (gstate.reversenormals & 1) {
|
||||
if (gstate.areNormalsReversed()) {
|
||||
multiplier = -multiplier;
|
||||
}
|
||||
const float *fv = (const float*)(ptr_ + onesize_*n + nrmoff);
|
||||
|
|
|
@ -60,7 +60,7 @@ void ComputeVertexShaderID(VertexShaderID *id, int prim, bool useHWTransform) {
|
|||
|
||||
bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
|
||||
bool hasNormal = (vertType & GE_VTYPE_NRM_MASK) != 0;
|
||||
bool hasBones = gstate.getWeightMask() != 0;
|
||||
bool hasBones = gstate.getWeightMask() != GE_VTYPE_WEIGHT_NONE;
|
||||
bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear();
|
||||
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled();
|
||||
|
||||
|
|
|
@ -566,7 +566,7 @@ void GPUCommon::ProcessEvent(GPUEvent ev) {
|
|||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(G3D, "Unexpected GPU event type: %d", (int)ev);
|
||||
ERROR_LOG_REPORT(G3D, "Unexpected GPU event type: %d", (int)ev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -225,6 +225,7 @@ struct GPUgstate
|
|||
bool isClearModeDepthWriteEnabled() const { return (clearmode&0x400) != 0; }
|
||||
bool isClearModeColorMask() const { return (clearmode&0x100) != 0; }
|
||||
bool isClearModeAlphaMask() const { return (clearmode&0x200) != 0; }
|
||||
bool isClearModeDepthMask() const { return (clearmode&0x400) != 0; }
|
||||
u32 getClearModeColorMask() const { return ((clearmode&0x100) ? 0xFFFFFF : 0) | ((clearmode&0x200) ? 0xFF000000 : 0); } // TODO: Different convention than getColorMask, confusing!
|
||||
|
||||
// Blend
|
||||
|
@ -283,11 +284,15 @@ struct GPUgstate
|
|||
int getTextureEnvColR() const { return texenvcolor&0xFF; }
|
||||
int getTextureEnvColG() const { return (texenvcolor>>8)&0xFF; }
|
||||
int getTextureEnvColB() const { return (texenvcolor>>16)&0xFF; }
|
||||
u32 getClutAddress() const { return (clutaddr & 0x00FFFFFF) | ((clutaddrupper << 8) & 0x0F000000); }
|
||||
int getClutLoadBytes() const { return (loadclut & 0x3F) * 32; }
|
||||
GEPaletteFormat getClutPaletteFormat() { return static_cast<GEPaletteFormat>(clutformat & 3); }
|
||||
int getClutIndexShift() const { return (clutformat >> 2) & 0x1F; }
|
||||
int getClutIndexMask() const { return (clutformat >> 8) & 0xFF; }
|
||||
int getClutIndexStartPos() const { return ((clutformat >> 16) & 0x1F) << 4; }
|
||||
int transformClutIndex(int index) const { return ((index >> getClutIndexShift()) & getClutIndexMask()) | getClutIndexStartPos(); }
|
||||
bool isClutIndexSimple() const { return (clutformat & ~3) == 0xC500FF00; } // Meaning, no special mask, shift, or start pos.
|
||||
bool isTextureSwizzled() const { return texmode & 1; }
|
||||
|
||||
// Lighting
|
||||
bool isLightingEnabled() const { return lightingEnable & 1; }
|
||||
|
@ -352,9 +357,24 @@ struct GPUgstate
|
|||
int getWeightMask() const { return vertType & GE_VTYPE_WEIGHT_MASK; }
|
||||
int getNumBoneWeights() const { return 1 + ((vertType & GE_VTYPE_WEIGHTCOUNT_MASK) >> GE_VTYPE_WEIGHTCOUNT_SHIFT); }
|
||||
bool isSkinningEnabled() const { return ((vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE); }
|
||||
int getTexCoordMask() const { return vertType & GE_VTYPE_TC_MASK; }
|
||||
bool areNormalsReversed() const { return reversenormals & 1; }
|
||||
|
||||
GEPatchPrimType getPatchPrimitiveType() const { return static_cast<GEPatchPrimType>(patchprimitive & 3); }
|
||||
|
||||
// Transfers
|
||||
u32 getTransferSrcAddress() const { return (transfersrc & 0xFFFFF0) | ((transfersrcw & 0xFF0000) << 8); }
|
||||
u32 getTransferSrcStride() const { return transfersrcw & 0x3F8; }
|
||||
int getTransferSrcX() const { return (transfersrcpos >> 0) & 0x3FF; }
|
||||
int getTransferSrcY() const { return (transfersrcpos >> 10) & 0x3FF; }
|
||||
u32 getTransferDstAddress() const { return (transferdst & 0xFFFFF0) | ((transferdstw & 0xFF0000) << 8); }
|
||||
u32 getTransferDstStride() const { return transferdstw & 0x3F8; }
|
||||
int getTransferDstX() const { return (transferdstpos >> 0) & 0x3FF; }
|
||||
int getTransferDstY() const { return (transferdstpos >> 10) & 0x3FF; }
|
||||
int getTransferWidth() const { return ((transfersize >> 0) & 0x3FF) + 1; }
|
||||
int getTransferHeight() const { return ((transfersize >> 10) & 0x3FF) + 1; }
|
||||
int getTransferBpp() const { return (transferstart & 1) ? 4 : 2; }
|
||||
|
||||
// Real data in the context ends here
|
||||
};
|
||||
|
||||
|
|
|
@ -437,7 +437,10 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) {
|
|||
|
||||
case GE_CMD_TRANSFERSRC:
|
||||
{
|
||||
sprintf(buffer, "Block transfer src: %06x", data);
|
||||
if (data & 0xF)
|
||||
sprintf(buffer, "Block transfer src: %06x (extra: %x)", data & ~0xF, data & 0xF);
|
||||
else
|
||||
sprintf(buffer, "Block transfer src: %06x", data);
|
||||
// Nothing to do, the next one prints
|
||||
}
|
||||
break;
|
||||
|
@ -445,7 +448,7 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) {
|
|||
case GE_CMD_TRANSFERSRCW:
|
||||
{
|
||||
u32 xferSrc = (gstate.transfersrc & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
|
||||
u32 xferSrcW = gstate.transfersrcw & 1023;
|
||||
u32 xferSrcW = data & 0x3FF;
|
||||
if (data & ~0xFF03FF)
|
||||
sprintf(buffer, "Block transfer src: %08x W: %i (extra %x)", xferSrc, xferSrcW, data);
|
||||
else
|
||||
|
@ -456,14 +459,17 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) {
|
|||
case GE_CMD_TRANSFERDST:
|
||||
{
|
||||
// Nothing to do, the next one prints
|
||||
sprintf(buffer, "Block transfer dst: %06x", data);
|
||||
if (data & 0xF)
|
||||
sprintf(buffer, "Block transfer dst: %06x (extra: %x)", data & ~0xF, data & 0xF);
|
||||
else
|
||||
sprintf(buffer, "Block transfer dst: %06x", data);
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_CMD_TRANSFERDSTW:
|
||||
{
|
||||
u32 xferDst = (gstate.transferdst & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
|
||||
u32 xferDstW = gstate.transferdstw & 1023;
|
||||
u32 xferDstW = data & 0x3FF;
|
||||
if (data & ~0xFF03FF)
|
||||
sprintf(buffer, "Block transfer dest: %08x W: %i (extra %x)", xferDst, xferDstW, data);
|
||||
else
|
||||
|
@ -505,10 +511,10 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) {
|
|||
}
|
||||
|
||||
case GE_CMD_TRANSFERSTART: // Orphis calls this TRXKICK
|
||||
if (data)
|
||||
sprintf(buffer, "Block transfer start: %x", data);
|
||||
if (data & ~1)
|
||||
sprintf(buffer, "Block transfer start: %d (extra %x)", data & 1, data & ~1);
|
||||
else
|
||||
sprintf(buffer, "Block transfer start");
|
||||
sprintf(buffer, "Block transfer start: %d", data);
|
||||
break;
|
||||
|
||||
case GE_CMD_TEXSIZE0:
|
||||
|
|
|
@ -265,7 +265,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
|||
case GE_CMD_LOADCLUT:
|
||||
// This could be used to "dirty" textures with clut.
|
||||
{
|
||||
u32 clutAddr = ((gstate.clutaddrupper & 0xFF0000)<<8) | (gstate.clutaddr & 0xFFFFFF);
|
||||
u32 clutAddr = gstate.getClutAddress();
|
||||
if (clutAddr)
|
||||
{
|
||||
DEBUG_LOG(G3D,"DL Clut load: %08x", clutAddr);
|
||||
|
@ -282,8 +282,8 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
|||
|
||||
case GE_CMD_TRANSFERSRCW:
|
||||
{
|
||||
u32 xferSrc = gstate.transfersrc | ((data&0xFF0000)<<8);
|
||||
u32 xferSrcW = gstate.transfersrcw & 1023;
|
||||
u32 xferSrc = (gstate.transfersrc & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
|
||||
u32 xferSrcW = data & 0x3FF;
|
||||
DEBUG_LOG(G3D,"Block Transfer Src: %08x W: %i", xferSrc, xferSrcW);
|
||||
break;
|
||||
}
|
||||
|
@ -291,8 +291,8 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
|||
|
||||
case GE_CMD_TRANSFERDSTW:
|
||||
{
|
||||
u32 xferDst= gstate.transferdst | ((data&0xFF0000)<<8);
|
||||
u32 xferDstW = gstate.transferdstw & 1023;
|
||||
u32 xferDst = (gstate.transferdst & 0x00FFFFFF) | ((data & 0xFF0000) << 8);
|
||||
u32 xferDstW = data & 0x3FF;
|
||||
DEBUG_LOG(G3D,"Block Transfer Dest: %08x W: %i", xferDst, xferDstW);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ static inline int orient2dIncY(int dX01)
|
|||
|
||||
static inline int GetPixelDataOffset(unsigned int texel_size_bits, unsigned int row_pitch_bits, unsigned int u, unsigned int v)
|
||||
{
|
||||
if (!(gstate.texmode & 1))
|
||||
if (!gstate.isTextureSwizzled())
|
||||
return v * row_pitch_bits *texel_size_bits/8 / 8 + u * texel_size_bits / 8;
|
||||
|
||||
int tile_size_bits = 32;
|
||||
|
@ -90,13 +90,6 @@ static inline u32 LookupColor(unsigned int index, unsigned int level)
|
|||
}
|
||||
}
|
||||
|
||||
static inline u32 GetClutIndex(u32 index) {
|
||||
const u32 clutBase = gstate.getClutIndexStartPos();
|
||||
const u32 clutMask = gstate.getClutIndexMask();
|
||||
const u8 clutShift = gstate.getClutIndexShift();
|
||||
return ((index >> clutShift) & clutMask) | clutBase;
|
||||
}
|
||||
|
||||
static inline void GetTexelCoordinates(int level, float s, float t, unsigned int& u, unsigned int& v)
|
||||
{
|
||||
s *= getFloat24(gstate.texscaleu);
|
||||
|
@ -185,25 +178,25 @@ static inline u32 SampleNearest(int level, unsigned int u, unsigned int v)
|
|||
|
||||
u32 val = srcptr[0] + (srcptr[1] << 8) + (srcptr[2] << 16) + (srcptr[3] << 24);
|
||||
|
||||
return LookupColor(GetClutIndex(val), level);
|
||||
return LookupColor(gstate.transformClutIndex(val), level);
|
||||
} else if (texfmt == GE_TFMT_CLUT16) {
|
||||
srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
|
||||
|
||||
u16 val = srcptr[0] + (srcptr[1] << 8);
|
||||
|
||||
return LookupColor(GetClutIndex(val), level);
|
||||
return LookupColor(gstate.transformClutIndex(val), level);
|
||||
} else if (texfmt == GE_TFMT_CLUT8) {
|
||||
srcptr += GetPixelDataOffset(8, texbufwidth*8, u, v);
|
||||
|
||||
u8 val = *srcptr;
|
||||
|
||||
return LookupColor(GetClutIndex(val), level);
|
||||
return LookupColor(gstate.transformClutIndex(val), level);
|
||||
} else if (texfmt == GE_TFMT_CLUT4) {
|
||||
srcptr += GetPixelDataOffset(4, texbufwidth*8, u, v);
|
||||
|
||||
u8 val = (u & 1) ? (srcptr[0] >> 4) : (srcptr[0] & 0xF);
|
||||
|
||||
return LookupColor(GetClutIndex(val), level);
|
||||
return LookupColor(gstate.transformClutIndex(val), level);
|
||||
} else {
|
||||
ERROR_LOG(G3D, "Unsupported texture format: %x", texfmt);
|
||||
return 0;
|
||||
|
@ -404,7 +397,7 @@ static inline Vec4<int> GetTextureFunctionOutput(const Vec3<int>& prim_color_rgb
|
|||
Vec3<int> out_rgb;
|
||||
int out_a;
|
||||
|
||||
bool rgba = (gstate.texfunc & 0x100) != 0;
|
||||
bool rgba = gstate.isTextureAlphaUsed();
|
||||
|
||||
switch (gstate.getTextureFunction()) {
|
||||
case GE_TEXFUNC_MODULATE:
|
||||
|
@ -452,10 +445,10 @@ static inline Vec4<int> GetTextureFunctionOutput(const Vec3<int>& prim_color_rgb
|
|||
|
||||
static inline bool ColorTestPassed(Vec3<int> color)
|
||||
{
|
||||
u32 mask = gstate.colormask&0xFFFFFF;
|
||||
color = Vec3<int>::FromRGB(color.ToRGB() & mask);
|
||||
Vec3<int> ref = Vec3<int>::FromRGB(gstate.colorref & mask);
|
||||
switch (gstate.colortest & 0x3) {
|
||||
const u32 mask = gstate.getColorTestMask();
|
||||
const u32 c = color.ToRGB() & mask;
|
||||
const u32 ref = gstate.getColorTestRef() & mask;
|
||||
switch (gstate.getColorTestFunction()) {
|
||||
case GE_COMP_NEVER:
|
||||
return false;
|
||||
|
||||
|
@ -463,21 +456,21 @@ static inline bool ColorTestPassed(Vec3<int> color)
|
|||
return true;
|
||||
|
||||
case GE_COMP_EQUAL:
|
||||
return (color.r() == ref.r() && color.g() == ref.g() && color.b() == ref.b());
|
||||
return c == ref;
|
||||
|
||||
case GE_COMP_NOTEQUAL:
|
||||
return (color.r() != ref.r() || color.g() != ref.g() || color.b() != ref.b());
|
||||
return c != ref;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool AlphaTestPassed(int alpha)
|
||||
{
|
||||
u8 mask = (gstate.alphatest >> 16) & 0xFF;
|
||||
u8 ref = (gstate.alphatest >> 8) & mask;
|
||||
const u8 mask = gstate.getAlphaTestMask() & 0xFF;
|
||||
const u8 ref = gstate.getAlphaTestRef() & mask;
|
||||
alpha &= mask;
|
||||
|
||||
switch (gstate.alphatest & 0x7) {
|
||||
switch (gstate.getAlphaTestFunction()) {
|
||||
case GE_COMP_NEVER:
|
||||
return false;
|
||||
|
||||
|
@ -726,7 +719,7 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData&
|
|||
// TODO: Fogging
|
||||
|
||||
// TODO: Is that the correct way to interpolate?
|
||||
// With the (u32), this causes an ICE in some versions of gcc.
|
||||
// Without the (u32), this causes an ICE in some versions of gcc.
|
||||
u16 z = (u16)(u32)(((float)v0.screenpos.z * w0 + (float)v1.screenpos.z * w1 + (float)v2.screenpos.z * w2) / (w0+w1+w2));
|
||||
|
||||
// Depth range test
|
||||
|
|
|
@ -363,7 +363,7 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
|||
break;
|
||||
}
|
||||
|
||||
TransformUnit::SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, gstate.patchprimitive&3, gstate.vertType);
|
||||
TransformUnit::SubmitSpline(control_points, indices, sp_ucount, sp_vcount, sp_utype, sp_vtype, gstate.getPatchPrimitiveType(), gstate.vertType);
|
||||
DEBUG_LOG(G3D,"DL DRAW SPLINE: %i x %i, %i x %i", sp_ucount, sp_vcount, sp_utype, sp_vtype);
|
||||
}
|
||||
break;
|
||||
|
@ -528,14 +528,14 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
|||
|
||||
case GE_CMD_LOADCLUT:
|
||||
{
|
||||
u32 clutAddr = ((gstate.clutaddr & 0xFFFFF0) | ((gstate.clutaddrupper << 8) & 0xFF000000));
|
||||
u32 clutTotalBytes_ = (gstate.loadclut & 0x3f) * 32;
|
||||
u32 clutAddr = gstate.getClutAddress();
|
||||
u32 clutTotalBytes = gstate.getClutLoadBytes();
|
||||
|
||||
if (Memory::IsValidAddress(clutAddr)) {
|
||||
Memory::Memcpy(clut, clutAddr, clutTotalBytes_);
|
||||
Memory::MemcpyUnchecked(clut, clutAddr, clutTotalBytes);
|
||||
} else {
|
||||
// TODO: Does this make any sense?
|
||||
memset(clut, 0xFF, clutTotalBytes_);
|
||||
memset(clut, 0xFF, clutTotalBytes);
|
||||
}
|
||||
|
||||
if (clutAddr)
|
||||
|
@ -549,67 +549,36 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
|||
}
|
||||
break;
|
||||
|
||||
//case GE_CMD_TRANSFERSRC:
|
||||
|
||||
// Don't need to do anything, just state for transferstart.
|
||||
case GE_CMD_TRANSFERSRC:
|
||||
case GE_CMD_TRANSFERSRCW:
|
||||
{
|
||||
u32 xferSrc = gstate.transfersrc | ((data&0xFF0000)<<8);
|
||||
u32 xferSrcW = gstate.transfersrcw & 1023;
|
||||
DEBUG_LOG(G3D,"Block Transfer Src: %08x W: %i", xferSrc, xferSrcW);
|
||||
break;
|
||||
}
|
||||
// case GE_CMD_TRANSFERDST:
|
||||
|
||||
case GE_CMD_TRANSFERDST:
|
||||
case GE_CMD_TRANSFERDSTW:
|
||||
{
|
||||
u32 xferDst= gstate.transferdst | ((data&0xFF0000)<<8);
|
||||
u32 xferDstW = gstate.transferdstw & 1023;
|
||||
DEBUG_LOG(G3D,"Block Transfer Dest: %08x W: %i", xferDst, xferDstW);
|
||||
break;
|
||||
}
|
||||
|
||||
case GE_CMD_TRANSFERSRCPOS:
|
||||
{
|
||||
u32 x = (data & 1023)+1;
|
||||
u32 y = ((data>>10) & 1023)+1;
|
||||
DEBUG_LOG(G3D, "DL Block Transfer Src Rect TL: %i, %i", x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
case GE_CMD_TRANSFERDSTPOS:
|
||||
{
|
||||
u32 x = (data & 1023)+1;
|
||||
u32 y = ((data>>10) & 1023)+1;
|
||||
DEBUG_LOG(G3D, "DL Block Transfer Dest Rect TL: %i, %i", x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
case GE_CMD_TRANSFERSIZE:
|
||||
{
|
||||
u32 w = (data & 1023)+1;
|
||||
u32 h = ((data>>10) & 1023)+1;
|
||||
DEBUG_LOG(G3D, "DL Block Transfer Rect Size: %i x %i", w, h);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_CMD_TRANSFERSTART:
|
||||
{
|
||||
u32 srcBasePtr = (gstate.transfersrc & 0xFFFFF0) | ((gstate.transfersrcw & 0xFF0000) << 8);
|
||||
u32 srcStride = gstate.transfersrcw & 0x3F8;
|
||||
u32 srcBasePtr = gstate.getTransferSrcAddress();
|
||||
u32 srcStride = gstate.getTransferSrcStride();
|
||||
|
||||
u32 dstBasePtr = (gstate.transferdst & 0xFFFFF0) | ((gstate.transferdstw & 0xFF0000) << 8);
|
||||
u32 dstStride = gstate.transferdstw & 0x3F8;
|
||||
u32 dstBasePtr = gstate.getTransferDstAddress();
|
||||
u32 dstStride = gstate.getTransferDstStride();
|
||||
|
||||
int srcX = gstate.transfersrcpos & 0x3FF;
|
||||
int srcY = (gstate.transfersrcpos >> 10) & 0x3FF;
|
||||
int srcX = gstate.getTransferSrcX();
|
||||
int srcY = gstate.getTransferSrcY();
|
||||
|
||||
int dstX = gstate.transferdstpos & 0x3FF;
|
||||
int dstY = (gstate.transferdstpos >> 10) & 0x3FF;
|
||||
int dstX = gstate.getTransferDstX();
|
||||
int dstY = gstate.getTransferDstY();
|
||||
|
||||
int width = (gstate.transfersize & 0x3FF) + 1;
|
||||
int height = ((gstate.transfersize >> 10) & 0x3FF) + 1;
|
||||
int width = gstate.getTransferWidth();
|
||||
int height = gstate.getTransferHeight();
|
||||
|
||||
int bpp = (gstate.transferstart & 1) ? 4 : 2;
|
||||
int bpp = gstate.getTransferBpp();
|
||||
|
||||
DEBUG_LOG(G3D, "Block transfer: %08x/%x -> %08x/%x, %ix%ix%i (%i,%i)->(%i,%i)", srcBasePtr, srcStride, dstBasePtr, dstStride, width, height, bpp, srcX, srcY, dstX, dstY);
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
const u8 *src = Memory::GetPointer(srcBasePtr + ((y + srcY) * srcStride + srcX) * bpp);
|
||||
|
@ -617,7 +586,6 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
|||
memcpy(dst, src, width * bpp);
|
||||
}
|
||||
|
||||
DEBUG_LOG(G3D, "DL Texture Transfer Start: PixFormat %i", data);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ static VertexData ReadVertex(VertexReader& vreader)
|
|||
float pos[3];
|
||||
vreader.ReadPos(pos);
|
||||
|
||||
if (!gstate.isModeClear() && gstate.textureMapEnable && vreader.hasUV()) {
|
||||
if (!gstate.isModeClear() && gstate.isTextureMapEnabled() && vreader.hasUV()) {
|
||||
float uv[2];
|
||||
vreader.ReadUV(uv);
|
||||
vertex.texturecoords = Vec2<float>(uv[0], uv[1]);
|
||||
|
@ -113,7 +113,7 @@ static VertexData ReadVertex(VertexReader& vreader)
|
|||
vreader.ReadNrm(normal);
|
||||
vertex.normal = Vec3<float>(normal[0], normal[1], normal[2]);
|
||||
|
||||
if (gstate.reversenormals & 1)
|
||||
if (gstate.areNormalsReversed())
|
||||
vertex.normal = -vertex.normal;
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ struct SplinePatch {
|
|||
int type;
|
||||
};
|
||||
|
||||
void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type)
|
||||
void TransformUnit::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type)
|
||||
{
|
||||
VertexDecoder vdecoder;
|
||||
vdecoder.SetVertexType(vertex_type);
|
||||
|
|
|
@ -115,6 +115,6 @@ public:
|
|||
static DrawingCoords ScreenToDrawing(const ScreenCoords& coords);
|
||||
static ScreenCoords DrawingToScreen(const DrawingCoords& coords);
|
||||
|
||||
static void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, u32 prim_type, u32 vertex_type);
|
||||
static void SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertex_type);
|
||||
static void SubmitPrimitive(void* vertices, void* indices, u32 prim_type, int vertex_count, u32 vertex_type);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue