Skip to content

Commit

Permalink
GPU: Allow usage of texturing in immediate verts.
Browse files Browse the repository at this point in the history
And respect the other flags that I can reproduce working in a test.
I can't seem to get the fog to work at all, or the shading mode, or the
secondary color.  Maybe depends on other flags or bits in other regs...
  • Loading branch information
unknownbrackets committed Sep 6, 2022
1 parent fce189f commit c2dbb9c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
34 changes: 33 additions & 1 deletion GPU/GPUCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2402,6 +2402,8 @@ void GPUCommon::Execute_ImmVertexAlphaPrim(u32 op, u32 diff) {
v.color1_32 = gstate.imm_scv & 0xFFFFFF;
if (prim != GE_PRIM_KEEP_PREVIOUS) {
immPrim_ = (GEPrimitiveType)prim;
// Flags seem to only be respected from the first prim.
immFlags_ = op & 0x00FFF800;
} else if (prim == GE_PRIM_KEEP_PREVIOUS && immPrim_ != GE_PRIM_INVALID) {
static constexpr int flushPrimCount[] = { 1, 2, 0, 3, 0, 0, 2, 0 };
// Instead of finding a proper point to flush, we just emit a full rectangle every time one
Expand Down Expand Up @@ -2448,12 +2450,42 @@ void GPUCommon::FlushImm() {
}
int vtype = GE_VTYPE_TC_FLOAT | GE_VTYPE_POS_FLOAT | GE_VTYPE_COL_8888 | GE_VTYPE_THROUGH;

static constexpr int GE_IMM_CULLENABLE = 0x00080000;
static constexpr int GE_IMM_CULLFACE = 0x00100000;
static constexpr int GE_IMM_TEXTURE = 0x00200000;
static constexpr int GE_IMM_DITHER = 0x00800000;

bool texturing = (immFlags_ & GE_IMM_TEXTURE) != 0;
bool prevTexturing = gstate.isTextureMapEnabled();
bool cullEnable = (immFlags_ & GE_IMM_CULLENABLE) != 0;
bool prevCullEnable = gstate.isCullEnabled();
int cullMode = (immFlags_ & GE_IMM_CULLFACE) != 0 ? 1 : 0;
bool prevDither = gstate.isDitherEnabled();
bool dither = (immFlags_ & GE_IMM_DITHER) != 0;
// Some notes say there's a flag to control this, but it seems to be flat regardless.
GEShadeMode prevShadeMode = gstate.getShadeMode();

if (texturing != prevTexturing || cullEnable != prevCullEnable || dither != prevDither || prevShadeMode != GE_SHADE_FLAT) {
DispatchFlush();
gstate.textureMapEnable = (GE_CMD_TEXTUREMAPENABLE << 24) | (int)texturing;
gstate.cullfaceEnable = (GE_CMD_CULLFACEENABLE << 24) | (int)cullEnable;
gstate.shademodel = (GE_CMD_SHADEMODE << 24) | GE_SHADE_FLAT;
gstate.ditherEnable = (GE_CMD_DITHERENABLE << 24) | (int)dither;
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_RASTER_STATE);
}

int bytesRead;
uint32_t vertTypeID = GetVertTypeID(vtype, 0);
drawEngineCommon_->DispatchSubmitImm(temp, nullptr, immPrim_, immCount_, vertTypeID, gstate.getCullMode(), &bytesRead);
drawEngineCommon_->DispatchSubmitImm(temp, nullptr, immPrim_, immCount_, vertTypeID, cullMode, &bytesRead);
// TOOD: In the future, make a special path for these.
// drawEngineCommon_->DispatchSubmitImm(immBuffer_, immCount_);
immCount_ = 0;

gstate.textureMapEnable = (GE_CMD_TEXTUREMAPENABLE << 24) | (int)prevTexturing;
gstate.cullfaceEnable = (GE_CMD_CULLFACEENABLE << 24) | (int)prevCullEnable;
gstate.shademodel = (GE_CMD_SHADEMODE << 24) | prevShadeMode;
gstate.ditherEnable = (GE_CMD_DITHERENABLE << 24) | (int)prevDither;
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE | DIRTY_RASTER_STATE);
}

void GPUCommon::ExecuteOp(u32 op, u32 diff) {
Expand Down
1 change: 1 addition & 0 deletions GPU/GPUCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ class GPUCommon : public GPUInterface, public GPUDebugInterface {
TransformedVertex immBuffer_[MAX_IMMBUFFER_SIZE];
int immCount_ = 0;
GEPrimitiveType immPrim_ = GE_PRIM_INVALID;
uint32_t immFlags_ = 0;

std::string reportingPrimaryInfo_;
std::string reportingFullInfo_;
Expand Down
4 changes: 3 additions & 1 deletion GPU/Software/TransformUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ void SoftwareDrawEngine::DispatchSubmitPrim(const void *verts, const void *inds,
}

void SoftwareDrawEngine::DispatchSubmitImm(const void *verts, const void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead) {
_assert_msg_(cullMode == gstate.getCullMode(), "Mixed cull mode not supported.");
int flipCull = cullMode != gstate.getCullMode() ? 1 : 0;
// TODO: For now, just setting all dirty.
transformUnit.SetDirty(SoftDirty(-1));
gstate.cullmode ^= flipCull;
transformUnit.SubmitPrimitive(verts, inds, prim, vertexCount, vertTypeID, bytesRead, this);
gstate.cullmode ^= flipCull;
// TODO: Should really clear, but the vertex type is faked so things might need resetting...
transformUnit.SetDirty(SoftDirty(-1));
}
Expand Down

0 comments on commit c2dbb9c

Please sign in to comment.