mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 15:41:04 +00:00
Addressed smaller comments, fb color/depth separate
This commit is contained in:
parent
d517757053
commit
dfc807daf9
@ -355,8 +355,8 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
|
|||||||
|
|
||||||
// GX request DMA - typically used for copying memory from GSP heap to VRAM
|
// GX request DMA - typically used for copying memory from GSP heap to VRAM
|
||||||
case CommandId::REQUEST_DMA:
|
case CommandId::REQUEST_DMA:
|
||||||
VideoCore::g_renderer->hw_rasterizer->NotifyPreCopy(Memory::VirtualToPhysicalAddress(command.dma_request.source_address),
|
VideoCore::g_renderer->hw_rasterizer->NotifyPreRead(Memory::VirtualToPhysicalAddress(command.dma_request.source_address),
|
||||||
command.dma_request.size);
|
command.dma_request.size);
|
||||||
|
|
||||||
memcpy(Memory::GetPointer(command.dma_request.dest_address),
|
memcpy(Memory::GetPointer(command.dma_request.dest_address),
|
||||||
Memory::GetPointer(command.dma_request.source_address),
|
Memory::GetPointer(command.dma_request.source_address),
|
||||||
|
@ -131,10 +131,10 @@ inline void Write(u32 addr, const T data) {
|
|||||||
u32 output_width = config.output_width / horizontal_scale;
|
u32 output_width = config.output_width / horizontal_scale;
|
||||||
u32 output_height = config.output_height / vertical_scale;
|
u32 output_height = config.output_height / vertical_scale;
|
||||||
|
|
||||||
u32 input_size = config.input_height.Value() * config.input_width.Value() * GPU::Regs::BytesPerPixel(config.input_format.Value());
|
u32 input_size = config.input_height * config.input_width * GPU::Regs::BytesPerPixel(config.input_format);
|
||||||
u32 output_size = output_height * output_width * GPU::Regs::BytesPerPixel(config.output_format.Value());
|
u32 output_size = output_height * output_width * GPU::Regs::BytesPerPixel(config.output_format);
|
||||||
|
|
||||||
VideoCore::g_renderer->hw_rasterizer->NotifyPreCopy(config.GetPhysicalInputAddress(), input_size);
|
VideoCore::g_renderer->hw_rasterizer->NotifyPreRead(config.GetPhysicalInputAddress(), input_size);
|
||||||
|
|
||||||
if (config.raw_copy) {
|
if (config.raw_copy) {
|
||||||
// Raw copies do not perform color conversion nor tiled->linear / linear->tiled conversions
|
// Raw copies do not perform color conversion nor tiled->linear / linear->tiled conversions
|
||||||
|
@ -15,10 +15,7 @@ public:
|
|||||||
/// Initialize API-specific GPU objects
|
/// Initialize API-specific GPU objects
|
||||||
virtual void InitObjects() = 0;
|
virtual void InitObjects() = 0;
|
||||||
|
|
||||||
/// Set the window (context) to draw with
|
/// Queues the primitive formed by the given vertices for rendering
|
||||||
virtual void SetWindow(EmuWindow* window) = 0;
|
|
||||||
|
|
||||||
/// Converts the triangle verts to hardware data format and adds them to the current batch
|
|
||||||
virtual void AddTriangle(const Pica::VertexShader::OutputVertex& v0,
|
virtual void AddTriangle(const Pica::VertexShader::OutputVertex& v0,
|
||||||
const Pica::VertexShader::OutputVertex& v1,
|
const Pica::VertexShader::OutputVertex& v1,
|
||||||
const Pica::VertexShader::OutputVertex& v2) = 0;
|
const Pica::VertexShader::OutputVertex& v2) = 0;
|
||||||
@ -26,9 +23,9 @@ public:
|
|||||||
/// Draw the current batch of triangles
|
/// Draw the current batch of triangles
|
||||||
virtual void DrawTriangles() = 0;
|
virtual void DrawTriangles() = 0;
|
||||||
|
|
||||||
/// Notify rasterizer that a copy within 3DS memory will occur after this notification
|
/// Notify rasterizer that the specified 3DS memory region will be read from after this notification
|
||||||
virtual void NotifyPreCopy(u32 src_paddr, u32 size) = 0;
|
virtual void NotifyPreRead(u32 paddr, u32 size) = 0;
|
||||||
|
|
||||||
/// Notify rasterizer that a 3DS memory region has been changed
|
/// Notify rasterizer that a 3DS memory region has been changed
|
||||||
virtual void NotifyFlush(u32 paddr, u32 size) = 0;
|
virtual void NotifyFlush(u32 addr, u32 size) = 0;
|
||||||
};
|
};
|
||||||
|
@ -500,6 +500,23 @@ struct Regs {
|
|||||||
RGBA4 = 4,
|
RGBA4 = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Returns the number of bytes in the specified color format
|
||||||
|
static unsigned BytesPerColorPixel(u32 format) {
|
||||||
|
switch (format) {
|
||||||
|
case ColorFormat::RGBA8:
|
||||||
|
return 4;
|
||||||
|
case ColorFormat::RGB8:
|
||||||
|
return 3;
|
||||||
|
case ColorFormat::RGB5A1:
|
||||||
|
case ColorFormat::RGB565:
|
||||||
|
case ColorFormat::RGBA4:
|
||||||
|
return 2;
|
||||||
|
default:
|
||||||
|
LOG_CRITICAL(HW_GPU, "Unknown color format %u", format);
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
INSERT_PADDING_WORDS(0x6);
|
INSERT_PADDING_WORDS(0x6);
|
||||||
|
|
||||||
DepthFormat depth_format;
|
DepthFormat depth_format;
|
||||||
|
@ -12,83 +12,86 @@
|
|||||||
|
|
||||||
namespace PicaToGL {
|
namespace PicaToGL {
|
||||||
|
|
||||||
static GLenum WrapMode(Pica::Regs::TextureConfig::WrapMode mode) {
|
inline GLenum WrapMode(Pica::Regs::TextureConfig::WrapMode mode) {
|
||||||
switch (mode) {
|
static const GLenum wrap_mode_table[] = {
|
||||||
case Pica::Regs::TextureConfig::WrapMode::ClampToEdge:
|
GL_CLAMP_TO_EDGE, // WrapMode::ClampToEdge
|
||||||
|
0, // Unknown
|
||||||
|
GL_REPEAT, // WrapMode::Repeat
|
||||||
|
GL_MIRRORED_REPEAT // WrapMode::MirroredRepeat
|
||||||
|
};
|
||||||
|
|
||||||
|
// Range check table for input
|
||||||
|
if (mode >= sizeof(wrap_mode_table) / sizeof(GLenum)) {
|
||||||
|
LOG_CRITICAL(Render_OpenGL, "Unknown texture wrap mode %d", mode);
|
||||||
|
UNREACHABLE();
|
||||||
|
|
||||||
return GL_CLAMP_TO_EDGE;
|
return GL_CLAMP_TO_EDGE;
|
||||||
case Pica::Regs::TextureConfig::WrapMode::Repeat:
|
}
|
||||||
return GL_REPEAT;
|
|
||||||
case Pica::Regs::TextureConfig::WrapMode::MirroredRepeat:
|
GLenum gl_mode = wrap_mode_table[mode];
|
||||||
return GL_MIRRORED_REPEAT;
|
|
||||||
default:
|
// Check for dummy values indicating an unknown mode
|
||||||
|
if (gl_mode == 0) {
|
||||||
LOG_CRITICAL(Render_OpenGL, "Unknown texture wrap mode %d", mode);
|
LOG_CRITICAL(Render_OpenGL, "Unknown texture wrap mode %d", mode);
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
|
||||||
return GL_CLAMP_TO_EDGE;
|
return GL_CLAMP_TO_EDGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return gl_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum BlendFunc(u32 factor) {
|
inline GLenum BlendFunc(u32 factor) {
|
||||||
switch (factor) {
|
static const GLenum blend_func_table[] = {
|
||||||
case Pica::registers.output_merger.alpha_blending.Zero:
|
GL_ZERO, // BlendFactor::Zero
|
||||||
return GL_ZERO;
|
GL_ONE, // BlendFactor::One
|
||||||
case Pica::registers.output_merger.alpha_blending.One:
|
GL_SRC_COLOR, // BlendFactor::SourceColor
|
||||||
return GL_ONE;
|
GL_ONE_MINUS_SRC_COLOR, // BlendFactor::OneMinusSourceColor
|
||||||
case Pica::registers.output_merger.alpha_blending.SourceColor:
|
GL_DST_COLOR, // BlendFactor::DestColor
|
||||||
return GL_SRC_COLOR;
|
GL_ONE_MINUS_DST_COLOR, // BlendFactor::OneMinusDestColor
|
||||||
case Pica::registers.output_merger.alpha_blending.OneMinusSourceColor:
|
GL_SRC_ALPHA, // BlendFactor::SourceAlpha
|
||||||
return GL_ONE_MINUS_SRC_COLOR;
|
GL_ONE_MINUS_SRC_ALPHA, // BlendFactor::OneMinusSourceAlpha
|
||||||
case Pica::registers.output_merger.alpha_blending.DestColor:
|
GL_DST_ALPHA, // BlendFactor::DestAlpha
|
||||||
return GL_DST_COLOR;
|
GL_ONE_MINUS_DST_ALPHA, // BlendFactor::OneMinusDestAlpha
|
||||||
case Pica::registers.output_merger.alpha_blending.OneMinusDestColor:
|
GL_CONSTANT_COLOR, // BlendFactor::ConstantColor
|
||||||
return GL_ONE_MINUS_DST_COLOR;
|
GL_ONE_MINUS_CONSTANT_COLOR, // BlendFactor::OneMinusConstantColor
|
||||||
case Pica::registers.output_merger.alpha_blending.SourceAlpha:
|
GL_CONSTANT_ALPHA, // BlendFactor::ConstantAlpha
|
||||||
return GL_SRC_ALPHA;
|
GL_ONE_MINUS_CONSTANT_ALPHA, // BlendFactor::OneMinusConstantAlpha
|
||||||
case Pica::registers.output_merger.alpha_blending.OneMinusSourceAlpha:
|
GL_SRC_ALPHA_SATURATE, // BlendFactor::SourceAlphaSaturate
|
||||||
return GL_ONE_MINUS_SRC_ALPHA;
|
};
|
||||||
case Pica::registers.output_merger.alpha_blending.DestAlpha:
|
|
||||||
return GL_DST_ALPHA;
|
// Range check table for input
|
||||||
case Pica::registers.output_merger.alpha_blending.OneMinusDestAlpha:
|
if (factor >= sizeof(blend_func_table) / sizeof(GLenum)) {
|
||||||
return GL_ONE_MINUS_DST_ALPHA;
|
|
||||||
case Pica::registers.output_merger.alpha_blending.ConstantColor:
|
|
||||||
return GL_CONSTANT_COLOR;
|
|
||||||
case Pica::registers.output_merger.alpha_blending.OneMinusConstantColor:
|
|
||||||
return GL_ONE_MINUS_CONSTANT_COLOR;
|
|
||||||
case Pica::registers.output_merger.alpha_blending.ConstantAlpha:
|
|
||||||
return GL_CONSTANT_ALPHA;
|
|
||||||
case Pica::registers.output_merger.alpha_blending.OneMinusConstantAlpha:
|
|
||||||
return GL_ONE_MINUS_CONSTANT_ALPHA;
|
|
||||||
case Pica::registers.output_merger.alpha_blending.SourceAlphaSaturate:
|
|
||||||
return GL_SRC_ALPHA_SATURATE;
|
|
||||||
default:
|
|
||||||
LOG_CRITICAL(Render_OpenGL, "Unknown blend factor %d", factor);
|
LOG_CRITICAL(Render_OpenGL, "Unknown blend factor %d", factor);
|
||||||
UNIMPLEMENTED();
|
UNREACHABLE();
|
||||||
|
|
||||||
return GL_ONE;
|
return GL_ONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return blend_func_table[factor];
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum CompareFunc(u32 func) {
|
inline GLenum CompareFunc(u32 func) {
|
||||||
switch (func) {
|
static const GLenum compare_func_table[] = {
|
||||||
case Pica::registers.output_merger.Never:
|
GL_NEVER, // CompareFunc::Never
|
||||||
return GL_NEVER;
|
GL_ALWAYS, // CompareFunc::Always
|
||||||
case Pica::registers.output_merger.Always:
|
GL_EQUAL, // CompareFunc::Equal
|
||||||
return GL_ALWAYS;
|
GL_NOTEQUAL, // CompareFunc::NotEqual
|
||||||
case Pica::registers.output_merger.Equal:
|
GL_LESS, // CompareFunc::LessThan
|
||||||
return GL_EQUAL;
|
GL_LEQUAL, // CompareFunc::LessThanOrEqual
|
||||||
case Pica::registers.output_merger.NotEqual:
|
GL_GREATER, // CompareFunc::GreaterThan
|
||||||
return GL_NOTEQUAL;
|
GL_GEQUAL, // CompareFunc::GreaterThanOrEqual
|
||||||
case Pica::registers.output_merger.LessThan:
|
};
|
||||||
return GL_LESS;
|
|
||||||
case Pica::registers.output_merger.LessThanOrEqual:
|
// Range check table for input
|
||||||
return GL_LEQUAL;
|
if (func >= sizeof(compare_func_table) / sizeof(GLenum)) {
|
||||||
case Pica::registers.output_merger.GreaterThan:
|
|
||||||
return GL_GREATER;
|
|
||||||
case Pica::registers.output_merger.GreaterThanOrEqual:
|
|
||||||
return GL_GEQUAL;
|
|
||||||
default:
|
|
||||||
LOG_CRITICAL(Render_OpenGL, "Unknown compare function %d", func);
|
LOG_CRITICAL(Render_OpenGL, "Unknown compare function %d", func);
|
||||||
UNIMPLEMENTED();
|
UNREACHABLE();
|
||||||
|
|
||||||
return GL_ALWAYS;
|
return GL_ALWAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return compare_func_table[func];
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -17,32 +17,12 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
u32 ColorFormatBytesPerPixel(u32 format) {
|
|
||||||
switch (format) {
|
|
||||||
case Pica::registers.framebuffer.RGBA8:
|
|
||||||
return 4;
|
|
||||||
case Pica::registers.framebuffer.RGB8:
|
|
||||||
return 3;
|
|
||||||
case Pica::registers.framebuffer.RGB5A1:
|
|
||||||
case Pica::registers.framebuffer.RGB565:
|
|
||||||
case Pica::registers.framebuffer.RGBA4:
|
|
||||||
return 2;
|
|
||||||
default:
|
|
||||||
LOG_CRITICAL(Render_OpenGL, "Unknown framebuffer color format %x", format);
|
|
||||||
UNIMPLEMENTED();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
RasterizerOpenGL::RasterizerOpenGL() : last_fb_color_addr(0), last_fb_depth_addr(0) {
|
RasterizerOpenGL::RasterizerOpenGL() : last_fb_color_addr(0), last_fb_depth_addr(0) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RasterizerOpenGL::~RasterizerOpenGL() {
|
RasterizerOpenGL::~RasterizerOpenGL() {
|
||||||
// Set context for automatic resource destruction
|
|
||||||
render_window->MakeCurrent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::InitObjects() {
|
void RasterizerOpenGL::InitObjects() {
|
||||||
@ -109,7 +89,7 @@ void RasterizerOpenGL::InitObjects() {
|
|||||||
|
|
||||||
// Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation
|
// Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation
|
||||||
fb_color_texture.texture.Create();
|
fb_color_texture.texture.Create();
|
||||||
ReconfigColorTexture(fb_color_texture, Pica::registers.framebuffer.RGBA8, 1, 1);
|
ReconfigureColorTexture(fb_color_texture, Pica::registers.framebuffer.RGBA8, 1, 1);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
@ -117,7 +97,7 @@ void RasterizerOpenGL::InitObjects() {
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
fb_depth_texture.texture.Create();
|
fb_depth_texture.texture.Create();
|
||||||
ReconfigDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1);
|
ReconfigureDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
@ -138,13 +118,8 @@ void RasterizerOpenGL::InitObjects() {
|
|||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_color_texture.texture.GetHandle(), 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb_color_texture.texture.GetHandle(), 0);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fb_depth_texture.texture.GetHandle(), 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, fb_depth_texture.texture.GetHandle(), 0);
|
||||||
|
|
||||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
ASSERT_MSG(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
|
||||||
LOG_CRITICAL(Render_OpenGL, "Framebuffer setup failed, status %X", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
"OpenGL rasterizer framebuffer setup failed, status %X", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterizerOpenGL::SetWindow(EmuWindow* window) {
|
|
||||||
render_window = window;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::AddTriangle(const Pica::VertexShader::OutputVertex& v0,
|
void RasterizerOpenGL::AddTriangle(const Pica::VertexShader::OutputVertex& v0,
|
||||||
@ -156,8 +131,6 @@ void RasterizerOpenGL::AddTriangle(const Pica::VertexShader::OutputVertex& v0,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::DrawTriangles() {
|
void RasterizerOpenGL::DrawTriangles() {
|
||||||
render_window->MakeCurrent();
|
|
||||||
|
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
SyncFramebuffer();
|
SyncFramebuffer();
|
||||||
@ -169,16 +142,14 @@ void RasterizerOpenGL::DrawTriangles() {
|
|||||||
vertex_batch.clear();
|
vertex_batch.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::NotifyPreCopy(PAddr src_addr, u32 size) {
|
void RasterizerOpenGL::NotifyPreRead(PAddr addr, u32 size) {
|
||||||
if (!Settings::values.use_hw_renderer)
|
if (!Settings::values.use_hw_renderer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
render_window->MakeCurrent();
|
|
||||||
|
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
PAddr cur_fb_color_addr = Pica::registers.framebuffer.GetColorBufferPhysicalAddress();
|
PAddr cur_fb_color_addr = Pica::registers.framebuffer.GetColorBufferPhysicalAddress();
|
||||||
u32 cur_fb_color_size = ColorFormatBytesPerPixel(Pica::registers.framebuffer.color_format)
|
u32 cur_fb_color_size = Pica::registers.framebuffer.BytesPerColorPixel(Pica::registers.framebuffer.color_format)
|
||||||
* Pica::registers.framebuffer.GetWidth() * Pica::registers.framebuffer.GetHeight();
|
* Pica::registers.framebuffer.GetWidth() * Pica::registers.framebuffer.GetHeight();
|
||||||
|
|
||||||
PAddr cur_fb_depth_addr = Pica::registers.framebuffer.GetDepthBufferPhysicalAddress();
|
PAddr cur_fb_depth_addr = Pica::registers.framebuffer.GetDepthBufferPhysicalAddress();
|
||||||
@ -186,18 +157,18 @@ void RasterizerOpenGL::NotifyPreCopy(PAddr src_addr, u32 size) {
|
|||||||
* Pica::registers.framebuffer.GetWidth() * Pica::registers.framebuffer.GetHeight();
|
* Pica::registers.framebuffer.GetWidth() * Pica::registers.framebuffer.GetHeight();
|
||||||
|
|
||||||
// If source memory region overlaps 3DS framebuffers, commit them before the copy happens
|
// If source memory region overlaps 3DS framebuffers, commit them before the copy happens
|
||||||
PAddr max_low_addr_bound = std::max(src_addr, cur_fb_color_addr);
|
PAddr max_low_addr_bound = std::max(addr, cur_fb_color_addr);
|
||||||
PAddr min_hi_addr_bound = std::min(src_addr + size, cur_fb_color_addr + cur_fb_color_size);
|
PAddr min_hi_addr_bound = std::min(addr + size, cur_fb_color_addr + cur_fb_color_size);
|
||||||
|
|
||||||
if (max_low_addr_bound <= min_hi_addr_bound) {
|
if (max_low_addr_bound <= min_hi_addr_bound) {
|
||||||
CommitFramebuffer();
|
CommitColorBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
max_low_addr_bound = std::max(src_addr, cur_fb_depth_addr);
|
max_low_addr_bound = std::max(addr, cur_fb_depth_addr);
|
||||||
min_hi_addr_bound = std::min(src_addr + size, cur_fb_depth_addr + cur_fb_depth_size);
|
min_hi_addr_bound = std::min(addr + size, cur_fb_depth_addr + cur_fb_depth_size);
|
||||||
|
|
||||||
if (max_low_addr_bound <= min_hi_addr_bound) {
|
if (max_low_addr_bound <= min_hi_addr_bound) {
|
||||||
CommitFramebuffer();
|
CommitDepthBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,12 +176,10 @@ void RasterizerOpenGL::NotifyFlush(PAddr addr, u32 size) {
|
|||||||
if (!Settings::values.use_hw_renderer)
|
if (!Settings::values.use_hw_renderer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
render_window->MakeCurrent();
|
|
||||||
|
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
PAddr cur_fb_color_addr = Pica::registers.framebuffer.GetColorBufferPhysicalAddress();
|
PAddr cur_fb_color_addr = Pica::registers.framebuffer.GetColorBufferPhysicalAddress();
|
||||||
u32 cur_fb_color_size = ColorFormatBytesPerPixel(Pica::registers.framebuffer.color_format)
|
u32 cur_fb_color_size = Pica::registers.framebuffer.BytesPerColorPixel(Pica::registers.framebuffer.color_format)
|
||||||
* Pica::registers.framebuffer.GetWidth() * Pica::registers.framebuffer.GetHeight();
|
* Pica::registers.framebuffer.GetWidth() * Pica::registers.framebuffer.GetHeight();
|
||||||
|
|
||||||
PAddr cur_fb_depth_addr = Pica::registers.framebuffer.GetDepthBufferPhysicalAddress();
|
PAddr cur_fb_depth_addr = Pica::registers.framebuffer.GetDepthBufferPhysicalAddress();
|
||||||
@ -236,7 +205,7 @@ void RasterizerOpenGL::NotifyFlush(PAddr addr, u32 size) {
|
|||||||
res_cache.NotifyFlush(addr, size);
|
res_cache.NotifyFlush(addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::ReconfigColorTexture(TextureInfo& texture, u32 format, u32 width, u32 height) {
|
void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, u32 format, u32 width, u32 height) {
|
||||||
GLint internal_format;
|
GLint internal_format;
|
||||||
|
|
||||||
texture.format = format;
|
texture.format = format;
|
||||||
@ -293,7 +262,7 @@ void RasterizerOpenGL::ReconfigColorTexture(TextureInfo& texture, u32 format, u3
|
|||||||
texture.gl_format, texture.gl_type, nullptr);
|
texture.gl_format, texture.gl_type, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::ReconfigDepthTexture(DepthTextureInfo& texture, Pica::Regs::DepthFormat format, u32 width, u32 height) {
|
void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::Regs::DepthFormat format, u32 width, u32 height) {
|
||||||
GLint internal_format;
|
GLint internal_format;
|
||||||
|
|
||||||
texture.format = format;
|
texture.format = format;
|
||||||
@ -351,15 +320,16 @@ void RasterizerOpenGL::SyncFramebuffer() {
|
|||||||
|
|
||||||
// Commit if fb modified in any way
|
// Commit if fb modified in any way
|
||||||
if (fb_modified) {
|
if (fb_modified) {
|
||||||
CommitFramebuffer();
|
CommitColorBuffer();
|
||||||
|
CommitDepthBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconfigure framebuffer textures if any property has changed
|
// Reconfigure framebuffer textures if any property has changed
|
||||||
if (fb_prop_changed) {
|
if (fb_prop_changed) {
|
||||||
ReconfigColorTexture(fb_color_texture, new_fb_color_format,
|
ReconfigureColorTexture(fb_color_texture, new_fb_color_format,
|
||||||
Pica::registers.framebuffer.GetWidth(), Pica::registers.framebuffer.GetHeight());
|
Pica::registers.framebuffer.GetWidth(), Pica::registers.framebuffer.GetHeight());
|
||||||
|
|
||||||
ReconfigDepthTexture(fb_depth_texture, new_fb_depth_format,
|
ReconfigureDepthTexture(fb_depth_texture, new_fb_depth_format,
|
||||||
Pica::registers.framebuffer.GetWidth(), Pica::registers.framebuffer.GetHeight());
|
Pica::registers.framebuffer.GetWidth(), Pica::registers.framebuffer.GetHeight());
|
||||||
|
|
||||||
// Only attach depth buffer as stencil if it supports stencil
|
// Only attach depth buffer as stencil if it supports stencil
|
||||||
@ -385,10 +355,6 @@ void RasterizerOpenGL::SyncFramebuffer() {
|
|||||||
last_fb_color_addr = cur_fb_color_addr;
|
last_fb_color_addr = cur_fb_color_addr;
|
||||||
last_fb_depth_addr = cur_fb_depth_addr;
|
last_fb_depth_addr = cur_fb_depth_addr;
|
||||||
|
|
||||||
// Currently not needed b/c of reloading buffers below, but will be needed for high-res rendering
|
|
||||||
//glDepthMask(GL_TRUE);
|
|
||||||
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
ReloadColorBuffer();
|
ReloadColorBuffer();
|
||||||
ReloadDepthBuffer();
|
ReloadDepthBuffer();
|
||||||
}
|
}
|
||||||
@ -549,7 +515,7 @@ void RasterizerOpenGL::ReloadColorBuffer() {
|
|||||||
if (color_buffer == nullptr)
|
if (color_buffer == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u32 bytes_per_pixel = ColorFormatBytesPerPixel(fb_color_texture.format);
|
u32 bytes_per_pixel = Pica::registers.framebuffer.BytesPerColorPixel(fb_color_texture.format);
|
||||||
|
|
||||||
std::unique_ptr<u8[]> temp_fb_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]);
|
std::unique_ptr<u8[]> temp_fb_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]);
|
||||||
|
|
||||||
@ -626,12 +592,12 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
|
|||||||
fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_fb_depth_buffer.get());
|
fb_depth_texture.gl_format, fb_depth_texture.gl_type, temp_fb_depth_buffer.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::CommitFramebuffer() {
|
void RasterizerOpenGL::CommitColorBuffer() {
|
||||||
if (last_fb_color_addr != 0) {
|
if (last_fb_color_addr != 0) {
|
||||||
u8* color_buffer = Memory::GetPhysicalPointer(last_fb_color_addr);
|
u8* color_buffer = Memory::GetPhysicalPointer(last_fb_color_addr);
|
||||||
|
|
||||||
if (color_buffer != nullptr) {
|
if (color_buffer != nullptr) {
|
||||||
u32 bytes_per_pixel = ColorFormatBytesPerPixel(fb_color_texture.format);
|
u32 bytes_per_pixel = Pica::registers.framebuffer.BytesPerColorPixel(fb_color_texture.format);
|
||||||
|
|
||||||
std::unique_ptr<u8[]> temp_gl_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]);
|
std::unique_ptr<u8[]> temp_gl_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]);
|
||||||
|
|
||||||
@ -656,7 +622,9 @@ void RasterizerOpenGL::CommitFramebuffer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterizerOpenGL::CommitDepthBuffer() {
|
||||||
if (last_fb_depth_addr != 0) {
|
if (last_fb_depth_addr != 0) {
|
||||||
// TODO: Output seems correct visually, but doesn't quite match sw renderer output. One of them is wrong.
|
// TODO: Output seems correct visually, but doesn't quite match sw renderer output. One of them is wrong.
|
||||||
u8* depth_buffer = Memory::GetPhysicalPointer(last_fb_depth_addr);
|
u8* depth_buffer = Memory::GetPhysicalPointer(last_fb_depth_addr);
|
||||||
|
@ -18,10 +18,7 @@ public:
|
|||||||
/// Initialize API-specific GPU objects
|
/// Initialize API-specific GPU objects
|
||||||
void InitObjects() override;
|
void InitObjects() override;
|
||||||
|
|
||||||
/// Set the window (context) to draw with
|
/// Queues the primitive formed by the given vertices for rendering
|
||||||
void SetWindow(EmuWindow* window) override;
|
|
||||||
|
|
||||||
/// Converts the triangle verts to hardware data format and adds them to the current batch
|
|
||||||
void AddTriangle(const Pica::VertexShader::OutputVertex& v0,
|
void AddTriangle(const Pica::VertexShader::OutputVertex& v0,
|
||||||
const Pica::VertexShader::OutputVertex& v1,
|
const Pica::VertexShader::OutputVertex& v1,
|
||||||
const Pica::VertexShader::OutputVertex& v2) override;
|
const Pica::VertexShader::OutputVertex& v2) override;
|
||||||
@ -29,8 +26,8 @@ public:
|
|||||||
/// Draw the current batch of triangles
|
/// Draw the current batch of triangles
|
||||||
void DrawTriangles() override;
|
void DrawTriangles() override;
|
||||||
|
|
||||||
/// Notify rasterizer that a copy within 3DS memory will occur after this notification
|
/// Notify rasterizer that the specified 3DS memory region will be read from after this notification
|
||||||
void NotifyPreCopy(PAddr src_addr, u32 size) override;
|
void NotifyPreRead(PAddr addr, u32 size) override;
|
||||||
|
|
||||||
/// Notify rasterizer that a 3DS memory region has been changed
|
/// Notify rasterizer that a 3DS memory region has been changed
|
||||||
void NotifyFlush(PAddr addr, u32 size) override;
|
void NotifyFlush(PAddr addr, u32 size) override;
|
||||||
@ -95,10 +92,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Reconfigure the OpenGL color texture to use the given format and dimensions
|
/// Reconfigure the OpenGL color texture to use the given format and dimensions
|
||||||
void ReconfigColorTexture(TextureInfo& texture, u32 format, u32 width, u32 height);
|
void ReconfigureColorTexture(TextureInfo& texture, u32 format, u32 width, u32 height);
|
||||||
|
|
||||||
/// Reconfigure the OpenGL depth texture to use the given format and dimensions
|
/// Reconfigure the OpenGL depth texture to use the given format and dimensions
|
||||||
void ReconfigDepthTexture(DepthTextureInfo& texture, Pica::Regs::DepthFormat format, u32 width, u32 height);
|
void ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::Regs::DepthFormat format, u32 width, u32 height);
|
||||||
|
|
||||||
/// Syncs the state and contents of the OpenGL framebuffer to match the current PICA framebuffer
|
/// Syncs the state and contents of the OpenGL framebuffer to match the current PICA framebuffer
|
||||||
void SyncFramebuffer();
|
void SyncFramebuffer();
|
||||||
@ -113,13 +110,19 @@ private:
|
|||||||
void ReloadDepthBuffer();
|
void ReloadDepthBuffer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the current OpenGL framebuffer to the current PICA framebuffer in 3ds memory
|
* Save the current OpenGL color framebuffer to the current PICA framebuffer in 3ds memory
|
||||||
* Loads the OpenGL framebuffer textures into temporary buffers
|
* Loads the OpenGL framebuffer textures into temporary buffers
|
||||||
* Then copies into the 3ds framebuffer using proper Morton order
|
* Then copies into the 3ds framebuffer using proper Morton order
|
||||||
*/
|
*/
|
||||||
void CommitFramebuffer();
|
void CommitColorBuffer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the current OpenGL depth framebuffer to the current PICA framebuffer in 3ds memory
|
||||||
|
* Loads the OpenGL framebuffer textures into temporary buffers
|
||||||
|
* Then copies into the 3ds framebuffer using proper Morton order
|
||||||
|
*/
|
||||||
|
void CommitDepthBuffer();
|
||||||
|
|
||||||
EmuWindow* render_window;
|
|
||||||
RasterizerCacheOpenGL res_cache;
|
RasterizerCacheOpenGL res_cache;
|
||||||
|
|
||||||
std::vector<HardwareVertex> vertex_batch;
|
std::vector<HardwareVertex> vertex_batch;
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/make_unique.h"
|
||||||
|
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
#include "video_core/renderer_opengl/gl_pica_to_gl.h"
|
#include "video_core/renderer_opengl/gl_pica_to_gl.h"
|
||||||
#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
|
#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
|
||||||
#include "video_core/debug_utils/debug_utils.h"
|
#include "video_core/debug_utils/debug_utils.h"
|
||||||
@ -21,7 +24,7 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, int texture_u
|
|||||||
state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.GetHandle();
|
state.texture_units[texture_unit].texture_2d = cached_texture->second->texture.GetHandle();
|
||||||
state.Apply();
|
state.Apply();
|
||||||
} else {
|
} else {
|
||||||
std::unique_ptr<CachedTexture> new_texture(new CachedTexture());
|
std::unique_ptr<CachedTexture> new_texture = Common::make_unique<CachedTexture>();
|
||||||
|
|
||||||
new_texture->texture.Create();
|
new_texture->texture.Create();
|
||||||
state.texture_units[texture_unit].texture_2d = new_texture->texture.GetHandle();
|
state.texture_units[texture_unit].texture_2d = new_texture->texture.GetHandle();
|
||||||
@ -31,8 +34,8 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, int texture_u
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, PicaToGL::WrapMode(config.config.wrap_s.Value()));
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, PicaToGL::WrapMode(config.config.wrap_s));
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, PicaToGL::WrapMode(config.config.wrap_t.Value()));
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, PicaToGL::WrapMode(config.config.wrap_t));
|
||||||
|
|
||||||
const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format);
|
const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format);
|
||||||
|
|
||||||
@ -40,11 +43,12 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, int texture_u
|
|||||||
new_texture->height = info.height;
|
new_texture->height = info.height;
|
||||||
new_texture->size = info.width * info.height * Pica::Regs::NibblesPerPixel(info.format);
|
new_texture->size = info.width * info.height * Pica::Regs::NibblesPerPixel(info.format);
|
||||||
|
|
||||||
|
u8* texture_src_data = Memory::GetPhysicalPointer(texture_addr);
|
||||||
std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]);
|
std::unique_ptr<Math::Vec4<u8>[]> temp_texture_buffer_rgba(new Math::Vec4<u8>[info.width * info.height]);
|
||||||
|
|
||||||
for (int y = 0; y < info.height; ++y) {
|
for (int y = 0; y < info.height; ++y) {
|
||||||
for (int x = 0; x < info.width; ++x) {
|
for (int x = 0; x < info.width; ++x) {
|
||||||
temp_texture_buffer_rgba[x + info.width * y] = Pica::DebugUtils::LookupTexture(Memory::GetPhysicalPointer(texture_addr), x, info.height - 1 - y, info);
|
temp_texture_buffer_rgba[x + info.width * y] = Pica::DebugUtils::LookupTexture(texture_src_data, x, info.height - 1 - y, info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +60,7 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, int texture_u
|
|||||||
|
|
||||||
void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size) {
|
void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size) {
|
||||||
// Flush any texture that falls in the flushed region
|
// Flush any texture that falls in the flushed region
|
||||||
for (auto it = texture_cache.begin(); it != texture_cache.end();) {
|
for (auto it = texture_cache.begin(); it != texture_cache.upper_bound(addr + size);) {
|
||||||
PAddr max_low_addr_bound = std::max(addr, it->first);
|
PAddr max_low_addr_bound = std::max(addr, it->first);
|
||||||
PAddr min_hi_addr_bound = std::min(addr + size, it->first + it->second->size);
|
PAddr min_hi_addr_bound = std::min(addr + size, it->first + it->second->size);
|
||||||
|
|
||||||
|
@ -5,20 +5,11 @@
|
|||||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_util.h"
|
#include "video_core/renderer_opengl/gl_shader_util.h"
|
||||||
|
|
||||||
// OGLResource base class
|
|
||||||
OGLResource::OGLResource() : handle(0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
OGLResource::~OGLResource() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void OGLResource::Release() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Textures
|
// Textures
|
||||||
|
OGLTexture::OGLTexture() : handle(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OGLTexture::~OGLTexture() {
|
OGLTexture::~OGLTexture() {
|
||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
@ -37,6 +28,10 @@ void OGLTexture::Release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
|
OGLShader::OGLShader() : handle(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OGLShader::~OGLShader() {
|
OGLShader::~OGLShader() {
|
||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
@ -55,6 +50,10 @@ void OGLShader::Release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buffer objects
|
// Buffer objects
|
||||||
|
OGLBuffer::OGLBuffer() : handle(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OGLBuffer::~OGLBuffer() {
|
OGLBuffer::~OGLBuffer() {
|
||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
@ -73,6 +72,10 @@ void OGLBuffer::Release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Vertex array objects
|
// Vertex array objects
|
||||||
|
OGLVertexArray::OGLVertexArray() : handle(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OGLVertexArray::~OGLVertexArray() {
|
OGLVertexArray::~OGLVertexArray() {
|
||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
@ -91,6 +94,10 @@ void OGLVertexArray::Release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Framebuffers
|
// Framebuffers
|
||||||
|
OGLFramebuffer::OGLFramebuffer() : handle(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OGLFramebuffer::~OGLFramebuffer() {
|
OGLFramebuffer::~OGLFramebuffer() {
|
||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
|
@ -8,74 +8,102 @@
|
|||||||
|
|
||||||
#include "generated/gl_3_2_core.h"
|
#include "generated/gl_3_2_core.h"
|
||||||
|
|
||||||
class OGLResource : NonCopyable {
|
class OGLTexture : public NonCopyable {
|
||||||
public:
|
public:
|
||||||
OGLResource();
|
OGLTexture();
|
||||||
virtual ~OGLResource();
|
~OGLTexture();
|
||||||
|
|
||||||
/// Returns the internal OpenGL resource handle for this resource
|
/// Returns the internal OpenGL resource handle for this resource
|
||||||
inline GLuint GetHandle() {
|
inline GLuint GetHandle() {
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new internal OpenGL resource and stores the handle
|
||||||
|
void Create();
|
||||||
|
|
||||||
/// Deletes the internal OpenGL resource
|
/// Deletes the internal OpenGL resource
|
||||||
virtual void Release();
|
void Release();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GLuint handle;
|
GLuint handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OGLTexture : public OGLResource {
|
class OGLShader : public NonCopyable {
|
||||||
public:
|
public:
|
||||||
~OGLTexture() override;
|
OGLShader();
|
||||||
|
~OGLShader();
|
||||||
|
|
||||||
/// Creates a new internal OpenGL resource and stores the handle
|
/// Returns the internal OpenGL resource handle for this resource
|
||||||
void Create();
|
inline GLuint GetHandle() {
|
||||||
|
return handle;
|
||||||
/// Deletes the internal OpenGL resource
|
}
|
||||||
void Release() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class OGLShader : public OGLResource {
|
|
||||||
public:
|
|
||||||
~OGLShader() override;
|
|
||||||
|
|
||||||
/// Creates a new internal OpenGL resource and stores the handle
|
/// Creates a new internal OpenGL resource and stores the handle
|
||||||
void Create(const char* vert_shader, const char* frag_shader);
|
void Create(const char* vert_shader, const char* frag_shader);
|
||||||
|
|
||||||
/// Deletes the internal OpenGL resource
|
/// Deletes the internal OpenGL resource
|
||||||
void Release() override;
|
void Release();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GLuint handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OGLBuffer : public OGLResource {
|
class OGLBuffer : public NonCopyable {
|
||||||
public:
|
public:
|
||||||
~OGLBuffer() override;
|
OGLBuffer();
|
||||||
|
~OGLBuffer();
|
||||||
|
|
||||||
|
/// Returns the internal OpenGL resource handle for this resource
|
||||||
|
inline GLuint GetHandle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new internal OpenGL resource and stores the handle
|
/// Creates a new internal OpenGL resource and stores the handle
|
||||||
void Create();
|
void Create();
|
||||||
|
|
||||||
/// Deletes the internal OpenGL resource
|
/// Deletes the internal OpenGL resource
|
||||||
void Release() override;
|
void Release();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GLuint handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OGLVertexArray : public OGLResource {
|
class OGLVertexArray : public NonCopyable {
|
||||||
public:
|
public:
|
||||||
~OGLVertexArray() override;
|
OGLVertexArray();
|
||||||
|
~OGLVertexArray();
|
||||||
|
|
||||||
|
/// Returns the internal OpenGL resource handle for this resource
|
||||||
|
inline GLuint GetHandle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new internal OpenGL resource and stores the handle
|
/// Creates a new internal OpenGL resource and stores the handle
|
||||||
void Create();
|
void Create();
|
||||||
|
|
||||||
/// Deletes the internal OpenGL resource
|
/// Deletes the internal OpenGL resource
|
||||||
void Release() override;
|
void Release();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GLuint handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OGLFramebuffer : public OGLResource {
|
class OGLFramebuffer : public NonCopyable {
|
||||||
public:
|
public:
|
||||||
~OGLFramebuffer() override;
|
OGLFramebuffer();
|
||||||
|
~OGLFramebuffer();
|
||||||
|
|
||||||
|
/// Returns the internal OpenGL resource handle for this resource
|
||||||
|
inline GLuint GetHandle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new internal OpenGL resource and stores the handle
|
/// Creates a new internal OpenGL resource and stores the handle
|
||||||
void Create();
|
void Create();
|
||||||
|
|
||||||
/// Deletes the internal OpenGL resource
|
/// Deletes the internal OpenGL resource
|
||||||
void Release() override;
|
void Release();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
GLuint handle;
|
||||||
};
|
};
|
||||||
|
@ -191,33 +191,33 @@ vec4 GetSource(int source) {
|
|||||||
return g_last_tex_env_out;
|
return g_last_tex_env_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec4(0.0, 0.0, 0.0, 0.0);
|
return vec4(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 GetColorModifier(int factor, vec4 color) {
|
vec3 GetColorModifier(int factor, vec4 color) {
|
||||||
if (factor == COLORMODIFIER_SOURCECOLOR) {
|
if (factor == COLORMODIFIER_SOURCECOLOR) {
|
||||||
return color.rgb;
|
return color.rgb;
|
||||||
} else if (factor == COLORMODIFIER_ONEMINUSSOURCECOLOR) {
|
} else if (factor == COLORMODIFIER_ONEMINUSSOURCECOLOR) {
|
||||||
return vec3(1.0, 1.0, 1.0) - color.rgb;
|
return vec3(1.0) - color.rgb;
|
||||||
} else if (factor == COLORMODIFIER_SOURCEALPHA) {
|
} else if (factor == COLORMODIFIER_SOURCEALPHA) {
|
||||||
return color.aaa;
|
return color.aaa;
|
||||||
} else if (factor == COLORMODIFIER_ONEMINUSSOURCEALPHA) {
|
} else if (factor == COLORMODIFIER_ONEMINUSSOURCEALPHA) {
|
||||||
return vec3(1.0, 1.0, 1.0) - color.aaa;
|
return vec3(1.0) - color.aaa;
|
||||||
} else if (factor == COLORMODIFIER_SOURCERED) {
|
} else if (factor == COLORMODIFIER_SOURCERED) {
|
||||||
return color.rrr;
|
return color.rrr;
|
||||||
} else if (factor == COLORMODIFIER_ONEMINUSSOURCERED) {
|
} else if (factor == COLORMODIFIER_ONEMINUSSOURCERED) {
|
||||||
return vec3(1.0, 1.0, 1.0) - color.rrr;
|
return vec3(1.0) - color.rrr;
|
||||||
} else if (factor == COLORMODIFIER_SOURCEGREEN) {
|
} else if (factor == COLORMODIFIER_SOURCEGREEN) {
|
||||||
return color.ggg;
|
return color.ggg;
|
||||||
} else if (factor == COLORMODIFIER_ONEMINUSSOURCEGREEN) {
|
} else if (factor == COLORMODIFIER_ONEMINUSSOURCEGREEN) {
|
||||||
return vec3(1.0, 1.0, 1.0) - color.ggg;
|
return vec3(1.0) - color.ggg;
|
||||||
} else if (factor == COLORMODIFIER_SOURCEBLUE) {
|
} else if (factor == COLORMODIFIER_SOURCEBLUE) {
|
||||||
return color.bbb;
|
return color.bbb;
|
||||||
} else if (factor == COLORMODIFIER_ONEMINUSSOURCEBLUE) {
|
} else if (factor == COLORMODIFIER_ONEMINUSSOURCEBLUE) {
|
||||||
return vec3(1.0, 1.0, 1.0) - color.bbb;
|
return vec3(1.0) - color.bbb;
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec3(0.0, 0.0, 0.0);
|
return vec3(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float GetAlphaModifier(int factor, vec4 color) {
|
float GetAlphaModifier(int factor, vec4 color) {
|
||||||
@ -250,9 +250,9 @@ vec3 ColorCombine(int op, vec3 color[3]) {
|
|||||||
} else if (op == OPERATION_ADD) {
|
} else if (op == OPERATION_ADD) {
|
||||||
return min(color[0] + color[1], 1.0);
|
return min(color[0] + color[1], 1.0);
|
||||||
} else if (op == OPERATION_ADDSIGNED) {
|
} else if (op == OPERATION_ADDSIGNED) {
|
||||||
return clamp(color[0] + color[1] - vec3(0.5, 0.5, 0.5), 0.0, 1.0);
|
return clamp(color[0] + color[1] - vec3(0.5), 0.0, 1.0);
|
||||||
} else if (op == OPERATION_LERP) {
|
} else if (op == OPERATION_LERP) {
|
||||||
return color[0] * color[2] + color[1] * (vec3(1.0, 1.0, 1.0) - color[2]);
|
return color[0] * color[2] + color[1] * (vec3(1.0) - color[2]);
|
||||||
} else if (op == OPERATION_SUBTRACT) {
|
} else if (op == OPERATION_SUBTRACT) {
|
||||||
return max(color[0] - color[1], 0.0);
|
return max(color[0] - color[1], 0.0);
|
||||||
} else if (op == OPERATION_MULTIPLYTHENADD) {
|
} else if (op == OPERATION_MULTIPLYTHENADD) {
|
||||||
@ -261,7 +261,7 @@ vec3 ColorCombine(int op, vec3 color[3]) {
|
|||||||
return min(color[0] + color[1], 1.0) * color[2];
|
return min(color[0] + color[1], 1.0) * color[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec3(0.0, 0.0, 0.0);
|
return vec3(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float AlphaCombine(int op, float alpha[3]) {
|
float AlphaCombine(int op, float alpha[3]) {
|
||||||
|
@ -42,7 +42,7 @@ OpenGLState::OpenGLState() {
|
|||||||
draw.shader_program = 0;
|
draw.shader_program = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::Apply() {
|
const void OpenGLState::Apply() {
|
||||||
// Culling
|
// Culling
|
||||||
if (cull.enabled) {
|
if (cull.enabled) {
|
||||||
if (cull.enabled != cur_state.cull.enabled) {
|
if (cull.enabled != cur_state.cull.enabled) {
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
} color; // GL_BLEND_COLOR
|
} color; // GL_BLEND_COLOR
|
||||||
} blend;
|
} blend;
|
||||||
|
|
||||||
|
// 3 texture units - one for each that is used in PICA fragment shader emulation
|
||||||
struct {
|
struct {
|
||||||
bool enabled_2d; // GL_TEXTURE_2D
|
bool enabled_2d; // GL_TEXTURE_2D
|
||||||
GLuint texture_2d; // GL_TEXTURE_BINDING_2D
|
GLuint texture_2d; // GL_TEXTURE_BINDING_2D
|
||||||
@ -57,12 +58,12 @@ public:
|
|||||||
OpenGLState();
|
OpenGLState();
|
||||||
|
|
||||||
/// Get the currently active OpenGL state
|
/// Get the currently active OpenGL state
|
||||||
static OpenGLState GetCurState() {
|
static const OpenGLState& GetCurState() {
|
||||||
return cur_state;
|
return cur_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply this state as the current OpenGL state
|
/// Apply this state as the current OpenGL state
|
||||||
void Apply();
|
const void Apply();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static OpenGLState cur_state;
|
static OpenGLState cur_state;
|
||||||
|
@ -348,7 +348,6 @@ void RendererOpenGL::UpdateFramerate() {
|
|||||||
*/
|
*/
|
||||||
void RendererOpenGL::SetWindow(EmuWindow* window) {
|
void RendererOpenGL::SetWindow(EmuWindow* window) {
|
||||||
render_window = window;
|
render_window = window;
|
||||||
hw_rasterizer->SetWindow(window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the renderer
|
/// Initialize the renderer
|
||||||
|
Loading…
Reference in New Issue
Block a user