Use OpenGL state cache. Allocate texture ids in bulk. Avoid modifier

volumes entirely when not needed.
This commit is contained in:
Flyinghead 2018-05-15 15:22:26 +02:00
parent 0ccd8ed5ca
commit de046c4620
4 changed files with 389 additions and 227 deletions

255
core/rend/gles/glcache.h Normal file
View File

@ -0,0 +1,255 @@
#pragma once
#include "gles.h"
#define TEXTURE_ID_CACHE_SIZE 32
class GLCache {
public:
GLCache() { Reset(); }
void BindBuffer(GLenum target, GLuint buffer) {
switch (target) {
case GL_ARRAY_BUFFER:
if (_array_buffer != buffer) {
glBindBuffer(target, buffer);
_array_buffer = buffer;
}
case GL_ELEMENT_ARRAY_BUFFER:
if (_element_array_buffer != buffer) {
glBindBuffer(target, buffer);
_element_array_buffer = buffer;
}
}
}
void BindTexture(GLenum target, GLuint texture) {
if (target == GL_TEXTURE_2D && 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) {
_src_blend_factor = sfactor;
_dst_blend_factor = dfactor;
glBlendFunc(sfactor, dfactor);
}
}
void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
if (red != _clear_r || green != _clear_g || blue != _clear_b || alpha != _clear_a) {
glClearColor(red, green, blue, alpha);
_clear_r = red;
_clear_g = green;
_clear_b = blue;
_clear_a = alpha;
}
}
void CullFace(GLenum mode) {
if (mode != _cull_face) {
_cull_face = mode;
glCullFace(mode);
}
}
void DeleteBuffers(GLsizei n, const GLuint *buffers) {
for (int i = 0; i < n; i++) {
if (buffers[i] == _array_buffer)
_array_buffer = 0;
if (buffers[i] == _element_array_buffer)
_element_array_buffer = 0;
}
glDeleteBuffers(n, buffers);
}
void DeleteTextures(GLsizei n, const GLuint *textures) {
for (int i = 0; i < n; i++) {
if (textures[i] == _texture) {
_texture = 0;
break;
}
}
glDeleteTextures(n, textures);
}
void DepthFunc(GLenum func) {
if (func != _depth_func) {
_depth_func = func;
glDepthFunc(func);
}
}
void DepthMask(GLboolean flag) {
if (flag != _depth_mask) {
_depth_mask = flag;
glDepthMask(flag);
}
}
void Enable(GLenum cap) {
switch (cap) {
case GL_BLEND:
if (_en_blend)
return;
_en_blend = true;
break;
case GL_CULL_FACE:
if (_en_cull_face)
return;
_en_cull_face = true;
break;
case GL_DEPTH_TEST:
if (_en_depth_test)
return;
_en_depth_test = true;
break;
case GL_SCISSOR_TEST:
if (_en_scissor_test)
return;
_en_scissor_test = true;
break;
case GL_STENCIL_TEST:
if (_en_stencil_test)
return;
_en_stencil_test = true;
break;
}
glEnable(cap);
}
void Disable(GLenum cap) {
switch (cap) {
case GL_BLEND:
if (!_en_blend)
return;
_en_blend = false;
break;
case GL_CULL_FACE:
if (!_en_cull_face)
return;
_en_cull_face = false;
break;
case GL_DEPTH_TEST:
if (!_en_depth_test)
return;
_en_depth_test = false;
break;
case GL_SCISSOR_TEST:
if (!_en_scissor_test)
return;
_en_scissor_test = false;
break;
case GL_STENCIL_TEST:
if (!_en_stencil_test)
return;
_en_stencil_test = false;
break;
}
glDisable(cap);
}
void UseProgram(GLuint program) {
if (program != _program) {
_program = program;
glUseProgram(program);
}
}
void StencilFunc(GLenum func, GLint ref, GLuint mask) {
if (_stencil_func != func || _stencil_ref != ref || _stencil_fmask != mask) {
_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) {
_stencil_sfail = sfail;
_stencil_dpfail = dpfail;
_stencil_dppass = dppass;
glStencilOp(sfail, dpfail, dppass);
}
}
void StencilMask(GLuint mask) {
if (_stencil_mask != mask) {
_stencil_mask = mask;
glStencilMask(mask);
}
}
GLuint GenTexture() {
if (_texture_cache_size == 0) {
_texture_cache_size = TEXTURE_ID_CACHE_SIZE;
glGenTextures(_texture_cache_size, _texture_ids);
}
return _texture_ids[--_texture_cache_size];
}
void Reset() {
_array_buffer = 0;
_element_array_buffer = 0;
_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_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;
}
private:
GLuint _array_buffer;
GLuint _element_array_buffer;
GLuint _texture;
GLenum _src_blend_factor;
GLenum _dst_blend_factor;
GLclampf _clear_r;
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;
GLenum _cull_face;
GLenum _depth_func;
GLboolean _depth_mask;
GLuint _program;
GLenum _stencil_func;
GLint _stencil_ref;
GLuint _stencil_fmask;
GLenum _stencil_sfail;
GLenum _stencil_dpfail;
GLenum _stencil_dppass;
GLuint _stencil_mask;
GLuint _texture_ids[TEXTURE_ID_CACHE_SIZE];
GLuint _texture_cache_size;
};
extern GLCache glcache;

