Skip to content
This repository has been archived by the owner on Jul 10, 2023. It is now read-only.

Multipass render to texture with options - implemented #1460

Merged
merged 26 commits into from
Feb 19, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f309a59
Render to texture single pass implemented
mar753 Oct 28, 2018
4fd9de5
Added rtt menu options
mar753 Nov 11, 2018
5f19eb7
Rtt menu options are now handled by GLES
mar753 Nov 11, 2018
4d39c10
Build fixes
mar753 Nov 11, 2018
e981dd1
Render to texture full multipass support added; RTT stride textures s…
mar753 Dec 16, 2018
0761ee7
RTT: glReadPixels() functions are now compatible with OpenGL ES 2.0
mar753 Dec 22, 2018
2a7f461
RTT: Synchronous rendering notice dialog added
mar753 Dec 22, 2018
127072e
RTT: Fixed slow rendering of RGBA5551 framebuffer format on Adreno 506
mar753 Dec 22, 2018
7450c24
Minor formatting fixes
mar753 Dec 22, 2018
302bfcd
Merge branch 'master' into mar753/render-to-texture-with-options
mar753 Dec 30, 2018
2aadb3c
RTT: Stencil support added (extension required)
mar753 Jan 7, 2019
10d6f25
Merge branch 'master' into mar753/render-to-texture-with-options
mar753 Jan 11, 2019
27360a1
Lgtm warnings fixed
mar753 Jan 12, 2019
a9affb8
RTT: Stencil support for full OpenGL >= 3.0 added
mar753 Jan 13, 2019
6499a82
RTT: Additional small fixes
mar753 Jan 13, 2019
77d9974
RTT: Performance improved for DC RGB565 and ARGB4444 textures - glRea…
mar753 Jan 14, 2019
86339c3
RTT: Support for OpenGL 2 added
mar753 Jan 18, 2019
88b9deb
Revert "RTT: Support for OpenGL 2 added"
mar753 Jan 20, 2019
b26b120
Merge branch 'master' of https://github.com/reicast/reicast-emulator …
mar753 Feb 6, 2019
a65436c
Handle dynamic resolution change during emulation (LRR mode)
mar753 Feb 8, 2019
8893f97
Handle odd screen resolution (POCOPHONE fix)
mar753 Feb 8, 2019
7ffbd4d
Merge branch 'master' of https://github.com/reicast/reicast-emulator …
mar753 Feb 9, 2019
7869a84
Additional fixes/cleanup
mar753 Feb 9, 2019
8d41881
Vertical scale factor support added - fixes Crazy Taxi pause menu bac…
mar753 Feb 10, 2019
3b951c0
Vertical scale factor support added - typo fix
mar753 Feb 11, 2019
d370fd6
PR requested changes; Adreno 506 generalized to Adreno
mar753 Feb 11, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions core/hw/pvr/ta_ctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,15 @@ bool QueueRender(TA_context* ctx)

bool too_fast = (cycle_span / time_span) > (SH4_MAIN_CLOCK * 1.2);

if (rqueue && too_fast && settings.pvr.SynchronousRender) {
if ((rqueue && too_fast && settings.pvr.SynchronousRender) ||
(settings.dreamcast.rttOption != 0 && rqueue && ctx->rend.isRTT)) {
//wait for a frame if
// we have another one queue'd and
// sh4 run at > 120% on the last slice
// and SynchronousRendering is enabled
frame_finished.Wait();
verify(!rqueue);
}
}

if (rqueue) {
tactx_Recycle(ctx);
Expand Down
2 changes: 2 additions & 0 deletions core/nullDC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ void LoadSettings()
settings.dreamcast.RTC = cfgLoadInt("config", "Dreamcast.RTC", GetRTC_now());
settings.dreamcast.region = cfgLoadInt("config", "Dreamcast.Region", 3);
settings.dreamcast.broadcast = cfgLoadInt("config", "Dreamcast.Broadcast", 4);
settings.dreamcast.rttOption = cfgLoadInt("config", "Dreamcast.Rtt", 0);
settings.aica.LimitFPS = cfgLoadInt("config", "aica.LimitFPS", 1);
settings.aica.NoBatch = cfgLoadInt("config", "aica.NoBatch", 0);
settings.aica.NoSound = cfgLoadInt("config", "aica.NoSound", 0);
Expand Down Expand Up @@ -377,4 +378,5 @@ void SaveSettings()
cfgSaveInt("config","Dreamcast.RTC", settings.dreamcast.RTC);
cfgSaveInt("config","Dreamcast.Region", settings.dreamcast.region);
cfgSaveInt("config","Dreamcast.Broadcast", settings.dreamcast.broadcast);
cfgSaveInt("config","Dreamcast.Rtt", settings.dreamcast.rttOption);
}
21 changes: 12 additions & 9 deletions core/rend/gles/gldraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,18 @@ s32 SetTileClip(u32 val, bool set)
return 0;

