bool VertexShaderCache::SetShader(u32 components) { VERTEXSHADERUID uid; GetVertexShaderId(&uid, components); if (last_entry) { if (uid == last_uid) { GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); ValidateVertexShaderIDs(API_D3D11, last_entry->safe_uid, last_entry->code, components); return (last_entry->shader != NULL); } } last_uid = uid; VSCache::iterator iter = vshaders.find(uid); if (iter != vshaders.end()) { const VSCacheEntry &entry = iter->second; last_entry = &entry; GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); ValidateVertexShaderIDs(API_D3D11, entry.safe_uid, entry.code, components); return (entry.shader != NULL); } const char *code = GenerateVertexShaderCode(components, API_D3D11); D3DBlob* pbytecode = NULL; D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode); if (pbytecode == NULL) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return false; } g_vs_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size()); bool success = InsertByteCode(uid, pbytecode); pbytecode->Release(); if (g_ActiveConfig.bEnableShaderDebugging && success) { vshaders[uid].code = code; GetSafeVertexShaderId(&vshaders[uid].safe_uid, components); } GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return success; }
VERTEXSHADER* VertexShaderCache::SetShader(u32 components) { VERTEXSHADERUID uid; GetVertexShaderId(&uid, components); if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount) { GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return pShaderLast; } memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID)); VSCache::iterator iter = vshaders.find(uid); if (iter != vshaders.end()) { iter->second.frameCount = frameCount; VSCacheEntry &entry = iter->second; if (&entry.shader != pShaderLast) { pShaderLast = &entry.shader; } GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return pShaderLast; } // Make an entry in the table VSCacheEntry& entry = vshaders[uid]; entry.frameCount = frameCount; pShaderLast = &entry.shader; const char *code = GenerateVertexShaderCode(components, API_OPENGL); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { static int counter = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%svs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); SaveData(szTemp, code); } #endif if (!code || !VertexShaderCache::CompileVertexShader(entry.shader, code)) { ERROR_LOG(VIDEO, "failed to create vertex shader"); GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return NULL; } INCSTAT(stats.numVertexShadersCreated); SETSTAT(stats.numVertexShadersAlive, vshaders.size()); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return pShaderLast; }
bool VertexShaderCache::SetShader(u32 components) { VERTEXSHADERUID uid; GetVertexShaderId(&uid, components); if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount) { GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return (vshaders[uid].shader != NULL); } memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID)); VSCache::iterator iter = vshaders.find(uid); if (iter != vshaders.end()) { iter->second.frameCount = frameCount; const VSCacheEntry &entry = iter->second; last_entry = &entry; if (entry.shader) D3D::SetVertexShader(entry.shader); GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return (entry.shader != NULL); } const char *code = GenerateVertexShaderCode(components, API_D3D9); u8 *bytecode; int bytecodelen; if (!D3D::CompileVertexShader(code, (int)strlen(code), &bytecode, &bytecodelen)) { if (g_ActiveConfig.bShowShaderErrors) { PanicAlert("Failed to compile Vertex Shader:\n\n%s", code); } GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return false; } g_vs_disk_cache.Append(uid, bytecode, bytecodelen); g_vs_disk_cache.Sync(); bool result = InsertByteCode(uid, bytecode, bytecodelen, true); delete [] bytecode; GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); return result; }