View File

@ -1,4 +1,4 @@
#include "gles.h"
#include "glcache.h"
#include "rend/rend.h"
#include <algorithm>
@ -12,12 +12,6 @@ Takes vertex, textures and renders to the currently set up target
*/
//Uncomment this to disable the stencil work around
//Seems like there's a bug either on the wrapper, or nvogl making
//stencil not work properly (requiring some double calls to get proper results)
#define NO_STENCIL_WORKAROUND
const static u32 CullMode[]=
{
@ -83,39 +77,17 @@ u32 gcflip;
static struct
{
TSP tsp;
//TCW tcw;
PCW pcw;
ISP_TSP isp;
u32 clipmode;
//u32 texture_enabled;
u32 stencil_modvol_on;
u32 program;
GLuint texture;
void Reset(const PolyParam* gp)
{
program=~0;
texture=~0;
tsp.full = ~gp->tsp.full;
//tcw.full = ~gp->tcw.full;
pcw.full = ~gp->pcw.full;
isp.full = ~gp->isp.full;
clipmode=0xFFFFFFFF;
// texture_enabled=~gp->pcw.Texture;
stencil_modvol_on=false;
}
} cache;
s32 SetTileClip(u32 val, bool set)
{
/*
if (set)
{
if (cache.clipmode==val)
return clip_mode;
cache.clipmode=val;
}*/
u32 clipmode=val>>28;
s32 clip_mode;
if (clipmode<2)
@ -168,12 +140,12 @@ void SetCull(u32 CulliMode)
{
if (CullMode[CulliMode]==GL_NONE)
{
glDisable(GL_CULL_FACE);
glcache.Disable(GL_CULL_FACE);
}
else
{
glEnable(GL_CULL_FACE);
glCullFace(CullMode[CulliMode]); //GL_FRONT/GL_BACK, ...
glcache.Enable(GL_CULL_FACE);
glcache.CullFace(CullMode[CulliMode]); //GL_FRONT/GL_BACK, ...
}
}
@ -181,57 +153,52 @@ template <u32 Type, bool SortingEnabled>
__forceinline
void SetGPState(const PolyParam* gp,u32 cflip=0)
{
//has to preserve cache_tsp/cache_isp
//can freely use cache_tcw
CurrentShader=&gl.pogram_table[GetProgramID(Type==ListType_Punch_Through?1:0,SetTileClip(gp->tileclip,false)+1,gp->pcw.Texture,gp->tsp.UseAlpha,gp->tsp.IgnoreTexA,gp->tsp.ShadInstr,gp->pcw.Offset,gp->tsp.FogCtrl)];
CurrentShader = &gl.pogram_table[
GetProgramID(Type == ListType_Punch_Through ? 1 : 0,
SetTileClip(gp->tileclip, false) + 1,
gp->pcw.Texture,
gp->tsp.UseAlpha,
gp->tsp.IgnoreTexA,
gp->tsp.ShadInstr,
gp->pcw.Offset,
gp->tsp.FogCtrl)];
if (CurrentShader->program == -1)
CompilePipelineShader(CurrentShader);
if (CurrentShader->program != cache.program)
{
cache.program=CurrentShader->program;
glUseProgram(CurrentShader->program);
}
glcache.UseProgram(CurrentShader->program);
SetTileClip(gp->tileclip,true);
//This for some reason doesn't work properly
//So, shadow bit emulation is disabled.
//This bit normally control which pixels are affected
//This bit control which pixels are affected
//by modvols
#ifdef NO_STENCIL_WORKAROUND
const u32 stencil=(gp->pcw.Shadow!=0)?0x80:0x0;
#else
//force everything to be shadowed
const u32 stencil=0x80;
#endif
if (cache.stencil_modvol_on!=stencil)
{
cache.stencil_modvol_on=stencil;
glStencilFunc(GL_ALWAYS,stencil,stencil);
}
glcache.StencilFunc(GL_ALWAYS,stencil,stencil);
bool texture_changed = false;
// FIXME the same gl texture id can be used with different parameters (filtering, clamping, etc.) This is not handled here
if (gp->texid != cache.texture)
{
cache.texture=gp->texid;
if (gp->texid != -1) {
//verify(glIsTexture(gp->texid));
glBindTexture(GL_TEXTURE_2D, gp->texid);
glcache.BindTexture(GL_TEXTURE_2D, gp->texid);
texture_changed = true;
}
}
if (Type==ListType_Translucent)
{
glcache.Enable(GL_BLEND);
glcache.BlendFunc(SrcBlendGL[gp->tsp.SrcInstr],DstBlendGL[gp->tsp.DstInstr]);
}
else
glcache.Disable(GL_BLEND);
if (gp->tsp.full != cache.tsp.full || texture_changed)
{
cache.tsp=gp->tsp;
if (Type==ListType_Translucent)
{
glBlendFunc(SrcBlendGL[gp->tsp.SrcInstr],DstBlendGL[gp->tsp.DstInstr]);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (gp->tsp.ClampU ? GL_CLAMP_TO_EDGE : (gp->tsp.FlipU ? GL_MIRRORED_REPEAT : GL_REPEAT))) ;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (gp->tsp.ClampV ? GL_CLAMP_TO_EDGE : (gp->tsp.FlipV ? GL_MIRRORED_REPEAT : GL_REPEAT))) ;
@ -256,22 +223,18 @@ __forceinline
//gcflip is global clip flip, needed for when rendering to texture due to mirrored Y direction
SetCull(gp->isp.CullMode^cflip^gcflip);
if (gp->isp.full!= cache.isp.full)
{
cache.isp.full=gp->isp.full;
//set Z mode, only if required
if (!(Type==ListType_Punch_Through || (Type==ListType_Translucent && SortingEnabled)))
glDepthFunc(Zfunction[gp->isp.DepthMode]);
//set Z mode, only if required
if (Type == ListType_Punch_Through || (Type == ListType_Translucent && SortingEnabled))
glcache.DepthFunc(GL_GEQUAL);
else
glcache.DepthFunc(Zfunction[gp->isp.DepthMode]);
#if TRIG_SORT
if (SortingEnabled)
glDepthMask(GL_FALSE);
else
if (SortingEnabled)
glcache.DepthMask(GL_FALSE);
else
#endif
glDepthMask(!gp->isp.ZWriteDis);
}
glcache.DepthMask(!gp->isp.ZWriteDis);
}
template <u32 Type, bool SortingEnabled>
@ -285,23 +248,11 @@ void DrawList(const List<PolyParam>& gply, int first, int count)
//we want at least 1 PParam
//reset the cache state
cache.Reset(params);
//set some 'global' modes for all primitives
//Z funct. can be fixed on these combinations, avoid setting it all the time
if (Type==ListType_Punch_Through || (Type==ListType_Translucent && SortingEnabled))
glDepthFunc(Zfunction[6]);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS,0,0);
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
#ifndef NO_STENCIL_WORKAROUND
//This looks like a driver bug
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
#endif
glcache.Enable(GL_STENCIL_TEST);
glcache.StencilFunc(GL_ALWAYS,0,0);
glcache.StencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
while(count-->0)
{
@ -359,7 +310,7 @@ void SortPParams(int first, int count)
pp++;
}
std::stable_sort(pvrrc.global_param_tr.head(),pvrrc.global_param_tr.head()+pvrrc.global_param_tr.used());
std::stable_sort(pvrrc.global_param_tr.head() + first, pvrrc.global_param_tr.head() + first + count);
}
Vertex* vtx_sort_base;
@ -578,7 +529,7 @@ void GenSorted(int first, int count)
v1=&vtx[1];
v2=&vtx[2];
}
#if 0
if (settings.pvr.subdivide_transp)
{
u32 tess_x=(max3(v0->x,v1->x,v2->x)-min3(v0->x,v1->x,v2->x))/32;
@ -652,6 +603,7 @@ void GenSorted(int first, int count)
}
}
else
#endif
{
fill_id(lst[pfsti].id,v0,v1,v2,vtx_base);
lst[pfsti].pid= ppid ;
@ -767,7 +719,7 @@ void GenSorted(int first, int count)
if (pidx_sort.size())
{
//Bind and upload sorted index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs2); glCheck();
glcache.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs2); glCheck();
glBufferData(GL_ELEMENT_ARRAY_BUFFER,vidx_sort.size()*2,&vidx_sort[0],GL_STREAM_DRAW);
if (tess_gen) printf("Generated %.2fK Triangles !\n",tess_gen/1000.0);
@ -779,26 +731,16 @@ void DrawSorted()
//if any drawing commands, draw them
if (pidx_sort.size())
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs2); glCheck();
glcache.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs2); glCheck();
u32 count=pidx_sort.size();
{
cache.Reset(pidx_sort[0].ppid);
//set some 'global' modes for all primitives
//Z sorting is fixed for .. sorted stuff
glDepthFunc(Zfunction[6]);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS,0,0);
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
#ifndef NO_STENCIL_WORKAROUND
//This looks like a driver bug
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
#endif
glcache.Enable(GL_STENCIL_TEST);
glcache.StencilFunc(GL_ALWAYS,0,0);
glcache.StencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
for (u32 p=0; p<count; p++)
{
@ -857,21 +799,14 @@ void SetMVS_Mode(u32 mv_mode,ISP_Modvol ispc)
if (mv_mode==0) //normal trigs
{
//set states
glEnable(GL_DEPTH_TEST);
glcache.Enable(GL_DEPTH_TEST);
//write only bit 1
glStencilMask(2);
glcache.StencilMask(2);
//no stencil testing
glStencilFunc(GL_ALWAYS,0,2);
glcache.StencilFunc(GL_ALWAYS,0,2);
//count the number of pixels in front of the Z buffer (xor zpass)
glStencilOp(GL_KEEP,GL_KEEP,GL_INVERT);
glcache.StencilOp(GL_KEEP,GL_KEEP,GL_INVERT);
//zfail would be better when camera is in the volume but it doesn't work for open volumes
//glStencilOp(GL_KEEP, GL_INVERT, GL_KEEP);
#ifndef NO_STENCIL_WORKAROUND
//this needs to be done .. twice ? looks like
//a bug somewhere, on gles/nvgl ?
glStencilOp(GL_KEEP,GL_KEEP,GL_INVERT);
#endif
//Cull mode needs to be set
SetCull(ispc.CullMode);
}
@ -883,7 +818,7 @@ void SetMVS_Mode(u32 mv_mode,ISP_Modvol ispc)
//common states
//no depth test
glDisable(GL_DEPTH_TEST);
glcache.Disable(GL_DEPTH_TEST);
if (mv_mode==1)
{
@ -894,14 +829,10 @@ void SetMVS_Mode(u32 mv_mode,ISP_Modvol ispc)
//1 : 1 : 01
//write bits 1:0
glStencilMask(3);
glcache.StencilMask(3);
//if (1<=st) st=1; else st=0;
glStencilFunc(GL_LEQUAL,1,3);
glStencilOp(GL_ZERO,GL_ZERO,GL_REPLACE);
#ifndef NO_STENCIL_WORKAROUND
//Look @ comment above -- this looks like a driver bug
glStencilOp(GL_ZERO,GL_ZERO,GL_REPLACE);
#endif
glcache.StencilFunc(GL_LEQUAL,1,3);
glcache.StencilOp(GL_ZERO,GL_ZERO,GL_REPLACE);
/*
//if !=0 -> set to 10
@ -926,14 +857,10 @@ void SetMVS_Mode(u32 mv_mode,ISP_Modvol ispc)
//1 : 1 : 01
// Write to bit 0
glStencilMask(1); // FIXME bit 1 is not reset. Need other pass
glcache.StencilMask(1); // FIXME bit 1 is not reset. Need other pass
//if (3==st) st=1; else st=0; //can't be done with a single pass
glStencilFunc(GL_EQUAL, 3, 3);
glStencilOp(GL_ZERO,GL_KEEP,GL_REPLACE);
#ifndef NO_STENCIL_WORKAROUND
//Look @ comment above -- this looks like a driver bug
glStencilOp(GL_ZERO,GL_KEEP,GL_REPLACE);
#endif
glcache.StencilFunc(GL_EQUAL, 3, 3);
glcache.StencilOp(GL_ZERO,GL_KEEP,GL_REPLACE);
}
}
}
@ -945,8 +872,8 @@ void SetupMainVBO()
glBindVertexArray(gl.vbo.vao);
#endif
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.geometry); glCheck();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs); glCheck();
glcache.BindBuffer(GL_ARRAY_BUFFER, gl.vbo.geometry); glCheck();
glcache.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs); glCheck();
//setup vertex buffers attrib pointers
glEnableVertexAttribArray(VERTEX_POS_ARRAY); glCheck();
@ -968,7 +895,7 @@ void SetupModvolVBO()
glBindVertexArray(gl.vbo.vao);
#endif
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.modvols); glCheck();
glcache.BindBuffer(GL_ARRAY_BUFFER, gl.vbo.modvols); glCheck();
//setup vertex buffers attrib pointers
glEnableVertexAttribArray(VERTEX_POS_ARRAY); glCheck();
@ -980,19 +907,19 @@ void SetupModvolVBO()
}
void DrawModVols(int first, int count)
{
if (count == 0 /*|| GetAsyncKeyState(VK_F4)*/)
if (count == 0 || pvrrc.modtrig.used() == 0)
return;
SetupModvolVBO();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glcache.Enable(GL_BLEND);
glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(gl.modvol_shader.program);
glcache.UseProgram(gl.modvol_shader.program);
glUniform1f(gl.modvol_shader.sp_ShaderColor,0.5f);
glDepthMask(GL_FALSE);
glDepthFunc(GL_GREATER);
glcache.DepthMask(GL_FALSE);
glcache.DepthFunc(GL_GREATER);
if(0 /*|| GetAsyncKeyState(VK_F5)*/ )
{
@ -1024,14 +951,10 @@ void DrawModVols(int first, int count)
if ( 0 /* || GetAsyncKeyState(VK_F6)*/ )
{
//simple single level stencil
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS,0x1,0x1);
glStencilOp(GL_KEEP,GL_KEEP,GL_INVERT);
#ifndef NO_STENCIL_WORKAROUND
//looks like a driver bug
glStencilOp(GL_KEEP,GL_KEEP,GL_INVERT);
#endif
glStencilMask(0x1);
glcache.Enable(GL_STENCIL_TEST);
glcache.StencilFunc(GL_ALWAYS,0x1,0x1);
glcache.StencilOp(GL_KEEP,GL_KEEP,GL_INVERT);
glcache.StencilMask(0x1);
SetCull(0);
glDrawArrays(GL_TRIANGLES, first, count * 3);
}
@ -1092,22 +1015,18 @@ void DrawModVols(int first, int count)
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
//black out any stencil with '1'
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glcache.Enable(GL_BLEND);
glcache.BlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL,0x81,0x81); //only pixels that are Modvol enabled, and in area 1
glcache.Enable(GL_STENCIL_TEST);
glcache.StencilFunc(GL_EQUAL,0x81,0x81); //only pixels that are Modvol enabled, and in area 1
//clear the stencil result bit
glStencilMask(0x3); //write to lsb
glStencilOp(GL_ZERO,GL_ZERO,GL_ZERO);
#ifndef NO_STENCIL_WORKAROUND
//looks like a driver bug ?
glStencilOp(GL_ZERO,GL_ZERO,GL_ZERO);
#endif
glcache.StencilMask(0x3); //write to lsb
glcache.StencilOp(GL_ZERO,GL_ZERO,GL_ZERO);
//don't do depth testing
glDisable(GL_DEPTH_TEST);
glcache.Disable(GL_DEPTH_TEST);
SetupMainVBO();
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
@ -1118,10 +1037,7 @@ void DrawModVols(int first, int count)
}
//restore states
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glcache.Enable(GL_DEPTH_TEST);
}
void DrawStrips()
@ -1137,38 +1053,25 @@ void DrawStrips()
const RenderPass& current_pass = pvrrc.render_passes.head()[render_pass];
//initial state
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glcache.Enable(GL_DEPTH_TEST);
glClearDepthf(0.f);
glDepthMask(GL_TRUE);
glStencilMask(0xFF);
glcache.DepthMask(GL_TRUE);
glcache.StencilMask(0xFF);
glClear(GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glCheck();
//Opaque
//Nothing extra needs to be setup here
/*if (!GetAsyncKeyState(VK_F1))*/
DrawList<ListType_Opaque,false>(pvrrc.global_param_op, previous_pass.op_count, current_pass.op_count - previous_pass.op_count);
// Modifier volumes
DrawModVols(previous_pass.mvo_count, current_pass.mvo_count);
//Alpha tested
//setup alpha test state
/*if (!GetAsyncKeyState(VK_F2))*/
DrawList<ListType_Punch_Through,false>(pvrrc.global_param_pt, previous_pass.pt_count, current_pass.pt_count - previous_pass.pt_count);
//Alpha blended
//Setup blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/*if (!GetAsyncKeyState(VK_F3))*/
{
/*
if (UsingAutoSort())
SortRendPolyParamList(pvrrc.global_param_tr);
else
*/
if (pvrrc.isAutoSort)
GenSorted(previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);

View File

@ -1,5 +1,5 @@
#include <math.h>
#include "gles.h"
#include "glcache.h"
#include "rend/TexCache.h"
#include "cfg/cfg.h"
@ -383,7 +383,7 @@ void main() \n\
" FRAGCOL "=vtx_base*" TEXLOOKUP "(tex,uv.st); \n\n\
}";
GLCache glcache;
gl_ctx gl;
int screen_width;
@ -677,12 +677,12 @@ int screen_height;
#if 0
//handy to debug really stupid render-not-working issues ...
glClearColor( 0, 0.5, 1, 1 );
glcache.ClearColor( 0, 0.5, 1, 1 );
glClear( GL_COLOR_BUFFER_BIT );
glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget());
glClearColor ( 1, 0.5, 0, 1 );
glcache.ClearColor ( 1, 0.5, 0, 1 );
glClear ( GL_COLOR_BUFFER_BIT );
glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget());
#endif
@ -804,7 +804,7 @@ GLuint gl_CompileAndLink(const char* VertexShader, const char* FragmentShader)
glDeleteShader(vs);
glDeleteShader(ps);
glUseProgram(program);
glcache.UseProgram(program);
verify(glIsProgram(program));
@ -1007,6 +1007,11 @@ bool gles_init()
#endif
#endif
//clean up the buffer
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
gl_swap();
return true;
}
@ -1032,10 +1037,10 @@ void tryfit(float* x,float* y)
//Add many samples for first and last value (fog-in, fog-out -> important)
if (i>0 && y[i]!=1 && y[i-1]==1)
rep=1000;
rep=10000;
if (i<127 && y[i]!=0 && y[i+1]==0)
rep=1000;
rep=10000;
for (int j=0;j<rep;j++)
{
@ -1369,8 +1374,8 @@ void OSD_DRAW()
verify(glIsProgram(gl.OSD_SHADER.program));
glBindTexture(GL_TEXTURE_2D,osd_tex);
glUseProgram(gl.OSD_SHADER.program);
glcache.BindTexture(GL_TEXTURE_2D, osd_tex);
glcache.UseProgram(gl.OSD_SHADER.program);
//reset rendering scale
/*
@ -1389,15 +1394,15 @@ void OSD_DRAW()
glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
*/
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glcache.Enable(GL_BLEND);
glcache.Disable(GL_DEPTH_TEST);
glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
glDepthFunc(GL_ALWAYS);
glcache.DepthMask(false);
glcache.DepthFunc(GL_ALWAYS);
glDisable(GL_CULL_FACE);
glDisable(GL_SCISSOR_TEST);
glcache.Disable(GL_CULL_FACE);
glcache.Disable(GL_SCISSOR_TEST);
int dfa=osd_count/4;
@ -1419,20 +1424,20 @@ void OSD_DRAW()
float ds2s_offs_x=(screen_width-dc2s_scale_h*640)/2;
glBindTexture(GL_TEXTURE_2D,osd_font);
glUseProgram(gl.OSD_SHADER.program);
glcache.BindTexture(GL_TEXTURE_2D,osd_font);
glcache.UseProgram(gl.OSD_SHADER.program);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glcache.Enable(GL_BLEND);
glcache.Disable(GL_DEPTH_TEST);
glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
glDepthFunc(GL_ALWAYS);
glcache.DepthMask(false);
glcache.DepthFunc(GL_ALWAYS);
glDisable(GL_CULL_FACE);
glDisable(GL_SCISSOR_TEST);
glcache.Disable(GL_CULL_FACE);
glcache.Disable(GL_SCISSOR_TEST);
int dfa=osd_count/4;
@ -1684,7 +1689,7 @@ bool RenderFrame()
tryfit(xvals,yvals);
}
glUseProgram(gl.modvol_shader.program);
glcache.UseProgram(gl.modvol_shader.program);
glUniform4fv( gl.modvol_shader.scale, 1, ShaderUniforms.scale_coefs);
glUniform4fv( gl.modvol_shader.depth_scale, 1, ShaderUniforms.depth_coefs);
@ -1692,7 +1697,7 @@ bool RenderFrame()
GLfloat td[4]={0.5,0,0,0};
glUseProgram(gl.OSD_SHADER.program);
glcache.UseProgram(gl.OSD_SHADER.program);
glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
glUniform4fv( gl.OSD_SHADER.depth_scale, 1, td);
@ -1704,7 +1709,7 @@ bool RenderFrame()
if (s->program == -1)
continue;
glUseProgram(s->program);
glcache.UseProgram(s->program);
ShaderUniforms.Set(s);
}
@ -1765,18 +1770,18 @@ bool RenderFrame()
//Color is cleared by the bgp
if (wide_screen_on)
glClearColor(pvrrc.verts.head()->col[2]/255.0f,pvrrc.verts.head()->col[1]/255.0f,pvrrc.verts.head()->col[0]/255.0f,1.0f);
glcache.ClearColor(pvrrc.verts.head()->col[2]/255.0f,pvrrc.verts.head()->col[1]/255.0f,pvrrc.verts.head()->col[0]/255.0f,1.0f);
else
glClearColor(0,0,0,1.0f);
glcache.ClearColor(0,0,0,1.0f);
glDisable(GL_SCISSOR_TEST);
glcache.Disable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT); glCheck();
//move vertex to gpu
//Main VBO
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.geometry); glCheck();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs); glCheck();
glcache.BindBuffer(GL_ARRAY_BUFFER, gl.vbo.geometry); glCheck();
glcache.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs); glCheck();
glBufferData(GL_ARRAY_BUFFER,pvrrc.verts.bytes(),pvrrc.verts.head(),GL_STREAM_DRAW); glCheck();
@ -1785,7 +1790,7 @@ bool RenderFrame()
//Modvol VBO
if (pvrrc.modtrig.used())
{
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.modvols); glCheck();
glcache.BindBuffer(GL_ARRAY_BUFFER, gl.vbo.modvols); glCheck();
glBufferData(GL_ARRAY_BUFFER,pvrrc.modtrig.bytes(),pvrrc.modtrig.head(),GL_STREAM_DRAW); glCheck();
}
@ -1808,7 +1813,7 @@ bool RenderFrame()
pvrrc.fb_Y_CLIP.min / scale_y * (is_rtt ? 1 : dc2s_scale_h),
(pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1) / scale_x * (is_rtt ? 1 : dc2s_scale_h),
(pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1) / scale_y * (is_rtt ? 1 : dc2s_scale_h));
glEnable(GL_SCISSOR_TEST);
glcache.Enable(GL_SCISSOR_TEST);
}
//restore scale_x
@ -2023,9 +2028,8 @@ GLuint loadPNG(const string& fname, int &width, int &height)
png_read_image(png_ptr, row_pointers);
//Now generate the OpenGL texture object
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
GLuint texture = glcache.GenTexture();
glcache.BindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, (GLvoid*) image_data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