if (set && clip_mode) {
csy = 480 - csy;
cey = 480 - cey;
float dc2s_scale_h = screen_height / 480.0f;
float ds2s_offs_x = (screen_width - dc2s_scale_h * 640) / 2;
csx = csx * dc2s_scale_h + ds2s_offs_x;
cex = cex * dc2s_scale_h + ds2s_offs_x;
csy = csy * dc2s_scale_h;
cey = cey * dc2s_scale_h;
glUniform4f(CurrentShader->pp_ClipTest, csx, cey, cex, csy);
if (!pvrrc.isRTT) {
float t = cey;
cey = 480 - csy;
csy = 480 - t;
float dc2s_scale_h = screen_height / 480.0f;
float ds2s_offs_x = (screen_width - dc2s_scale_h * 640) / 2;
csx = csx * dc2s_scale_h + ds2s_offs_x;
cex = cex * dc2s_scale_h + ds2s_offs_x;
csy = csy * dc2s_scale_h;
cey = cey * dc2s_scale_h;
}
glUniform4f(CurrentShader->pp_ClipTest, csx, csy, cex, cey);
}

return clip_mode;
Expand Down
49 changes: 31 additions & 18 deletions core/rend/gles/gles.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <math.h>
#include <types.h>
#include "gles.h"
#include "rend/TexCache.h"
#include "cfg/cfg.h"
Expand Down Expand Up @@ -172,10 +173,10 @@ const char* VertexShaderSource =

#endif





//0 - not in use
//1 - in use since the last frame
//2 - not anymore in use (e.g. exit to menu)
u8 rttInUse = 0;

/*

Expand Down Expand Up @@ -996,6 +997,8 @@ bool gles_init()
if (!gl_create_resources())
return false;

InitShadowCircle();

#if defined(GLES) && HOST_OS != OS_DARWIN && !defined(TARGET_NACL32)
#ifdef TARGET_PANDORA
fbdev=open("/dev/fb0", O_RDONLY);
Expand Down Expand Up @@ -1447,9 +1450,10 @@ void OSD_DRAW()

bool ProcessFrame(TA_context* ctx)
{
//disable RTTs for now ..
if (ctx->rend.isRTT)
if (ctx->rend.isRTT && settings.dreamcast.rttOption == 0)
{
return false;
}

ctx->rend_inuse.Lock();
ctx->MarkRend();
Expand Down Expand Up @@ -1580,14 +1584,10 @@ bool RenderFrame()

//For some reason this produces wrong results
//so for now its hacked based like on the d3d code
/*
dc_width=FB_X_CLIP.max-FB_X_CLIP.min+1;
dc_height=FB_Y_CLIP.max-FB_Y_CLIP.min+1;
u32 pvr_stride=(FB_W_LINESTRIDE.stride)*8;
*/

dc_width=640;
dc_height=480;
dc_width = FB_X_CLIP.max - FB_X_CLIP.min + 1;
dc_height = FB_Y_CLIP.max - FB_Y_CLIP.min + 1;
//u32 pvr_stride=(FB_W_LINESTRIDE.stride)*8;
}

float scale_x=1, scale_y=1;
Expand Down Expand Up @@ -1646,8 +1646,9 @@ bool RenderFrame()
/*
Handle Dc to screen scaling
*/
float dc2s_scale_h=screen_height/480.0f;
float ds2s_offs_x=(screen_width-dc2s_scale_h*640)/2;

