void VertexShaderCache::Init() { const D3D11_INPUT_ELEMENT_DESC simpleelems[2] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; const D3D11_INPUT_ELEMENT_DESC clearelems[2] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; unsigned int cbsize = ROUND_UP(sizeof(VertexShaderConstants), 16); // must be a multiple of 16 D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); HRESULT hr = D3D::device->CreateBuffer(&cbdesc, nullptr, &vscbuf); CHECK(hr == S_OK, "Create vertex shader constant buffer (size=%u)", cbsize); D3D::SetDebugObjectName((ID3D11DeviceChild*)vscbuf, "vertex shader constant buffer used to emulate the GX pipeline"); D3DBlob* blob; D3D::CompileVertexShader(simple_shader_code, &blob); D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout); SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob); if (SimpleLayout == nullptr || SimpleVertexShader == nullptr) PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__); blob->Release(); D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleVertexShader, "simple vertex shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)SimpleLayout, "simple input layout"); D3D::CompileVertexShader(clear_shader_code, &blob); D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout); ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob); if (ClearLayout == nullptr || ClearVertexShader == nullptr) PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__); blob->Release(); D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearVertexShader, "clear vertex shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)ClearLayout, "clear input layout"); Clear(); if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); SETSTAT(stats.numVertexShadersCreated, 0); SETSTAT(stats.numVertexShadersAlive, 0); std::string cache_filename = StringFromFormat("%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), SConfig::GetInstance().m_strUniqueID.c_str()); VertexShaderCacheInserter inserter; g_vs_disk_cache.OpenAndRead(cache_filename, inserter); if (g_Config.bEnableShaderDebugging) Clear(); last_entry = nullptr; }
void PixelShaderCache::Init() { last_entry = NULL; //program used for clear screen { char pprog[3072]; sprintf(pprog, "void main(\n" "out float4 ocol0 : COLOR0,\n" " in float4 incol0 : COLOR0){\n" "ocol0 = incol0;\n" "}\n"); s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); } int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF); int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); // other screen copy/convert programs for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) { for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) { for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) { if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1] || depthType && !s_CopyProgram[copyMatrixType][depthType-1][ssaaMode] || copyMatrixType && !s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]) { // if it failed at a lower setting, it's going to fail here for the same reason it did there, // so skip this attempt to avoid duplicate error messages. s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; } else { s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode); } } } } Clear(); if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); SETSTAT(stats.numPixelShadersCreated, 0); SETSTAT(stats.numPixelShadersAlive, 0); char cache_filename[MAX_PATH]; sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); PixelShaderCacheInserter inserter; g_ps_disk_cache.OpenAndRead(cache_filename, inserter); if (g_Config.bEnableShaderDebugging) Clear(); }
void VertexShaderCache::Init() { const D3D11_INPUT_ELEMENT_DESC simpleelems[2] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; const D3D11_INPUT_ELEMENT_DESC clearelems[2] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; unsigned int cbsize = Common::AlignUp(static_cast<unsigned int>(sizeof(VertexShaderConstants)), 16); // must be a multiple of 16 D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); HRESULT hr = D3D::device->CreateBuffer(&cbdesc, nullptr, &vscbuf); CHECK(hr == S_OK, "Create vertex shader constant buffer (size=%u)", cbsize); D3D::SetDebugObjectName(vscbuf, "vertex shader constant buffer used to emulate the GX pipeline"); D3DBlob* blob; D3D::CompileVertexShader(simple_shader_code, &blob); D3D::device->CreateInputLayout(simpleelems, 2, blob->Data(), blob->Size(), &SimpleLayout); SimpleVertexShader = D3D::CreateVertexShaderFromByteCode(blob); if (SimpleLayout == nullptr || SimpleVertexShader == nullptr) PanicAlert("Failed to create simple vertex shader or input layout at %s %d\n", __FILE__, __LINE__); blob->Release(); D3D::SetDebugObjectName(SimpleVertexShader, "simple vertex shader"); D3D::SetDebugObjectName(SimpleLayout, "simple input layout"); D3D::CompileVertexShader(clear_shader_code, &blob); D3D::device->CreateInputLayout(clearelems, 2, blob->Data(), blob->Size(), &ClearLayout); ClearVertexShader = D3D::CreateVertexShaderFromByteCode(blob); if (ClearLayout == nullptr || ClearVertexShader == nullptr) PanicAlert("Failed to create clear vertex shader or input layout at %s %d\n", __FILE__, __LINE__); blob->Release(); D3D::SetDebugObjectName(ClearVertexShader, "clear vertex shader"); D3D::SetDebugObjectName(ClearLayout, "clear input layout"); Clear(); SETSTAT(stats.numVertexShadersCreated, 0); SETSTAT(stats.numVertexShadersAlive, 0); if (g_ActiveConfig.bShaderCache) LoadShaderCache(); g_async_compiler = std::make_unique<VideoCommon::AsyncShaderCompiler>(); g_async_compiler->ResizeWorkerThreads(g_ActiveConfig.CanPrecompileUberShaders() ? g_ActiveConfig.GetShaderPrecompilerThreads() : g_ActiveConfig.GetShaderCompilerThreads()); if (g_ActiveConfig.CanPrecompileUberShaders()) QueueUberShaderCompiles(); }
void PixelShaderCache::Init() { Clear(); SETSTAT(stats.numPixelShadersCreated, 0); SETSTAT(stats.numPixelShadersAlive, 0); last_entry = nullptr; }
ssize_t _sys_read( struct fdinfo *fio, bitptr bufptr, size_t nbytes, struct ffsw *retstat, int fulp, int *ubc) { ssize_t ret = 0; char *buf; buf = BPTR2CP(bufptr); if ((BPBITOFF(bufptr) & 7) != 0 || *ubc != 0) ERETURN(retstat, FDC_ERR_UBC, 0); #ifdef __mips /* * If our last i/o was asynchronous, then our file position * won't be what we expect. Seek to the right position. We * could use a pread instead of seeking, but that would also * not update the file position. I'm doing this because it seems * to me most 'expected' for the system call layer. */ if (((struct sys_f *)fio->lyr_info)->needpos) { if (lseek( fio->realfd, ((struct sys_f *)fio->lyr_info)->curpos, 0) < 0) ERETURN(retstat, errno, 0); ((struct sys_f *)fio->lyr_info)->needpos = 0; } #endif if (nbytes > 0) { if (((struct sys_f *)fio->lyr_info)->nointrio) ret = read(fio->realfd, buf, nbytes); else { LOOP_SYSCALL(ret, read(fio->realfd, buf, nbytes)); } if (ret < 0) ERETURN(retstat, errno, 0); } if (ret == 0 && nbytes > 0) { SETSTAT(retstat, FFEOD, ret); } else { SETSTAT(retstat, FFCNT, ret); #ifdef __mips ((struct sys_f *)(fio->lyr_info))->curpos += ret; #endif } return (ret); }
void PixelShaderCache::Init() { unsigned int cbsize = Common::AlignUp(static_cast<unsigned int>(sizeof(PixelShaderConstants)), 16); // must be a multiple of 16 D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); D3D::device->CreateBuffer(&cbdesc, nullptr, &pscbuf); CHECK(pscbuf != nullptr, "Create pixel shader constant buffer"); D3D::SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "pixel shader constant buffer used to emulate the GX pipeline"); // used when drawing clear quads s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code); CHECK(s_ClearProgram != nullptr, "Create clear pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "clear pixel shader"); // used for anaglyph stereoscopy s_AnaglyphProgram = D3D::CompileAndCreatePixelShader(anaglyph_program_code); CHECK(s_AnaglyphProgram != nullptr, "Create anaglyph pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_AnaglyphProgram, "anaglyph pixel shader"); // used when copying/resolving the color buffer s_ColorCopyProgram[0] = D3D::CompileAndCreatePixelShader(color_copy_program_code); CHECK(s_ColorCopyProgram[0] != nullptr, "Create color copy pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorCopyProgram[0], "color copy pixel shader"); // used for color conversion s_ColorMatrixProgram[0] = D3D::CompileAndCreatePixelShader(color_matrix_program_code); CHECK(s_ColorMatrixProgram[0] != nullptr, "Create color matrix pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorMatrixProgram[0], "color matrix pixel shader"); // used for depth copy s_DepthMatrixProgram[0] = D3D::CompileAndCreatePixelShader(depth_matrix_program); CHECK(s_DepthMatrixProgram[0] != nullptr, "Create depth matrix pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_DepthMatrixProgram[0], "depth matrix pixel shader"); Clear(); if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); SETSTAT(stats.numPixelShadersCreated, 0); SETSTAT(stats.numPixelShadersAlive, 0); std::string cache_filename = StringFromFormat("%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), SConfig::GetInstance().m_strGameID.c_str()); PixelShaderCacheInserter inserter; g_ps_disk_cache.OpenAndRead(cache_filename, inserter); last_entry = nullptr; }
static ssize_t _tmf_eovseen( struct tmfio *xfinfo, size_t nbytes, char *dataptr, ssize_t ret, struct ffsw *stat) { xfinfo->tmf_eovhit = 1; if (xfinfo->eovbuf == NULL) { xfinfo->eovbuf = malloc(xfinfo->tmf_bufsiz); if (xfinfo->eovbuf == NULL) { ERETURN(stat,FDC_ERR_NOMEM, 0); } xfinfo->eovbase = xfinfo->eovbuf; } if (ret < 0) { (void) memcpy(xfinfo->eovbuf, dataptr, nbytes); xfinfo->eovbytes = nbytes; xfinfo->tmf_partblk = 0; } else { (void) memcpy(xfinfo->eovbuf, dataptr + ret, nbytes - ret); xfinfo->eovbytes = nbytes - ret; xfinfo->tmf_partblk = 1; } xfinfo->tmf_cnt = 0; xfinfo->tmf_bufptr = xfinfo->tmf_base; SETSTAT(stat, FFEOR, nbytes); return(nbytes); }
bool PixelShaderCache::InsertByteCode(const PixelShaderUid &uid, const void* bytecode, unsigned int bytecodelen) { ID3D11PixelShader* shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); if (shader == nullptr) return false; // TODO: Somehow make the debug name a bit more specific D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache"); // Make an entry in the table PSCacheEntry newentry; newentry.shader = shader; PixelShaders[uid] = newentry; last_entry = &PixelShaders[uid]; if (!shader) { // INCSTAT(stats.numPixelShadersFailed); return false; } INCSTAT(stats.numPixelShadersCreated); SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); return true; }
FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { PIXELSHADERUID uid; GetPixelShaderId(&uid, dstAlphaMode, components); // Check if the shader is already set if (last_entry) { if (uid == last_uid) { GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); ValidatePixelShaderIDs(API_OPENGL, last_entry->safe_uid, last_entry->shader.strprog, dstAlphaMode, components); return &last_entry->shader; } } last_uid = uid; PSCache::iterator iter = PixelShaders.find(uid); if (iter != PixelShaders.end()) { PSCacheEntry &entry = iter->second; last_entry = &entry; GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); ValidatePixelShaderIDs(API_OPENGL, entry.safe_uid, entry.shader.strprog, dstAlphaMode, components); return &last_entry->shader; } // Make an entry in the table PSCacheEntry& newentry = PixelShaders[uid]; last_entry = &newentry; const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components); if (g_ActiveConfig.bEnableShaderDebugging && code) { GetSafePixelShaderId(&newentry.safe_uid, dstAlphaMode, components); newentry.shader.strprog = code; } #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { static int counter = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); SaveData(szTemp, code); } #endif if (!code || !CompilePixelShader(newentry.shader, code)) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return NULL; } INCSTAT(stats.numPixelShadersCreated); SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); return &last_entry->shader; }
void ShaderCache::HandlePSUIDChange(PixelShaderUid ps_uid, DSTALPHA_MODE ps_dst_alpha_mode) { s_last_pixel_shader_uid = ps_uid; auto ps_iterator = s_ps_bytecode_cache.find(ps_uid); if (ps_iterator != s_ps_bytecode_cache.end()) { s_last_pixel_shader_bytecode = ps_iterator->second; GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); } else { ShaderCode ps_code = GeneratePixelShaderCode(APIType::D3D, ps_uid.GetUidData()); ID3DBlob* ps_bytecode = nullptr; if (!D3D::CompilePixelShader(ps_code.GetBuffer(), &ps_bytecode)) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return; } s_last_pixel_shader_bytecode = InsertByteCode(ps_uid, &s_ps_bytecode_cache, ps_bytecode); s_ps_disk_cache.Append(ps_uid, reinterpret_cast<u8*>(ps_bytecode->GetBufferPointer()), static_cast<u32>(ps_bytecode->GetBufferSize())); SETSTAT(stats.numPixelShadersAlive, static_cast<int>(s_ps_bytecode_cache.size())); INCSTAT(stats.numPixelShadersCreated); } }
void ShaderCache::HandleVSUIDChange(VertexShaderUid vs_uid) { s_last_vertex_shader_uid = vs_uid; auto vs_iterator = s_vs_bytecode_cache.find(vs_uid); if (vs_iterator != s_vs_bytecode_cache.end()) { s_last_vertex_shader_bytecode = vs_iterator->second; GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); } else { ShaderCode vs_code = GenerateVertexShaderCode(APIType::D3D, vs_uid.GetUidData()); ID3DBlob* vs_bytecode = nullptr; if (!D3D::CompileVertexShader(vs_code.GetBuffer(), &vs_bytecode)) { GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); return; } s_last_vertex_shader_bytecode = InsertByteCode(vs_uid, &s_vs_bytecode_cache, vs_bytecode); s_vs_disk_cache.Append(vs_uid, reinterpret_cast<u8*>(vs_bytecode->GetBufferPointer()), static_cast<u32>(vs_bytecode->GetBufferSize())); SETSTAT(stats.numVertexShadersAlive, static_cast<int>(s_vs_bytecode_cache.size())); INCSTAT(stats.numVertexShadersCreated); } }
/* * Write an EOF to a buffer-layer file. * */ int _sqb_weof(struct fdinfo *fio, struct ffsw *stat) { struct fdinfo *llfio; if (fio->rwflag == WRITIN) { if (_sqb_flush(fio, stat) < 0) { return(ERR); } } else if (fio->rwflag == READIN || fio->rwflag == POSITIN) { /* synchronize physical position with logical */ if (_sqb_sync(fio, stat, 1) < 0) { return(ERR); } } fio->rwflag = WRITIN; /* * Tell the underlying layer to write an EOF */ llfio = fio->fioptr; if (XRCALL(llfio,weofrtn) llfio, stat) == ERR) return(ERR); SETSTAT(stat, FFEOF, 0); return(0); }
void PixelShaderCache::Init() { unsigned int cbsize = ((sizeof(PixelShaderConstants))&(~0xf))+0x10; // must be a multiple of 16 D3D11_BUFFER_DESC cbdesc = CD3D11_BUFFER_DESC(cbsize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); D3D::device->CreateBuffer(&cbdesc, NULL, &pscbuf); CHECK(pscbuf!=NULL, "Create pixel shader constant buffer"); D3D::SetDebugObjectName((ID3D11DeviceChild*)pscbuf, "pixel shader constant buffer used to emulate the GX pipeline"); // used when drawing clear quads s_ClearProgram = D3D::CompileAndCreatePixelShader(clear_program_code, sizeof(clear_program_code)); CHECK(s_ClearProgram!=NULL, "Create clear pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ClearProgram, "clear pixel shader"); // used when copying/resolving the color buffer s_ColorCopyProgram[0] = D3D::CompileAndCreatePixelShader(color_copy_program_code, sizeof(color_copy_program_code)); CHECK(s_ColorCopyProgram[0]!=NULL, "Create color copy pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorCopyProgram[0], "color copy pixel shader"); // used for color conversion s_ColorMatrixProgram[0] = D3D::CompileAndCreatePixelShader(color_matrix_program_code, sizeof(color_matrix_program_code)); CHECK(s_ColorMatrixProgram[0]!=NULL, "Create color matrix pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_ColorMatrixProgram[0], "color matrix pixel shader"); // used for depth copy s_DepthMatrixProgram[0] = D3D::CompileAndCreatePixelShader(depth_matrix_program, sizeof(depth_matrix_program)); CHECK(s_DepthMatrixProgram[0]!=NULL, "Create depth matrix pixel shader"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_DepthMatrixProgram[0], "depth matrix pixel shader"); Clear(); if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); SETSTAT(stats.numPixelShadersCreated, 0); SETSTAT(stats.numPixelShadersAlive, 0); char cache_filename[MAX_PATH]; sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); PixelShaderCacheInserter inserter; g_ps_disk_cache.OpenAndRead(cache_filename, inserter); if (g_Config.bEnableShaderDebugging) Clear(); last_entry = NULL; }
int _er90b_write(struct fdinfo *fio, bitptr bufptr, int nbytes, struct ffsw *retstat, int fulp, int *ubc) { int ret; int nbt = 0; /* number of bytes transferred so far */ int nbreq; /* number of bytes requested this request */ char *buf; ER90BYT *f; int zero = 0; struct ffsw dumstat; buf = BPTR2CP(bufptr); if ((BPBITOFF(bufptr) & 7) != 0 || *ubc != 0) ERETURN(retstat, FDC_ERR_UBC, 0); nbreq = nbytes; if (fio->rwflag == POSITIN) { f = (ER90BYT *)fio->lyr_info; if (f->tpos) { ret = _tape_tpwait(f->fd, &(f->tpos)); if (ret < 0) ERETURN(retstat, errno, 0); } } else if (fio->rwflag == READIN) { /* write after read requires position to zero */ ret = _er90b_pos(fio, FP_RSEEK, &zero, 1, &dumstat); if (ret < 0) { *retstat = dumstat; return(ERR); } } if (nbreq > 0) { again: /* It is not safe to reissue the write if it fails */ /* with EINTR. Some data may have been transferred */ ret= write(fio->realfd, buf, nbreq); if (ret < 0) ERETURN(retstat, errno, nbt); nbt += ret; /* * The assumption is made here that the system will never return * zero bytes on a non-zero request without an error! */ if (nbt < nbytes) { buf += ret; nbreq -= ret; goto again; } } else if (nbytes < 0) ERETURN(retstat, FDC_ERR_REQ, 0); SETSTAT(retstat, FFCNT, nbt); fio->rwflag = WRITIN; return (nbt); }
void Init() { MarkAllDirty(); for (auto& map_entry : g_main_cp_state.vertex_loaders) map_entry = nullptr; for (auto& map_entry : g_preprocess_cp_state.vertex_loaders) map_entry = nullptr; SETSTAT(stats.numVertexLoaders, 0); }
_ffseek_t _sys_lseek(struct fdinfo *fio, off_t pos, int whence, struct ffsw *stat) { off_t ret; #ifdef __mips if ((((struct sys_f *)(fio->lyr_info))->needpos) && whence == SEEK_CUR) ret = lseek(fio->realfd, pos + ((struct sys_f *)(fio->lyr_info))->curpos, SEEK_SET); else ret = lseek(fio->realfd, pos, whence); #else ret = lseek(fio->realfd, pos, whence); #endif if (ret < 0) { ERETURN(stat, errno, 0); } #ifdef __mips ((struct sys_f *)(fio->lyr_info))->curpos = ret; ((struct sys_f *)(fio->lyr_info))->needpos = 0; #endif fio->rwflag = POSITIN; if (whence == SEEK_SET && pos == 0) { fio->ateof = 0; fio->ateod = 0; SETSTAT(stat, FFBOD, 0); } else if (whence == SEEK_END && pos == 0) { fio->ateof = 1; fio->ateod = 1; /* seek to end, set stat */ SETSTAT(stat, FFEOD, 0); } else SETSTAT(stat, FFCNT, 0); fio->last_recbits = fio->recbits; fio->recbits = 0; return (ret); }
void VertexShaderCache::PushByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, VertexShaderCache::VSCacheEntry* entry) { entry->shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen); entry->compiled = true; if (entry->shader) { INCSTAT(stats.numVertexShadersCreated); SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); } }
void PixelShaderCache::PushByteCode(const PixelShaderUid &uid, const u8 *bytecode, int bytecodelen, PixelShaderCache::PSCacheEntry* entry) { entry->shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); entry->compiled = true; if (entry->shader) { INCSTAT(stats.numPixelShadersCreated); SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); } }
void ProgramShaderCache::Init(void) { // We have to get the UBO alignment here because // if we generate a buffer that isn't aligned // then the UBO will fail. if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) { GLint Align; glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &Align); s_ps_data_size = C_PENVCONST_END * sizeof(float) * 4; s_vs_data_size = C_VENVCONST_END * sizeof(float) * 4; s_vs_data_offset = ROUND_UP(s_ps_data_size, Align); s_ubo_buffer_size = ROUND_UP(s_ps_data_size, Align) + ROUND_UP(s_vs_data_size, Align); // We multiply by *4*4 because we need to get down to basic machine units. // So multiply by four to get how many floats we have from vec4s // Then once more to get bytes s_buffer = new StreamBuffer(GL_UNIFORM_BUFFER, UBO_LENGTH); s_ubo_buffer = new u8[s_ubo_buffer_size]; memset(s_ubo_buffer, 0, s_ubo_buffer_size); s_ubo_dirty = true; } // Read our shader cache, only if supported if (g_ogl_config.bSupportsGLSLCache) { GLint Supported; glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &Supported); if(!Supported) { ERROR_LOG(VIDEO, "GL_ARB_get_program_binary is supported, but no binary format is known. So disable shader cache."); g_ogl_config.bSupportsGLSLCache = false; } else { if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); char cache_filename[MAX_PATH]; sprintf(cache_filename, "%sogl-%s-shaders.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); ProgramShaderCacheInserter inserter; g_program_disk_cache.OpenAndRead(cache_filename, inserter); } SETSTAT(stats.numPixelShadersAlive, pshaders.size()); } CreateHeader(); CurrentProgram = 0; last_entry = NULL; }
void ShaderCache::Init() { // This class intentionally shares its shader cache files with DX11, as the shaders are (right // now) identical. // Reduces unnecessary compilation when switching between APIs. s_last_geometry_shader_bytecode = {}; s_last_pixel_shader_bytecode = {}; s_last_vertex_shader_bytecode = {}; s_last_geometry_shader_uid = {}; s_last_pixel_shader_uid = {}; s_last_vertex_shader_uid = {}; // Ensure shader cache directory exists.. std::string shader_cache_path = File::GetUserPath(D_SHADERCACHE_IDX); if (!File::Exists(shader_cache_path)) File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); std::string title_game_id = SConfig::GetInstance().m_strGameID.c_str(); std::string gs_cache_filename = StringFromFormat("%sdx11-%s-gs.cache", shader_cache_path.c_str(), title_game_id.c_str()); std::string ps_cache_filename = StringFromFormat("%sdx11-%s-ps.cache", shader_cache_path.c_str(), title_game_id.c_str()); std::string vs_cache_filename = StringFromFormat("%sdx11-%s-vs.cache", shader_cache_path.c_str(), title_game_id.c_str()); ShaderCacheInserter<GeometryShaderUid, GsBytecodeCache, &s_gs_bytecode_cache> gs_inserter; s_gs_disk_cache.OpenAndRead(gs_cache_filename, gs_inserter); ShaderCacheInserter<PixelShaderUid, PsBytecodeCache, &s_ps_bytecode_cache> ps_inserter; s_ps_disk_cache.OpenAndRead(ps_cache_filename, ps_inserter); ShaderCacheInserter<VertexShaderUid, VsBytecodeCache, &s_vs_bytecode_cache> vs_inserter; s_vs_disk_cache.OpenAndRead(vs_cache_filename, vs_inserter); SETSTAT(stats.numPixelShadersAlive, static_cast<int>(s_ps_bytecode_cache.size())); SETSTAT(stats.numPixelShadersCreated, static_cast<int>(s_ps_bytecode_cache.size())); SETSTAT(stats.numVertexShadersAlive, static_cast<int>(s_vs_bytecode_cache.size())); SETSTAT(stats.numVertexShadersCreated, static_cast<int>(s_vs_bytecode_cache.size())); }
void GeometryShaderCache::PushByteCode(const void* bytecode, unsigned int bytecodelen, GeometryShaderCache::GSCacheEntry* entry) { entry->shader = std::move(D3D::CreateGeometryShaderFromByteCode(bytecode, bytecodelen)); entry->compiled = true; if (entry->shader != nullptr) { // TODO: Somehow make the debug name a bit more specific D3D::SetDebugObjectName(entry->shader.get(), "a Geometry shader of GeometryShaderCache"); INCSTAT(stats.numGeometryShadersCreated); SETSTAT(stats.numGeometryShadersAlive, static_cast<int>(s_geometry_shaders->size())); } }
void VertexShaderCache::PushByteCode(D3DBlob&& bcodeblob, VSCacheEntry* entry) { entry->shader = std::move(D3D::CreateVertexShaderFromByteCode(bcodeblob)); entry->compiled = true; entry->SetByteCode(std::move(bcodeblob)); if (entry->shader) { // TODO: Somehow make the debug name a bit more specific D3D::SetDebugObjectName(entry->shader.get(), "a vertex shader of VertexShaderCache"); INCSTAT(stats.numVertexShadersCreated); SETSTAT(stats.numVertexShadersAlive, static_cast<int>(s_vshaders->size())); } }
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; }
void ProgramShaderCache::Init() { // We have to get the UBO alignment here because // if we generate a buffer that isn't aligned // then the UBO will fail. glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &s_ubo_align); s_ubo_buffer_size = ROUND_UP(PixelShaderManager::ConstantBufferSize * sizeof(float), s_ubo_align) + ROUND_UP(VertexShaderManager::ConstantBufferSize * sizeof(float), s_ubo_align) + ROUND_UP(sizeof(GeometryShaderConstants), s_ubo_align); // We multiply by *4*4 because we need to get down to basic machine units. // So multiply by four to get how many floats we have from vec4s // Then once more to get bytes s_buffer = StreamBuffer::Create(GL_UNIFORM_BUFFER, UBO_LENGTH); // Read our shader cache, only if supported if (g_ogl_config.bSupportsGLSLCache && !g_Config.bEnableShaderDebugging) { GLint Supported; glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &Supported); if (!Supported) { ERROR_LOG(VIDEO, "GL_ARB_get_program_binary is supported, but no binary format is known. So disable shader cache."); g_ogl_config.bSupportsGLSLCache = false; } else { if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); std::string cache_filename = StringFromFormat("%sIOGL-%s-shaders.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), SConfig::GetInstance().m_strUniqueID.c_str()); ProgramShaderCacheInserter inserter; g_program_disk_cache.OpenAndRead(cache_filename, inserter); } SETSTAT(stats.numPixelShadersAlive, pshaders.size()); } CreateHeader(); CurrentProgram = 0; last_entry = nullptr; }
_er90b_lseek(struct fdinfo *fio, int pos, int whence, struct ffsw *stat) { int ret; if (whence == 0 && pos == 0) { ret = _er90b_rewd((ER90BYT *)fio->lyr_info); if (ret < 0) ERETURN(stat, errno, 0); fio->ateof = 0; fio->ateod = 0; SETSTAT(stat, FFBOD, 0); } else { ERETURN(stat, FDC_ERR_NOSUP, 0); } fio->rwflag = POSITIN; return (0); }
bool VertexShaderCache::InsertShader(const VertexShaderUid& uid, ID3D11VertexShader* shader, D3DBlob* blob) { auto iter = vshaders.find(uid); if (iter != vshaders.end() && !iter->second.pending) return false; VSCacheEntry& newentry = vshaders[uid]; newentry.pending = false; if (!shader || !blob) return false; shader->AddRef(); newentry.SetByteCode(blob); newentry.shader = shader; INCSTAT(stats.numPixelShadersCreated); SETSTAT(stats.numPixelShadersAlive, static_cast<int>(vshaders.size())); return true; }
/* * Write an EOD. * Truncate the file. This is the 'real' end of the data. * We cannot do this if we were reading or if we just positioned. */ int _tmf_weod(struct fdinfo *fio, struct ffsw *stat) { register int ret; struct tmfio *xfinfo; xfinfo = (struct tmfio *)fio->lyr_info; if (xfinfo->rwflag != WRITIN) { ERETURN(stat, FENOENDF, 0); } ret = XRCALL(fio, flushrtn) fio, stat); if (ret < 0) return(ret); SETSTAT(stat, FFEOD, 0); return(0); }
bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) { LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen); // Make an entry in the table VSCacheEntry entry; entry.shader = shader; vshaders[uid] = entry; last_entry = &vshaders[uid]; if (!shader) return false; INCSTAT(stats.numVertexShadersCreated); SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); if (activate) { D3D::SetVertexShader(shader); return true; } return false; }
bool VertexShaderCache::InsertByteCode(const VertexShaderUid& uid, D3DBlob* bcodeblob) { ID3D11VertexShader* shader = D3D::CreateVertexShaderFromByteCode(bcodeblob); if (shader == nullptr) return false; // TODO: Somehow make the debug name a bit more specific D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a vertex shader of VertexShaderCache"); // Make an entry in the table VSCacheEntry entry; entry.shader = shader; entry.SetByteCode(bcodeblob); vshaders[uid] = entry; last_entry = &vshaders[uid]; INCSTAT(stats.numVertexShadersCreated); SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); return true; }
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) { LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); // Make an entry in the table PSCacheEntry newentry; newentry.shader = shader; PixelShaders[uid] = newentry; last_entry = &PixelShaders[uid]; if (!shader) { // INCSTAT(stats.numPixelShadersFailed); return false; } INCSTAT(stats.numPixelShadersCreated); SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); if (activate) { D3D::SetPixelShader(shader); } return true; }