Backport changes from libretro

This commit is contained in:
Flyinghead 2018-10-05 15:07:30 +02:00
parent 124f920170
commit 77fae1ef09
5 changed files with 157 additions and 94 deletions

View File

@ -77,10 +77,6 @@ extern int screen_height;
GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt);
void gl4DrawFramebuffer(float w, float h);
int gl4GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode,
u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset,
u32 pp_FogCtrl, bool two_volumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass);
extern const char *gl4PixelPipelineShader;
bool gl4CompilePipelineShader(gl4PipelineShader* s, const char *source = gl4PixelPipelineShader);

View File

@ -44,6 +44,30 @@ static GLuint texSamplers[2];
static GLuint depth_fbo;
GLuint depthSaveTexId;
static int gl4GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode,
u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset,
u32 pp_FogCtrl, bool pp_TwoVolumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass)
{
u32 rv=0;
rv|=pp_ClipTestMode;
rv<<=1; rv|=cp_AlphaTest;
rv<<=1; rv|=pp_Texture;
rv<<=1; rv|=pp_UseAlpha;
rv<<=1; rv|=pp_IgnoreTexA;
rv<<=2; rv|=pp_ShadInstr;
rv<<=1; rv|=pp_Offset;
rv<<=2; rv|=pp_FogCtrl;
rv <<= 1; rv |= (int)pp_TwoVolumes;
rv <<= 3; rv |= pp_DepthFunc;
rv <<= 1; rv |= (int)pp_Gouraud;
rv <<= 1; rv |= pp_BumpMap;
rv <<= 1; rv |= fog_clamping;
rv <<= 2; rv |= pass;
return rv;
}
static void setCurrentShader(u32 cp_AlphaTest, u32 pp_ClipTestMode,
u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset,
u32 pp_FogCtrl, bool pp_TwoVolumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass)
@ -446,11 +470,9 @@ void gl4DrawStrips(GLuint output_fbo)
if (texSamplers[0] == 0)
glGenSamplers(2, texSamplers);
glcache.ClearColor(0, 0, 0, 0);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glcache.DepthMask(GL_TRUE);
glStencilMask(0xFF);
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCheck();
glClear(GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCheck();
SetupMainVBO();
//Draw the strips !

View File

@ -409,30 +409,6 @@ gl4_ctx gl4;
struct gl4ShaderUniforms_t gl4ShaderUniforms;
int gl4GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode,
u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset,
u32 pp_FogCtrl, bool pp_TwoVolumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass)
{
u32 rv=0;
rv|=pp_ClipTestMode;
rv<<=1; rv|=cp_AlphaTest;
rv<<=1; rv|=pp_Texture;
rv<<=1; rv|=pp_UseAlpha;
rv<<=1; rv|=pp_IgnoreTexA;
rv<<=2; rv|=pp_ShadInstr;
rv<<=1; rv|=pp_Offset;
rv<<=2; rv|=pp_FogCtrl;
rv <<= 1; rv |= (int)pp_TwoVolumes;
rv <<= 3; rv |= pp_DepthFunc;
rv <<= 1; rv |= (int)pp_Gouraud;
rv <<= 1; rv |= pp_BumpMap;
rv <<= 1; rv |= fog_clamping;
rv <<= 2; rv |= pass;
return rv;
}
bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = PixelPipelineShader */)
{
char vshader[16384];
@ -505,6 +481,7 @@ bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = Pix
glUniform1i(gu, 3); // GL_TEXTURE3
s->pp_Number = glGetUniformLocation(s->program, "pp_Number");
s->pp_DepthFunc = glGetUniformLocation(s->program, "pp_DepthFunc");
s->blend_mode = glGetUniformLocation(s->program, "blend_mode");
s->use_alpha = glGetUniformLocation(s->program, "use_alpha");
@ -515,6 +492,24 @@ bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = Pix
return glIsProgram(s->program)==GL_TRUE;
}
static void gl_term(void)
{
gl4.vbo.geometry = 0;
glDeleteProgram(gl4.modvol_shader.program);
glDeleteBuffers(1, &gl4.vbo.geometry);
glDeleteBuffers(1, &gl4.vbo.modvols);
glDeleteBuffers(1, &gl4.vbo.idxs);
glDeleteBuffers(1, &gl4.vbo.idxs2);
glDeleteBuffers(1, &gl4.vbo.tr_poly_params);
for (auto it = gl4.shaders.begin(); it != gl4.shaders.end(); it++)
{
if (it->second->program != -1)
glDeleteProgram(it->second->program);
delete it->second;
}
gl4.shaders.clear();
}
static bool gl_create_resources()
{
if (gl4.vbo.geometry != 0)
@ -579,6 +574,8 @@ static bool gles_init()
}
printf("Per-pixel sorting enabled\n");
glcache.DisableCache();
if (!gl_create_resources())
return false;
@ -602,6 +599,7 @@ static bool gles_init()
u32 dst[16];
UpscalexBRZ(2, src, dst, 2, 2, false);
}
fog_needs_update = true;
return true;
}
@ -822,9 +820,6 @@ static bool RenderFrame()
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(struct PolyParam) * pvrrc.global_param_tr.used(), pvrrc.global_param_tr.head(), GL_STATIC_DRAW);
glCheck();
int offs_x=ds2s_offs_x+0.5f;
//this needs to be scaled
//not all scaling affects pixel operations, scale to adjust for that
scale_x *= scissoring_scale_x;
@ -844,7 +839,7 @@ static bool RenderFrame()
if (!is_rtt)
{
// Add x offset for aspect ratio > 4/3
min_x = min_x * dc2s_scale_h + offs_x;
min_x = min_x * dc2s_scale_h + ds2s_offs_x;
// Invert y coordinates when rendering to screen
min_y = screen_height - (min_y + height) * dc2s_scale_h;
width *= dc2s_scale_h;
@ -852,11 +847,13 @@ static bool RenderFrame()
if (ds2s_offs_x > 0)
{
float rounded_offs_x = ds2s_offs_x + 0.5f;
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
glcache.Enable(GL_SCISSOR_TEST);
glScissor(0, 0, ds2s_offs_x, screen_height);
glScissor(0, 0, rounded_offs_x, screen_height);
glClear(GL_COLOR_BUFFER_BIT);
glScissor(screen_width - ds2s_offs_x, 0, ds2s_offs_x, screen_height);
glScissor(screen_width - rounded_offs_x, 0, rounded_offs_x, screen_height);
glClear(GL_COLOR_BUFFER_BIT);
}
}
@ -868,7 +865,7 @@ static bool RenderFrame()
height *= settings.rend.RenderToTextureUpscale;
}
glScissor(min_x, min_y, width, height);
glScissor(min_x + 0.5f, min_y + 0.5f, width + 0.5f, height + 0.5f);
glcache.Enable(GL_SCISSOR_TEST);
}
@ -883,11 +880,8 @@ static bool RenderFrame()
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
DrawFramebuffer(dc_width, dc_height);
gl4DrawFramebuffer(dc_width, dc_height);
}
#if HOST_OS==OS_WINDOWS
//Sleep(40); //to test MT stability
#endif
eglCheck();
@ -934,6 +928,36 @@ struct gl4rend : Renderer
void Term()
{
termABuffer();
if (stencilTexId != 0)
{
glcache.DeleteTextures(1, &stencilTexId);
stencilTexId = 0;
}
if (depthTexId != 0)
{
glcache.DeleteTextures(1, &depthTexId);
depthTexId = 0;
}
if (opaqueTexId != 0)
{
glcache.DeleteTextures(1, &opaqueTexId);
opaqueTexId = 0;
}
if (depthSaveTexId != 0)
{
glcache.DeleteTextures(1, &depthSaveTexId);
depthSaveTexId = 0;
}
if (KillTex)
{
void killtex();
killtex();
printf("Texture cache cleared\n");
}
CollectCleanup();
gl_term();
}
bool Process(TA_context* ctx) { return ProcessFrame(ctx); }