float dc2s_scale_h = is_rtt ? (screen_width / dc_width) : (screen_height / 480.0);
float ds2s_offs_x = is_rtt ? 0 : ((screen_width - dc2s_scale_h * 640.0) / 2);

//-1 -> too much to left
ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h*scale_x);
Expand Down Expand Up @@ -1703,7 +1704,6 @@ bool RenderFrame()
glUniform4fv( gl.modvol_shader.scale, 1, ShaderUniforms.scale_coefs);
glUniform4fv( gl.modvol_shader.depth_scale, 1, ShaderUniforms.depth_coefs);


GLfloat td[4]={0.5,0,0,0};

glUseProgram(gl.OSD_SHADER.program);
Expand Down Expand Up @@ -1768,12 +1768,22 @@ bool RenderFrame()
break;
}
BindRTT(FB_W_SOF1&VRAM_MASK,FB_X_CLIP.max-FB_X_CLIP.min+1,FB_Y_CLIP.max-FB_Y_CLIP.min+1,channels,format);
rttInUse = 1;
}
else
{
#if HOST_OS != OS_DARWIN
//Fix this in a proper way
if (rttInUse == 1) {
ReadRTT();
rttInUse = 2;
}
else if (rttInUse == 2) {
FreeRTTBuffers();
rttInUse = 0;
}

glBindFramebuffer(GL_FRAMEBUFFER,0);
glViewport(0, 0, screen_width, screen_height);
#endif
}

Expand Down Expand Up @@ -1834,7 +1844,10 @@ bool RenderFrame()
//restore scale_x
scale_x /= scissoring_scale_x;

DrawStrips();
if (!(is_rtt && (settings.dreamcast.rttOption > 0 && settings.dreamcast.rttOption <= 3)))
{
DrawStrips();
}

#if HOST_OS==OS_WINDOWS
//Sleep(40); //to test MT stability
Expand Down
3 changes: 3 additions & 0 deletions core/rend/gles/gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,12 @@ void DoCleanup();
void SortPParams();

void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt);
void ReadRTT();
void FreeRTTBuffers();
int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode,
u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset,
u32 pp_FogCtrl);
void InitShadowCircle();

bool CompilePipelineShader(PipelineShader* s);
#define TEXTURE_LOAD_ERROR 0
Expand Down
134 changes: 120 additions & 14 deletions core/rend/gles/gltex.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#include "gles.h"
#include "rend/TexCache.h"
#include "hw/pvr/pvr_mem.h"
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

/*
Textures
Expand All @@ -20,6 +25,11 @@ Compression
look into it, but afaik PVRC is not realtime doable
*/

const u32 shadowCircleW = 128;
const u32 shadowCircleH = 128;
u16 shadowCircleTexture[shadowCircleW][shadowCircleH] = {0};
u16 buf[1024*1024];

#if FEAT_HAS_SOFTREND
#include <xmmintrin.h>
#endif
Expand Down Expand Up @@ -384,11 +394,6 @@ 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.depthb) glDeleteRenderbuffers(1,&rv.depthb);
if (rv.stencilb) glDeleteRenderbuffers(1,&rv.stencilb);

rv.TexAddr=addy>>3;

// Find the largest square power of two texture that fits into the viewport
Expand All @@ -397,7 +402,8 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
//glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFbo);

// Generate and bind a render buffer which will become a depth buffer shared between our two FBOs
glGenRenderbuffers(1, &rv.depthb);
if (!rv.depthb)
glGenRenderbuffers(1, &rv.depthb);
glBindRenderbuffer(GL_RENDERBUFFER, rv.depthb);

