Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assorted crash fixes and asserts #17374

Merged
merged 8 commits into from
May 1, 2023
4 changes: 4 additions & 0 deletions Common/GPU/OpenGL/GLRenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,10 @@ class GLRenderManager {
pushbuffer->End();
}

bool IsInRenderPass() const {
return curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER;
}

// This starts a new step (like a "render pass" in Vulkan).
//
// After a "CopyFramebuffer" or the other functions that start "steps", you need to call this before
Expand Down
2 changes: 2 additions & 0 deletions Common/GPU/Vulkan/VulkanMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,8 @@ void VulkanPushPool::BeginFrame() {
}

void VulkanPushPool::NextBlock(VkDeviceSize allocationSize) {
_dbg_assert_(allocationSize != 0); // If so, the logic in the caller is wrong, should never need a new block for this case.

int curFrameIndex = vulkan_->GetCurFrame();
curBlockIndex_++;
while (curBlockIndex_ < blocks_.size()) {
Expand Down
1 change: 1 addition & 0 deletions Common/GPU/Vulkan/VulkanMemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class VulkanPushPool : public VulkanMemoryManager {
void GetDebugString(char *buffer, size_t bufSize) const override;

// When using the returned memory, make sure to bind the returned vkbuf.
// It is okay to allocate 0 bytes.
uint8_t *Allocate(VkDeviceSize numBytes, VkDeviceSize alignment, VkBuffer *vkbuf, uint32_t *bindOffset) {
_dbg_assert_(curBlockIndex_ >= 0);

Expand Down
5 changes: 5 additions & 0 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,11 @@ void VKContext::DrawIndexed(int vertexCount, int offset) {
}

void VKContext::DrawUP(const void *vdata, int vertexCount) {
_dbg_assert_(vertexCount >= 0);
if (vertexCount <= 0) {
return;
}

VkBuffer vulkanVbuf, vulkanUBObuf;
size_t vbBindOffset = push_->Push(vdata, vertexCount * curPipeline_->stride[0], 4, &vulkanVbuf);
uint32_t ubo_offset = (uint32_t)curPipeline_->PushUBO(push_, vulkan_, &vulkanUBObuf);
Expand Down
2 changes: 1 addition & 1 deletion Core/CoreTiming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ void Shutdown()
delete ev;
}
}

u64 GetTicks()
{
if (currentMIPS) {
Expand Down
71 changes: 49 additions & 22 deletions Core/ELF/ParamSFO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,28 @@ void ParamSFOData::SetValue(std::string key, std::string value, int max_size) {
values[key].max_size = max_size;
}

void ParamSFOData::SetValue(std::string key, const u8* value, unsigned int size, int max_size) {
void ParamSFOData::SetValue(std::string key, const u8 *value, unsigned int size, int max_size) {
values[key].type = VT_UTF8_SPE;
values[key].SetData(value,size);
values[key].SetData(value, size);
values[key].max_size = max_size;
}

int ParamSFOData::GetValueInt(std::string key) {
std::map<std::string,ValueData>::iterator it = values.find(key);
int ParamSFOData::GetValueInt(std::string key) const {
std::map<std::string,ValueData>::const_iterator it = values.find(key);
if(it == values.end() || it->second.type != VT_INT)
return 0;
return it->second.i_value;
}
std::string ParamSFOData::GetValueString(std::string key) {
std::map<std::string,ValueData>::iterator it = values.find(key);

std::string ParamSFOData::GetValueString(std::string key) const {
std::map<std::string,ValueData>::const_iterator it = values.find(key);
if(it == values.end() || (it->second.type != VT_UTF8))
return "";
return it->second.s_value;
}
u8* ParamSFOData::GetValueData(std::string key, unsigned int *size) {
std::map<std::string,ValueData>::iterator it = values.find(key);

const u8 *ParamSFOData::GetValueData(std::string key, unsigned int *size) const {
std::map<std::string,ValueData>::const_iterator it = values.find(key);
if(it == values.end() || (it->second.type != VT_UTF8_SPE))
return 0;
if(size)
Expand All @@ -83,7 +85,7 @@ u8* ParamSFOData::GetValueData(std::string key, unsigned int *size) {
return it->second.u_value;
}

std::vector<std::string> ParamSFOData::GetKeys() {
std::vector<std::string> ParamSFOData::GetKeys() const {
std::vector<std::string> result;
for (const auto &pair : values) {
result.push_back(pair.first);
Expand All @@ -109,43 +111,70 @@ bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size) {

const u8 *data_start = paramsfo + header->data_table_start;

auto readStringCapped = [paramsfo, size](size_t offset, size_t maxLen) -> std::string {
std::string str;
while (offset < size) {
char c = (char)(paramsfo[offset]);
if (c) {
str.push_back(c);
} else {
break;
}
offset++;
if (maxLen != 0 && str.size() == maxLen)
break;
}
return str;
};

for (u32 i = 0; i < header->index_table_entries; i++)
{
size_t key_offset = header->key_table_start + indexTables[i].key_table_offset;
if (key_offset >= size) {
return false;
}

size_t data_offset = header->data_table_start + indexTables[i].data_table_offset;
if (data_offset >= size) {
return false;
}

const char *key = (const char *)(paramsfo + key_offset);
std::string key = readStringCapped(key_offset, 0);
if (key.empty())
continue; // Likely ran into a truncated PARAMSFO.

switch (indexTables[i].param_fmt) {
case 0x0404:
{
if (data_offset + 4 > size)
continue;
// Unsigned int
const u32_le *data = (const u32_le *)(paramsfo + data_offset);
SetValue(key, *data, indexTables[i].param_max_len);
VERBOSE_LOG(LOADER, "%s %08x", key, *data);
VERBOSE_LOG(LOADER, "%s %08x", key.c_str(), *data);
}
break;
case 0x0004:
// Special format UTF-8
{
if (data_offset + indexTables[i].param_len > size)
continue;
const u8 *utfdata = (const u8 *)(paramsfo + data_offset);
VERBOSE_LOG(LOADER, "%s %s", key, utfdata);
VERBOSE_LOG(LOADER, "%s %s", key.c_str(), utfdata);
SetValue(key, utfdata, indexTables[i].param_len, indexTables[i].param_max_len);
}
break;
case 0x0204:
// Regular UTF-8
{
const char *utfdata = (const char *)(paramsfo + data_offset);
VERBOSE_LOG(LOADER, "%s %s", key, utfdata);
SetValue(key, std::string(utfdata /*, indexTables[i].param_len*/), indexTables[i].param_max_len);
// TODO: Likely should use param_len here, but there's gotta be a reason we avoided it before.
std::string str = readStringCapped(data_offset, indexTables[i].param_max_len);
VERBOSE_LOG(LOADER, "%s %s", key.c_str(), str.c_str());
SetValue(key, str, indexTables[i].param_max_len);
}
break;
default:
break;
}
}

Expand Down Expand Up @@ -176,7 +205,7 @@ int ParamSFOData::GetDataOffset(const u8 *paramsfo, std::string dataName) {
return -1;
}

bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size) {
bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size) const {
size_t total_size = 0;
size_t key_size = 0;
size_t data_size = 0;
Expand All @@ -198,7 +227,7 @@ bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size) {
}

// Padding
while((key_size%4)) key_size++;
while ((key_size % 4) != 0) key_size++;

header.key_table_start = sizeof(Header) + header.index_table_entries * sizeof(IndexTable);
header.data_table_start = header.key_table_start + (u32)key_size;
Expand Down Expand Up @@ -266,20 +295,18 @@ void ParamSFOData::Clear() {
}

void ParamSFOData::ValueData::SetData(const u8* data, int size) {
if(u_value)
{
if (u_value) {
delete[] u_value;
u_value = 0;
}
if(size > 0)
{
if (size > 0) {
u_value = new u8[size];
memcpy(u_value, data, size);
}
u_size = size;
}

std::string ParamSFOData::GenerateFakeID(std::string filename) {
std::string ParamSFOData::GenerateFakeID(std::string filename) const {
// Generates fake gameID for homebrew based on it's folder name.
// Should probably not be a part of ParamSFO, but it'll be called in same places.
std::string file = PSP_CoreParameter().fileToStart.ToString();
Expand Down
14 changes: 7 additions & 7 deletions Core/ELF/ParamSFO.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ class ParamSFOData
public:
void SetValue(std::string key, unsigned int value, int max_size);
void SetValue(std::string key, std::string value, int max_size);
void SetValue(std::string key, const u8* value, unsigned int size, int max_size);
void SetValue(std::string key, const u8 *value, unsigned int size, int max_size);

int GetValueInt(std::string key);
std::string GetValueString(std::string key);
u8* GetValueData(std::string key, unsigned int *size);
int GetValueInt(std::string key) const;
std::string GetValueString(std::string key) const;
const u8 *GetValueData(std::string key, unsigned int *size) const;

std::vector<std::string> GetKeys();
std::string GenerateFakeID(std::string filename = "");
std::vector<std::string> GetKeys() const;
std::string GenerateFakeID(std::string filename = "") const;

std::string GetDiscID() {
const std::string discID = GetValueString("DISC_ID");
Expand All @@ -53,7 +53,7 @@ class ParamSFOData
}

bool ReadSFO(const u8 *paramsfo, size_t size);
bool WriteSFO(u8 **paramsfo, size_t *size);
bool WriteSFO(u8 **paramsfo, size_t *size) const;

bool ReadSFO(const std::vector<u8> &paramsfo) {
if (!paramsfo.empty()) {
Expand Down
21 changes: 20 additions & 1 deletion Core/HLE/Plugins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.

#include <set>
#include <mutex>

#include "Common/Data/Format/IniFile.h"
#include "Common/File/FileUtil.h"
Expand All @@ -29,6 +30,8 @@
#include "Core/HLE/sceKernelModule.h"

namespace HLEPlugins {

std::mutex g_inputMutex;
float PluginDataAxis[JOYSTICK_AXIS_MAX];
std::map<int, uint8_t> PluginDataKeys;

Expand Down Expand Up @@ -189,6 +192,8 @@ bool Load() {
started = true;
}

std::lock_guard<std::mutex> guard(g_inputMutex);
PluginDataKeys.clear();
return started;
}

Expand All @@ -199,6 +204,8 @@ void Unload() {
void Shutdown() {
prxPlugins.clear();
anyEnabled = false;
std::lock_guard<std::mutex> guard(g_inputMutex);
PluginDataKeys.clear();
}

void DoState(PointerWrap &p) {
Expand All @@ -214,4 +221,16 @@ bool HasEnabled() {
return anyEnabled;
}

};
void SetKey(int key, uint8_t value) {
if (anyEnabled) {
std::lock_guard<std::mutex> guard(g_inputMutex);
PluginDataKeys[key] = value;
}
}

uint8_t GetKey(int key) {
std::lock_guard<std::mutex> guard(g_inputMutex);
return PluginDataKeys[key];
}

} // namespace
8 changes: 6 additions & 2 deletions Core/HLE/Plugins.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#pragma once

#include <cstdint>
#include "Input/KeyCodes.h"

class PointerWrap;
Expand All @@ -33,6 +34,9 @@ void DoState(PointerWrap &p);

bool HasEnabled();

void SetKey(int key, uint8_t value);
uint8_t GetKey(int key);

extern float PluginDataAxis[JOYSTICK_AXIS_MAX];
extern std::map<int, uint8_t> PluginDataKeys;
};

} // namespace
2 changes: 1 addition & 1 deletion Core/HLE/sceIo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2072,7 +2072,7 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o
return 0;
case EMULATOR_DEVCTL__GET_VKEY:
if (Memory::IsValidAddress(outPtr) && (argAddr >= 0 && argAddr < NKCODE_MAX)) {
Memory::Write_U8(HLEPlugins::PluginDataKeys[argAddr], outPtr);
Memory::Write_U8(HLEPlugins::GetKey(argAddr), outPtr);
}
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions Core/Reporting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,8 @@ namespace Reporting
{
SetCurrentThreadName("Report");

AndroidJNIThreadContext jniContext; // destructor detaches

Payload &payload = payloadBuffer[pos];
Buffer output;

Expand Down
10 changes: 9 additions & 1 deletion GPU/GLES/DrawEngineGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ void DrawEngineGLES::DoFlush() {
PROFILE_THIS_SCOPE("flush");
FrameData &frameData = frameData_[render_->GetCurFrame()];

// Attempt to gather some information (asserts now upload the game name).
_assert_(render_->IsInRenderPass());

bool textureNeedsApply = false;
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
textureCache_->SetTexture();
Expand Down Expand Up @@ -411,7 +414,11 @@ void DrawEngineGLES::DoFlush() {

ApplyDrawStateLate(result.setStencil, result.stencilValue);

shaderManager_->ApplyFragmentShader(vsid, vshader, pipelineState_, framebufferManager_->UseBufferedRendering());
LinkedShader *linked = shaderManager_->ApplyFragmentShader(vsid, vshader, pipelineState_, framebufferManager_->UseBufferedRendering());
if (!linked) {
// Not much we can do here. Let's skip drawing.
goto bail;
}

if (result.action == SW_DRAW_PRIMITIVES) {
if (result.drawIndexed) {
Expand Down Expand Up @@ -455,6 +462,7 @@ void DrawEngineGLES::DoFlush() {
decOptions_.applySkinInDecode = g_Config.bSoftwareSkinning;
}

bail:
gpuStats.numFlushes++;
gpuStats.numDrawCalls += numDrawCalls;
gpuStats.numVertsSubmitted += vertexCountInDrawCalls_;
Expand Down
9 changes: 8 additions & 1 deletion GPU/GLES/ShaderManagerGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,15 @@ LinkedShader::LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs,
: render_(render), useHWTransform_(useHWTransform) {
PROFILE_THIS_SCOPE("shaderlink");

_assert_(vs);
_assert_(fs);

vs_ = vs;

std::vector<GLRShader *> shaders;
shaders.push_back(vs->shader);
shaders.push_back(fs->shader);


std::vector<GLRProgram::Semantic> semantics;
semantics.reserve(7);
semantics.push_back({ ATTR_POSITION, "position" });
Expand Down Expand Up @@ -874,6 +876,11 @@ LinkedShader *ShaderManagerGLES::ApplyFragmentShader(VShaderID VSID, Shader *vs,
if (ls == nullptr) {
_dbg_assert_(FSID.Bit(FS_BIT_FLATSHADE) == VSID.Bit(VS_BIT_FLATSHADE));

if (vs == nullptr || fs == nullptr) {
// Can't draw. This shouldn't really happen.
return nullptr;
}

// Check if we can link these.
ls = new LinkedShader(render_, VSID, vs, FSID, fs, vs->UseHWTransform());
ls->use(VSID);
Expand Down
Loading