| 150 | } |
| 151 | |
| 152 | void GSState::Reset(bool hardware_reset) |
| 153 | { |
| 154 | Flush(GSFlushReason::RESET); |
| 155 | |
| 156 | // FIXME: bios logo not shown cut in half after reset, missing graphics in GoW after first FMV |
| 157 | memset(&m_path, 0, sizeof(m_path)); |
| 158 | memset(&m_v, 0, sizeof(m_v)); |
| 159 | |
| 160 | m_env.Reset(); |
| 161 | m_mem.m_clut.Reset(); |
| 162 | |
| 163 | PRIM = &m_env.PRIM; |
| 164 | |
| 165 | UpdateContext(); |
| 166 | |
| 167 | UpdateVertexKick(); |
| 168 | |
| 169 | for (u32 i = 0; i < 2; i++) |
| 170 | { |
| 171 | m_env.CTXT[i].UpdateScissor(); |
| 172 | |
| 173 | // What is this nonsense? Basically, GOW does a 32x448 draw after resetting the GS, thinking the PSM for the framebuffer is going |
| 174 | // to be set to C24, therefore the alpha bits get left alone. Because of the reset, in PCSX2, it ends up as C32, and the TC gets |
| 175 | // confused, leading to a later texture load using this render target instead of local memory. It's a problem because the game |
| 176 | // uploads texture data on startup to the beginning of VRAM, and never overwrites it. |
| 177 | // |
| 178 | // In the software renderer, if we let the draw happen, it gets scissored to 1x1 (because the scissor is inclusive of the |
| 179 | // upper bounds). This doesn't seem to destroy the chest texture, presumably it's further out in memory. |
| 180 | // |
| 181 | // Hardware test show that VRAM gets corrupted on CSR reset, but the first page remains intact. We're guessing this has something |
| 182 | // to do with DRAM refresh, and perhaps the internal counters used for refresh also getting reset. We're obviously not going |
| 183 | // to emulate this, but to work around the aforementioned issue, in the hardware renderers, we set the scissor to an out of |
| 184 | // bounds value. This means that draws get skipped until the game sets a proper scissor up, which is definitely going to happen |
| 185 | // after reset (otherwise it'd only ever render 1x1). |
| 186 | // |
| 187 | if (!hardware_reset && GSIsHardwareRenderer()) |
| 188 | m_env.CTXT[i].scissor.cull = GSVector4i::xffffffff(); |
| 189 | |
| 190 | m_env.CTXT[i].offset.fb = m_mem.GetOffset(m_env.CTXT[i].FRAME.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].FRAME.PSM); |
| 191 | m_env.CTXT[i].offset.zb = m_mem.GetOffset(m_env.CTXT[i].ZBUF.Block(), m_env.CTXT[i].FRAME.FBW, m_env.CTXT[i].ZBUF.PSM); |
| 192 | m_env.CTXT[i].offset.fzb4 = m_mem.GetPixelOffset4(m_env.CTXT[i].FRAME, m_env.CTXT[i].ZBUF); |
| 193 | } |
| 194 | |
| 195 | UpdateScissor(); |
| 196 | |
| 197 | m_vertex->head = 0; |
| 198 | m_vertex->tail = 0; |
| 199 | m_vertex->next = 0; |
| 200 | m_index->tail = 0; |
| 201 | m_scanmask_used = 0; |
| 202 | m_texflush_flag = false; |
| 203 | m_channel_shuffle = false; |
| 204 | m_dirty_gs_regs = 0; |
| 205 | m_backed_up_ctx = -1; |
| 206 | |
| 207 | memcpy(&m_prev_env, &m_env, sizeof(m_prev_env)); |
| 208 | |
| 209 | ResetDrawBuffers(); |
no test coverage detected