/*
Expand All @@ -412,23 +418,25 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, fbw, fbh);
#endif

glGenRenderbuffers(1, &rv.stencilb);
if (!rv.stencilb)
glGenRenderbuffers(1, &rv.stencilb);
glBindRenderbuffer(GL_RENDERBUFFER, rv.stencilb);
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, fbw, fbh);

// Create a texture for rendering to
glGenTextures(1, &rv.tex);
if (!rv.tex)
glGenTextures(1, &rv.tex);
glBindTexture(GL_TEXTURE_2D, rv.tex);

glTexImage2D(GL_TEXTURE_2D, 0, channels, fbw, fbh, 0, channels, fmt, 0);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// Create the object that will allow us to render to the aforementioned texture
glGenFramebuffers(1, &rv.fbo);
if (!rv.fbo)
glGenFramebuffers(1, &rv.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, rv.fbo);

// Attach the texture to the FBO
Expand All @@ -441,6 +449,80 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);

verify(uStatus == GL_FRAMEBUFFER_COMPLETE);

glViewport(0, 0, fbw, fbh);
}

void handlePackModeRTT(GLint w, GLint h)
{
switch (FB_W_CTRL.fb_packmode) {
//currently RGB 565 is supported only
case 1: //0x1 565 RGB 16 bit
{
u16 *dataPointer = temp_tex_buffer;
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, temp_tex_buffer);
for (u32 i = 0; i < w * h; i++)
{
buf[i] = ((*dataPointer & 0xF000) >> 12) | ((*dataPointer & 0x0FFF) << 4);
*dataPointer++;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, buf);

break;
}
default:
//clear unsupported texture to avoid artifacts
memset(buf, '\0', w * h);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, buf);

break;
}
}

void ReadRTT()
{
FBT& rv=fb_rtt;

//get viewport width and height from rtt framebuffer
GLint dimensions[4] = {0};
glGetIntegerv(GL_VIEWPORT, dimensions);
GLint w = dimensions[2];
GLint h = dimensions[3];

//bind texture to which we have rendered in the last rtt pass
glBindTexture(GL_TEXTURE_2D, rv.tex);

if (settings.dreamcast.rttOption == 3)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shadowCircleW, shadowCircleH, 0,
GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, shadowCircleTexture[0]);
}
else if (settings.dreamcast.rttOption == 2)
{
for (u32 i = 0; i < w * h; i++)
buf[i] = ~0;

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, buf);
}
else if (settings.dreamcast.rttOption == 1)
{
for (u32 i = 0; i < w * h; i++)
buf[i] = 0;

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, buf);
}
else if (settings.dreamcast.rttOption == 4)
{
handlePackModeRTT(w, h);
}
}

void FreeRTTBuffers()
{
if (fb_rtt.fbo) { glDeleteFramebuffers(1,&fb_rtt.fbo); fb_rtt.fbo = 0; }
if (fb_rtt.tex) { glDeleteTextures(1,&fb_rtt.tex); fb_rtt.tex = 0; }
if (fb_rtt.depthb) { glDeleteRenderbuffers(1,&fb_rtt.depthb); fb_rtt.depthb = 0; }
if (fb_rtt.stencilb) { glDeleteRenderbuffers(1,&fb_rtt.stencilb); fb_rtt.stencilb = 0; }
}

GLuint gl_GetTexture(TSP tsp, TCW tcw)
Expand Down Expand Up @@ -526,8 +608,8 @@ text_info raw_GetTexture(TSP tsp, TCW tcw)
rv.width = tf->w;
rv.pdata = tf->pData;
rv.textype = tf->tex_type;


return rv;
}

Expand Down Expand Up @@ -557,6 +639,30 @@ void CollectCleanup() {
void DoCleanup() {

}

void InitShadowCircle() {
s32 middle_x = shadowCircleW / 2;
s32 middle_y = shadowCircleH / 2;
u32 radius = 15;

s32 x = 0, y = 0;
for (s32 i = 0; i <= 360; i = i + 2) {
x = s32(radius * cos(i * M_PI / 180));
y = s32(radius * sin(i * M_PI / 180));
shadowCircleTexture[middle_x + x][middle_y + y] = 0x5555;

if (y < 0) {
for (s32 j = 0; j < abs(y); ++j) {
shadowCircleTexture[middle_x + x][middle_y - j] = 0xAAAA;
}
} else {
for (s32 j = 1; j < y; ++j) {
shadowCircleTexture[middle_x + x][middle_y + j] = 0xAAAA;
}
}
}
}

void killtex()
{
for (TexCacheIter i=TexCache.begin();i!=TexCache.end();i++)
Expand Down
1 change: 1 addition & 0 deletions core/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ struct settings_t
u32 RTC;
u32 region;
u32 broadcast;
u32 rttOption;
} dreamcast;

struct
Expand Down
Loading