View File

@ -1,4 +1,4 @@
#include "gles.h"
#include "glcache.h"
#include "rend/TexCache.h"
#include "hw/pvr/pvr_mem.h"
#include "hw/mem/_vmem.h"
@ -176,7 +176,7 @@ struct TextureCacheData
{
//ask GL for texture ID
if (isGL) {
glGenTextures(1, &texID);
texID = glcache.GenTexture();
}
else {
texID = 0;
@ -201,7 +201,7 @@ struct TextureCacheData
if (texID) {
//bind texture to set modes
glBindTexture(GL_TEXTURE_2D, texID);
glcache.BindTexture(GL_TEXTURE_2D, texID);
//set texture repeat mode
SetRepeatMode(GL_TEXTURE_WRAP_S, tsp.ClampU, tsp.FlipU); // glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (tsp.ClampU ? GL_CLAMP_TO_EDGE : (tsp.FlipU ? GL_MIRRORED_REPEAT : GL_REPEAT))) ;
@ -348,7 +348,7 @@ struct TextureCacheData
if (texID) {
//upload to OpenGL !
glBindTexture(GL_TEXTURE_2D, texID);
glcache.BindTexture(GL_TEXTURE_2D, texID);
GLuint comps=textype==GL_UNSIGNED_SHORT_5_6_5?GL_RGB:GL_RGBA;
glTexImage2D(GL_TEXTURE_2D, 0,comps , w, h, 0, comps, textype, temp_tex_buffer);
if (tcw.MipMapped && settings.rend.UseMipmaps)
@ -399,7 +399,7 @@ struct TextureCacheData
}
if (texID) {
glDeleteTextures(1, &texID);
glcache.DeleteTextures(1, &texID);
}
if (lock_block)
libCore_vramlock_Unlock_block(lock_block);
@ -428,7 +428,7 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
FBT& rv=fb_rtt;
if (rv.fbo) glDeleteFramebuffers(1,&rv.fbo);
if (rv.tex) glDeleteTextures(1,&rv.tex);
if (rv.tex) glcache.DeleteTextures(1,&rv.tex);
if (rv.depthb) glDeleteRenderbuffers(1,&rv.depthb);
if (rv.stencilb) glDeleteRenderbuffers(1,&rv.stencilb);
@ -466,8 +466,8 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fbw2, fbh2);
// Create a texture for rendering to
glGenTextures(1, &rv.tex);
glBindTexture(GL_TEXTURE_2D, rv.tex);
rv.tex = glcache.GenTexture();
glcache.BindTexture(GL_TEXTURE_2D, rv.tex);
glTexImage2D(GL_TEXTURE_2D, 0, channels, fbw2, fbh2, 0, channels, fmt, 0);
@ -597,7 +597,7 @@ void ReadRTTBuffer() {
//dumpRtTexture(fb_rtt.TexAddr, w, h);
if (w > 1024 || h > 1024) {
glDeleteTextures(1, &fb_rtt.tex);
glcache.DeleteTextures(1, &fb_rtt.tex);
}
else
{
@ -620,7 +620,7 @@ void ReadRTTBuffer() {
TextureCacheData *texture_data = getTextureCacheData(tsp, tcw);
if (texture_data->texID != 0)
glDeleteTextures(1, &texture_data->texID);
glcache.DeleteTextures(1, &texture_data->texID);
else {
texture_data->Create(false);
texture_data->lock_block = libCore_vramlock_Lock(texture_data->sa_tex, texture_data->sa + texture_data->size - 1, texture_data);