View File

@ -9,16 +9,18 @@ public:
GLCache() { Reset(); }
void BindTexture(GLenum target, GLuint texture) {
if (target == GL_TEXTURE_2D && texture != _texture) {
if (target == GL_TEXTURE_2D && !_disable_cache) {
if (texture != _texture) {
glBindTexture(target, texture);
_texture = texture;
}
}
else
glBindTexture(target, texture);
}
void BlendFunc(GLenum sfactor, GLenum dfactor) {
if (sfactor != _src_blend_factor || dfactor != _dst_blend_factor) {
if (sfactor != _src_blend_factor || dfactor != _dst_blend_factor || _disable_cache) {
_src_blend_factor = sfactor;
_dst_blend_factor = dfactor;
glBlendFunc(sfactor, dfactor);
@ -26,7 +28,7 @@ public:
}
void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
if (red != _clear_r || green != _clear_g || blue != _clear_b || alpha != _clear_a) {
if (red != _clear_r || green != _clear_g || blue != _clear_b || alpha != _clear_a || _disable_cache) {
_clear_r = red;
_clear_g = green;
_clear_b = blue;
@ -36,15 +38,16 @@ public:
}
void CullFace(GLenum mode) {
if (mode != _cull_face) {
if (mode != _cull_face || _disable_cache) {
_cull_face = mode;
glCullFace(mode);
}
}
void DeleteTextures(GLsizei n, const GLuint *textures) {
for (int i = 0; i < n; i++) {
_texture_params.erase(textures[i]);
for (int i = 0; i < n; i++)
{
_texture_params.erase(textures[i]);
if (textures[i] == _texture)
_texture = 0;
}
@ -52,61 +55,64 @@ public:
}
void DepthFunc(GLenum func) {
if (func != _depth_func) {
if (func != _depth_func || _disable_cache) {
_depth_func = func;
glDepthFunc(func);
}
}
void DepthMask(GLboolean flag) {
if (flag != _depth_mask) {
if (flag != _depth_mask || _disable_cache) {
_depth_mask = flag;
glDepthMask(flag);
}
}
void Enable(GLenum cap) {
setCapability(cap, true);
setCapability(cap, GL_TRUE);
}
void Disable(GLenum cap) {
setCapability(cap, false);
setCapability(cap, GL_FALSE);
}
void UseProgram(GLuint program) {
if (program != _program) {
if (program != _program || _disable_cache) {
_program = program;
glUseProgram(program);
}
}
void StencilFunc(GLenum func, GLint ref, GLuint mask) {
if (_stencil_func != func || _stencil_ref != ref || _stencil_fmask != mask) {
if (_stencil_func != func || _stencil_ref != ref || _stencil_fmask != mask || _disable_cache) {
_stencil_func = func;
_stencil_ref = ref;
_stencil_fmask = mask;
glStencilFunc(func, ref, mask);
}
}
void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) {
if (_stencil_sfail != sfail ||_stencil_dpfail != dpfail || _stencil_dppass != dppass) {
if (_stencil_sfail != sfail ||_stencil_dpfail != dpfail || _stencil_dppass != dppass || _disable_cache) {
_stencil_sfail = sfail;
_stencil_dpfail = dpfail;
_stencil_dppass = dppass;
glStencilOp(sfail, dpfail, dppass);
}
}
void StencilMask(GLuint mask) {
if (_stencil_mask != mask) {
if (_stencil_mask != mask || _disable_cache) {
_stencil_mask = mask;
glStencilMask(mask);
}
}
void TexParameteri(GLenum target, GLenum pname, GLint param) {
if (target == GL_TEXTURE_2D)
void TexParameteri(GLenum target, GLenum pname, GLint param)
{
if (target == GL_TEXTURE_2D && !_disable_cache)
{
TextureParameters &cur_params = _texture_params[_texture];
switch (pname) {
@ -144,36 +150,43 @@ public:
}
void Reset() {
_texture = 0;
_src_blend_factor = GL_ONE;
_dst_blend_factor = GL_ZERO;
_clear_r = 0.f;
_clear_g = 0.f;
_clear_b = 0.f;
_clear_a = 0.f;
_en_blend = false;
_en_cull_face = false;
_en_depth_test = false;
_en_scissor_test = false;
_en_stencil_test = false;
_cull_face = GL_BACK;
_depth_func = GL_LESS;
_depth_mask = true;
_program = 0;
_texture = 0xFFFFFFFFu;
_src_blend_factor = 0xFFFFFFFFu;
_dst_blend_factor = 0xFFFFFFFFu;
_clear_r = -1.f;
_clear_g = -1.f;
_clear_b = -1.f;
_clear_a = -1.f;
_en_blend = 0xFF;
_en_cull_face = 0xFF;
_en_depth_test = 0xFF;
_en_scissor_test = 0xFF;
_en_stencil_test = 0xFF;
_cull_face = 0xFFFFFFFFu;
_depth_func = 0xFFFFFFFFu;
_depth_mask = 0xFF;
_program = 0xFFFFFFFFu;
_texture_cache_size = 0;
_stencil_func = GL_ALWAYS;
_stencil_ref = 0;
_stencil_fmask = ~0;
_stencil_sfail = GL_KEEP;
_stencil_dpfail = GL_KEEP;
_stencil_dppass = GL_KEEP;
_stencil_mask = ~0;
_stencil_func = 0xFFFFFFFFu;
_stencil_ref = -1;
_stencil_fmask = 0;
_stencil_sfail = 0xFFFFFFFFu;
_stencil_dpfail = 0xFFFFFFFFu;
_stencil_dppass = 0xFFFFFFFFu;
_stencil_mask = 0;
}
void DisableCache() { _disable_cache = true; }
void EnableCache()
{
_disable_cache = true;
Reset();
}
private:
class TextureParameters {
public:
TextureParameters() : _min_filter(GL_NEAREST_MIPMAP_LINEAR), _mag_filter(GL_LINEAR), _wrap_s(GL_REPEAT), _wrap_t(GL_REPEAT) {}
TextureParameters() : _min_filter(0xFFFFFFFFu), _mag_filter(0xFFFFFFFFu), _wrap_s(0xFFFFFFFFu), _wrap_t(0xFFFFFFFFu) {}
GLenum _min_filter;
GLenum _mag_filter;
@ -181,8 +194,8 @@ private:
GLenum _wrap_t;
};
void setCapability(GLenum cap, bool value) {
bool *pCap = NULL;
void setCapability(GLenum cap, GLboolean value) {
GLboolean *pCap = NULL;
switch (cap) {
case GL_BLEND:
pCap = &_en_blend;
@ -201,7 +214,7 @@ private:
break;
}
if (pCap != NULL) {
if (*pCap == value)
if (*pCap == value && !_disable_cache)
return;
*pCap = value;
}
@ -211,6 +224,8 @@ private:
glDisable(cap);
}
GLuint _array_buffer;
GLuint _element_array_buffer;
GLuint _texture;
GLenum _src_blend_factor;
GLenum _dst_blend_factor;
@ -218,11 +233,11 @@ private:
GLclampf _clear_g;
GLclampf _clear_b;
GLclampf _clear_a;
bool _en_blend;
bool _en_cull_face;
bool _en_depth_test;
bool _en_scissor_test;
bool _en_stencil_test;
GLboolean _en_blend;
GLboolean _en_cull_face;
GLboolean _en_depth_test;
GLboolean _en_scissor_test;
GLboolean _en_stencil_test;
GLenum _cull_face;
GLenum _depth_func;
GLboolean _depth_mask;
@ -237,6 +252,7 @@ private:
GLuint _texture_ids[TEXTURE_ID_CACHE_SIZE];
GLuint _texture_cache_size;
std::map<GLuint, TextureParameters> _texture_params;
bool _disable_cache;
};
extern GLCache glcache;

View File

@ -1087,6 +1087,8 @@ bool gles_init()
(void*)libPvr_GetRenderSurface()))
return false;
glcache.EnableCache();
if (!gl_create_resources())
return false;
@ -1119,6 +1121,7 @@ bool gles_init()
u32 dst[16];
UpscalexBRZ(2, src, dst, 2, 2, false);
}
fog_needs_update = true;
return true;
}
@ -1905,7 +1908,7 @@ bool RenderFrame()
if (!is_rtt)
{
// Add x offset for aspect ratio > 4/3
min_x = min_x * dc2s_scale_h + offs_x;
min_x = min_x * dc2s_scale_h + ds2s_offs_x;
// Invert y coordinates when rendering to screen
min_y = screen_height - (min_y + height) * dc2s_scale_h;
width *= dc2s_scale_h;
@ -1913,11 +1916,13 @@ bool RenderFrame()
if (ds2s_offs_x > 0)
{
float rounded_offs_x = ds2s_offs_x + 0.5f;
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
glcache.Enable(GL_SCISSOR_TEST);
glScissor(0, 0, offs_x, screen_height);
glScissor(0, 0, rounded_offs_x, screen_height);
glClear(GL_COLOR_BUFFER_BIT);
glScissor(screen_width - offs_x, 0, offs_x, screen_height);
glScissor(screen_width - rounded_offs_x, 0, rounded_offs_x, screen_height);
glClear(GL_COLOR_BUFFER_BIT);
}
}
@ -1929,7 +1934,7 @@ bool RenderFrame()
height *= settings.rend.RenderToTextureUpscale;
}
glScissor(min_x, min_y, width, height);
glScissor(min_x + 0.5f, min_y + 0.5f, width + 0.5f, height + 0.5f);
glcache.Enable(GL_SCISSOR_TEST);
}