summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorMarkus Wick <degasus@users.noreply.github.com>2015-09-17 18:42:17 +0200
committerMarkus Wick <degasus@users.noreply.github.com>2015-09-17 18:42:17 +0200
commitedae1d3bcb4383abd344757c4eab13d975a5e153 (patch)
tree4395c37354ac9d51ce86b6d029c6bbd8a9ca4bcf /Source
parent52de4cc476429d77240434c4c0c6fcaff353f39a (diff)
parent3b5b80bf3c209b01a4835a2aa0729fc6b3f38d40 (diff)
Merge pull request #3055 from degasus/videosw
Video Software cleanup
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/DolphinWX/SoftwareVideoConfigDialog.cpp3
-rw-r--r--Source/Core/VideoBackends/Software/CMakeLists.txt1
-rw-r--r--Source/Core/VideoBackends/Software/DebugUtil.cpp15
-rw-r--r--Source/Core/VideoBackends/Software/EfbCopy.cpp66
-rw-r--r--Source/Core/VideoBackends/Software/HwRasterizer.cpp382
-rw-r--r--Source/Core/VideoBackends/Software/HwRasterizer.h47
-rw-r--r--Source/Core/VideoBackends/Software/Rasterizer.cpp328
-rw-r--r--Source/Core/VideoBackends/Software/SWRenderer.cpp3
-rw-r--r--Source/Core/VideoBackends/Software/SWVideoConfig.cpp3
-rw-r--r--Source/Core/VideoBackends/Software/SWVideoConfig.h1
-rw-r--r--Source/Core/VideoBackends/Software/SWmain.cpp14
-rw-r--r--Source/Core/VideoBackends/Software/Software.vcxproj4
-rw-r--r--Source/Core/VideoBackends/Software/Tev.cpp207
13 files changed, 196 insertions, 878 deletions
diff --git a/Source/Core/DolphinWX/SoftwareVideoConfigDialog.cpp b/Source/Core/DolphinWX/SoftwareVideoConfigDialog.cpp
index dd747c4513..fb2fbddbcd 100644
--- a/Source/Core/DolphinWX/SoftwareVideoConfigDialog.cpp
+++ b/Source/Core/DolphinWX/SoftwareVideoConfigDialog.cpp
@@ -76,9 +76,6 @@ SoftwareVideoConfigDialog::SoftwareVideoConfigDialog(wxWindow* parent, const std
choice_backend->Disable();
}
- // rasterizer
- szr_rendering->Add(new SettingCheckBox(page_general, _("Hardware rasterization"), "", vconfig.bHwRasterizer));
-
// xfb
szr_rendering->Add(new SettingCheckBox(page_general, _("Bypass XFB"), "", vconfig.bBypassXFB));
}
diff --git a/Source/Core/VideoBackends/Software/CMakeLists.txt b/Source/Core/VideoBackends/Software/CMakeLists.txt
index 089261adcc..7b86ffae5c 100644
--- a/Source/Core/VideoBackends/Software/CMakeLists.txt
+++ b/Source/Core/VideoBackends/Software/CMakeLists.txt
@@ -5,7 +5,6 @@ set(SRCS BPMemLoader.cpp
DebugUtil.cpp
EfbCopy.cpp
EfbInterface.cpp
- HwRasterizer.cpp
SWmain.cpp
OpcodeDecoder.cpp
RasterFont.cpp
diff --git a/Source/Core/VideoBackends/Software/DebugUtil.cpp b/Source/Core/VideoBackends/Software/DebugUtil.cpp
index 4f7d732c0b..7be0692088 100644
--- a/Source/Core/VideoBackends/Software/DebugUtil.cpp
+++ b/Source/Core/VideoBackends/Software/DebugUtil.cpp
@@ -11,7 +11,6 @@
#include "VideoBackends/Software/BPMemLoader.h"
#include "VideoBackends/Software/DebugUtil.h"
#include "VideoBackends/Software/EfbInterface.h"
-#include "VideoBackends/Software/HwRasterizer.h"
#include "VideoBackends/Software/SWCommandProcessor.h"
#include "VideoBackends/Software/SWRenderer.h"
#include "VideoBackends/Software/SWStatistics.h"
@@ -25,8 +24,6 @@
namespace DebugUtil
{
-static bool drawingHwTriangles = false;
-
static const int NUM_OBJECT_BUFFERS = 40;
static u32 *ObjectBuffer[NUM_OBJECT_BUFFERS];
@@ -207,12 +204,6 @@ void OnObjectBegin()
{
if (g_SWVideoConfig.bDumpTextures && swstats.thisFrame.numDrawnObjects >= g_SWVideoConfig.drawStart && swstats.thisFrame.numDrawnObjects < g_SWVideoConfig.drawEnd)
DumpActiveTextures();
-
- if (g_SWVideoConfig.bHwRasterizer)
- {
- HwRasterizer::BeginTriangles();
- drawingHwTriangles = true;
- }
}
}
@@ -225,12 +216,6 @@ void OnObjectEnd()
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(),
swstats.thisFrame.numDrawnObjects));
- if (g_SWVideoConfig.bHwRasterizer || drawingHwTriangles)
- {
- HwRasterizer::EndTriangles();
- drawingHwTriangles = false;
- }
-
for (int i = 0; i < NUM_OBJECT_BUFFERS; i++)
{
if (DrawnToBuffer[i])
diff --git a/Source/Core/VideoBackends/Software/EfbCopy.cpp b/Source/Core/VideoBackends/Software/EfbCopy.cpp
index 688a5cddb9..42759e20e9 100644
--- a/Source/Core/VideoBackends/Software/EfbCopy.cpp
+++ b/Source/Core/VideoBackends/Software/EfbCopy.cpp
@@ -9,7 +9,6 @@
#include "VideoBackends/Software/DebugUtil.h"
#include "VideoBackends/Software/EfbCopy.h"
#include "VideoBackends/Software/EfbInterface.h"
-#include "VideoBackends/Software/HwRasterizer.h"
#include "VideoBackends/Software/SWCommandProcessor.h"
#include "VideoBackends/Software/SWRenderer.h"
#include "VideoBackends/Software/SWStatistics.h"
@@ -31,47 +30,41 @@ namespace EfbCopy
{
GLInterface->Update(); // update the render window position and the backbuffer size
- if (!g_SWVideoConfig.bHwRasterizer)
- {
- INFO_LOG(VIDEO, "xfbaddr: %x, fbwidth: %i, fbheight: %i, source: (%i, %i, %i, %i), Gamma %f",
- xfbAddr, fbWidth, fbHeight, sourceRc.top, sourceRc.left, sourceRc.bottom, sourceRc.right, Gamma);
+ INFO_LOG(VIDEO, "xfbaddr: %x, fbwidth: %i, fbheight: %i, source: (%i, %i, %i, %i), Gamma %f",
+ xfbAddr, fbWidth, fbHeight, sourceRc.top, sourceRc.left, sourceRc.bottom, sourceRc.right, Gamma);
- if (!g_SWVideoConfig.bBypassXFB)
- {
- EfbInterface::yuv422_packed* xfb_in_ram = (EfbInterface::yuv422_packed *) Memory::GetPointer(xfbAddr);
+ if (!g_SWVideoConfig.bBypassXFB)
+ {
+ EfbInterface::yuv422_packed* xfb_in_ram = (EfbInterface::yuv422_packed *) Memory::GetPointer(xfbAddr);
- EfbInterface::CopyToXFB(xfb_in_ram, fbWidth, fbHeight, sourceRc, Gamma);
- }
- else
- {
- // Ask SWRenderer for the next color texture
- u8 *colorTexture = SWRenderer::GetNextColorTexture();
-
- EfbInterface::BypassXFB(colorTexture, fbWidth, fbHeight, sourceRc, Gamma);
-
- // Tell SWRenderer we are now finished with it.
- SWRenderer::SwapColorTexture();
-
- // FifoPlayer is broken and never calls BeginFrame/EndFrame.
- // Hence, we manually force a swap now. This emulates the behavior
- // of hardware backends with XFB emulation disabled.
- // TODO: Fix FifoPlayer by making proper use of VideoInterface!
- // This requires careful synchronization since GPU commands
- // are processed on a different thread than VI commands.
- SWRenderer::Swap(fbWidth, fbHeight);
- DebugUtil::OnFrameEnd(fbWidth, fbHeight);
- }
+ EfbInterface::CopyToXFB(xfb_in_ram, fbWidth, fbHeight, sourceRc, Gamma);
+ }
+ else
+ {
+ // Ask SWRenderer for the next color texture
+ u8 *colorTexture = SWRenderer::GetNextColorTexture();
+
+ EfbInterface::BypassXFB(colorTexture, fbWidth, fbHeight, sourceRc, Gamma);
+
+ // Tell SWRenderer we are now finished with it.
+ SWRenderer::SwapColorTexture();
+
+ // FifoPlayer is broken and never calls BeginFrame/EndFrame.
+ // Hence, we manually force a swap now. This emulates the behavior
+ // of hardware backends with XFB emulation disabled.
+ // TODO: Fix FifoPlayer by making proper use of VideoInterface!
+ // This requires careful synchronization since GPU commands
+ // are processed on a different thread than VI commands.
+ SWRenderer::Swap(fbWidth, fbHeight);
+ DebugUtil::OnFrameEnd(fbWidth, fbHeight);
}
}
static void CopyToRam()
{
- if (!g_SWVideoConfig.bHwRasterizer)
- {
- u8 *dest_ptr = Memory::GetPointer(bpmem.copyTexDest << 5);
+ u8 *dest_ptr = Memory::GetPointer(bpmem.copyTexDest << 5);
- TextureEncoder::Encode(dest_ptr);
- }
+ TextureEncoder::Encode(dest_ptr);
}
static void ClearEfb()
@@ -138,10 +131,7 @@ namespace EfbCopy
if (bpmem.triggerEFBCopy.clear)
{
- if (g_SWVideoConfig.bHwRasterizer)
- HwRasterizer::Clear();
- else
- ClearEfb();
+ ClearEfb();
}
}
}
diff --git a/Source/Core/VideoBackends/Software/HwRasterizer.cpp b/Source/Core/VideoBackends/Software/HwRasterizer.cpp
deleted file mode 100644
index 7ddf15bb38..0000000000
--- a/Source/Core/VideoBackends/Software/HwRasterizer.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright 2009 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-#include "Common/CommonTypes.h"
-#include "Common/MemoryUtil.h"
-
-#include "VideoBackends/OGL/GLInterfaceBase.h"
-#include "VideoBackends/Software/BPMemLoader.h"
-#include "VideoBackends/Software/DebugUtil.h"
-#include "VideoBackends/Software/HwRasterizer.h"
-#include "VideoBackends/Software/NativeVertexFormat.h"
-
-#include "VideoCommon/VideoCommon.h"
-
-#define TEMP_SIZE (1024*1024*4)
-
-namespace HwRasterizer
-{
- static float efbHalfWidth;
- static float efbHalfHeight;
- static bool hasTexture;
-
- static u8 *temp;
-
- // Programs
- static GLuint colProg, texProg, clearProg;
-
- // Texture type
- static GLenum texType;
-
- // Color
- static GLint col_apos = -1, col_atex = -1;
- // Tex
- static GLint tex_apos = -1, tex_atex = -1, tex_utex = -1;
- // Clear shader
- static GLint clear_apos = -1, clear_ucol = -1;
-
- static void CreateShaders()
- {
- // Color Vertices
- static const char *fragcolText =
- "#ifdef GL_ES\n"
- "precision highp float;\n"
- "#endif\n"
- "varying vec4 TexCoordOut;\n"
- "void main() {\n"
- " gl_FragColor = TexCoordOut;\n"
- "}\n";
- // Texture Vertices
- static const char *fragtexText =
- "#ifdef GL_ES\n"
- "precision highp float;\n"
- "#define texture2DRect texture2D\n"
- "#define sampler2DRect sampler2D\n"
- "#endif\n"
- "varying vec4 TexCoordOut;\n"
- "uniform sampler2DRect Texture;\n"
- "void main() {\n"
- " gl_FragColor = texture2DRect(Texture, TexCoordOut.xy);\n"
- "}\n";
- // Clear shader
- static const char *fragclearText =
- "#ifdef GL_ES\n"
- "precision highp float;\n"
- "#endif\n"
- "uniform vec4 Color;\n"
- "void main() {\n"
- " gl_FragColor = Color;\n"
- "}\n";
- // Generic passthrough vertice shaders
- static const char *vertShaderText =
- "attribute vec4 pos;\n"
- "attribute vec4 TexCoordIn;\n "
- "varying vec4 TexCoordOut;\n "
- "void main() {\n"
- " gl_Position = pos;\n"
- " TexCoordOut = TexCoordIn;\n"
- "}\n";
- static const char *vertclearText =
- "attribute vec4 pos;\n"
- "void main() {\n"
- " gl_Position = pos;\n"
- "}\n";
-
- // Color Program
- colProg = OpenGL_CompileProgram(vertShaderText, fragcolText);
-
- // Texture Program
- texProg = OpenGL_CompileProgram(vertShaderText, fragtexText);
-
- // Clear Program
- clearProg = OpenGL_CompileProgram(vertclearText, fragclearText);
-
- // Color attributes
- col_apos = glGetAttribLocation(colProg, "pos");
- col_atex = glGetAttribLocation(colProg, "TexCoordIn");
- // Texture attributes
- tex_apos = glGetAttribLocation(texProg, "pos");
- tex_atex = glGetAttribLocation(texProg, "TexCoordIn");
- tex_utex = glGetUniformLocation(texProg, "Texture");
- // Clear attributes
- clear_apos = glGetAttribLocation(clearProg, "pos");
- clear_ucol = glGetUniformLocation(clearProg, "Color");
- }
-
- void Init()
- {
- efbHalfWidth = EFB_WIDTH / 2.0f;
- efbHalfHeight = 480 / 2.0f;
-
- temp = (u8*)AllocateMemoryPages(TEMP_SIZE);
- }
- void Shutdown()
- {
- glDeleteProgram(colProg);
- glDeleteProgram(texProg);
- glDeleteProgram(clearProg);
- }
- void Prepare()
- {
- //legacy multitexturing: select texture channel only.
- glActiveTexture(GL_TEXTURE0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment
- if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL)
- {
- glShadeModel(GL_SMOOTH);
- glDisable(GL_BLEND);
- glClearDepth(1.0f);
- glEnable(GL_SCISSOR_TEST);
- glDisable(GL_LIGHTING);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glClientActiveTexture(GL_TEXTURE0);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glEnable(GL_TEXTURE_RECTANGLE_ARB);
- glStencilFunc(GL_ALWAYS, 0, 0);
- glDisable(GL_STENCIL_TEST);
- }
- // used by hw rasterizer if it enables blending and depth test
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDepthFunc(GL_LEQUAL);
-
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
- CreateShaders();
- if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL)
- texType = GL_TEXTURE_RECTANGLE;
- else
- texType = GL_TEXTURE_2D;
- }
- static float width, height;
- static void LoadTexture()
- {
- FourTexUnits &texUnit = bpmem.tex[0];
- u32 imageAddr = texUnit.texImage3[0].image_base;
- // Texture Rectangle uses pixel coordinates
- // While GLES uses texture coordinates
- if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL)
- {
- width = (float)texUnit.texImage0[0].width;
- height = (float)texUnit.texImage0[0].height;
- }
- else
- {
- width = 1;
- height = 1;
- }
- TexCacheEntry &cacheEntry = textures[imageAddr];
- cacheEntry.Update();
-
- glBindTexture(texType, cacheEntry.texture);
- glTexParameteri(texType, GL_TEXTURE_MAG_FILTER, texUnit.texMode0[0].mag_filter ? GL_LINEAR : GL_NEAREST);
- glTexParameteri(texType, GL_TEXTURE_MIN_FILTER, (texUnit.texMode0[0].min_filter >= 4) ? GL_LINEAR : GL_NEAREST);
- }
-
- void BeginTriangles()
- {
- // disabling depth test sometimes allows more things to be visible
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
-
- hasTexture = bpmem.tevorders[0].enable0;
-
- if (hasTexture)
- LoadTexture();
- }
-
- void EndTriangles()
- {
- glBindTexture(texType, 0);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
- }
-
- static void DrawColorVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
- {
- float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f;
- float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight);
- float z0 = v0->screenPosition.z / (float)0x00ffffff;
-
- float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f;
- float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight);
- float z1 = v1->screenPosition.z / (float)0x00ffffff;
-
- float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f;
- float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight);
- float z2 = v2->screenPosition.z / (float)0x00ffffff;
-
- float r0 = v0->color[0][OutputVertexData::RED_C] / 255.0f;
- float g0 = v0->color[0][OutputVertexData::GRN_C] / 255.0f;
- float b0 = v0->color[0][OutputVertexData::BLU_C] / 255.0f;
-
- float r1 = v1->color[0][OutputVertexData::RED_C] / 255.0f;
- float g1 = v1->color[0][OutputVertexData::GRN_C] / 255.0f;
- float b1 = v1->color[0][OutputVertexData::BLU_C] / 255.0f;
-
- float r2 = v2->color[0][OutputVertexData::RED_C] / 255.0f;
- float g2 = v2->color[0][OutputVertexData::GRN_C] / 255.0f;
- float b2 = v2->color[0][OutputVertexData::BLU_C] / 255.0f;
-
- static const GLfloat verts[3][3] = {
- { x0, y0, z0 },
- { x1, y1, z1 },
- { x2, y2, z2 }
- };
- static const GLfloat col[3][4] = {
- { r0, g0, b0, 1.0f },
- { r1, g1, b1, 1.0f },
- { r2, g2, b2, 1.0f }
- };
- {
- glUseProgram(colProg);
- glEnableVertexAttribArray(col_apos);
- glEnableVertexAttribArray(col_atex);
-
- glVertexAttribPointer(col_apos, 3, GL_FLOAT, GL_FALSE, 0, verts);
- glVertexAttribPointer(col_atex, 4, GL_FLOAT, GL_FALSE, 0, col);
- glDrawArrays(GL_TRIANGLES, 0, 3);
- glDisableVertexAttribArray(col_atex);
- glDisableVertexAttribArray(col_apos);
- }
- }
-
- static void DrawTextureVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
- {
- float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f;
- float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight);
- float z0 = v0->screenPosition.z;
-
- float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f;
- float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight);
- float z1 = v1->screenPosition.z;
-
- float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f;
- float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight);
- float z2 = v2->screenPosition.z;
-
- float s0 = v0->texCoords[0].x / width;
- float t0 = v0->texCoords[0].y / height;
-
- float s1 = v1->texCoords[0].x / width;
- float t1 = v1->texCoords[0].y / height;
-
- float s2 = v2->texCoords[0].x / width;
- float t2 = v2->texCoords[0].y / height;
-
- static const GLfloat verts[3][3] = {
- { x0, y0, z0 },
- { x1, y1, z1 },
- { x2, y2, z2 }
- };
- static const GLfloat tex[3][2] = {
- { s0, t0 },
- { s1, t1 },
- { s2, t2 }
- };
- {
- glUseProgram(texProg);
- glEnableVertexAttribArray(tex_apos);
- glEnableVertexAttribArray(tex_atex);
-
- glVertexAttribPointer(tex_apos, 3, GL_FLOAT, GL_FALSE, 0, verts);
- glVertexAttribPointer(tex_atex, 2, GL_FLOAT, GL_FALSE, 0, tex);
- glUniform1i(tex_utex, 0);
- glDrawArrays(GL_TRIANGLES, 0, 3);
- glDisableVertexAttribArray(tex_atex);
- glDisableVertexAttribArray(tex_apos);
- }
- }
-
- void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2)
- {
- if (hasTexture)
- DrawTextureVertex(v0, v1, v2);
- else
- DrawColorVertex(v0, v1, v2);
- }
-
- void Clear()
- {
- u8 r = (bpmem.clearcolorAR & 0x00ff);
- u8 g = (bpmem.clearcolorGB & 0xff00) >> 8;
- u8 b = (bpmem.clearcolorGB & 0x00ff);
- u8 a = (bpmem.clearcolorAR & 0xff00) >> 8;
-
- GLfloat left = (GLfloat)bpmem.copyTexSrcXY.x / efbHalfWidth - 1.0f;
- GLfloat top = 1.0f - (GLfloat)bpmem.copyTexSrcXY.y / efbHalfHeight;
- GLfloat right = (GLfloat)(left + bpmem.copyTexSrcWH.x + 1) / efbHalfWidth - 1.0f;
- GLfloat bottom = 1.0f - (GLfloat)(top + bpmem.copyTexSrcWH.y + 1) / efbHalfHeight;
- GLfloat depth = (GLfloat)bpmem.clearZValue / (GLfloat)0x00ffffff;
- static const GLfloat verts[4][3] = {
- { left, top, depth },
- { right, top, depth },
- { right, bottom, depth },
- { left, bottom, depth }
- };
- {
- glUseProgram(clearProg);
- glVertexAttribPointer(clear_apos, 3, GL_FLOAT, GL_FALSE, 0, verts);
- glUniform4f(clear_ucol, r, g, b, a);
- glEnableVertexAttribArray(col_apos);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableVertexAttribArray(col_apos);
- }
- }
-
- TexCacheEntry::TexCacheEntry()
- {
- Create();
- }
-
- void TexCacheEntry::Create()
- {
- FourTexUnits &texUnit = bpmem.tex[0];
-
- texImage0.hex = texUnit.texImage0[0].hex;
- texImage1.hex = texUnit.texImage1[0].hex;
- texImage2.hex = texUnit.texImage2[0].hex;
- texImage3.hex = texUnit.texImage3[0].hex;
- texTlut.hex = texUnit.texTlut[0].hex;
-
- int image_width = texImage0.width;
- int image_height = texImage0.height;
-
- DebugUtil::GetTextureRGBA(temp, 0, 0, image_width, image_height);
-
- glGenTextures(1, (GLuint *)&texture);
- glBindTexture(texType, texture);
- glTexImage2D(texType, 0, GL_RGBA, (GLsizei)image_width, (GLsizei)image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp);
- }
-
- void TexCacheEntry::Destroy()
- {
- if (texture == 0)
- return;
-
- glDeleteTextures(1, &texture);
- texture = 0;
- }
-
- void TexCacheEntry::Update()
- {
- FourTexUnits &texUnit = bpmem.tex[0];
-
- // extra checks cause textures to be reloaded much more
- if (texUnit.texImage0[0].hex != texImage0.hex ||
- // texUnit.texImage1[0].hex != texImage1.hex ||
- // texUnit.texImage2[0].hex != texImage2.hex ||
- texUnit.texImage3[0].hex != texImage3.hex ||
- texUnit.texTlut[0].hex != texTlut.hex)
- {
- Destroy();
- Create();
- }
- }
-}
-
diff --git a/Source/Core/VideoBackends/Software/HwRasterizer.h b/Source/Core/VideoBackends/Software/HwRasterizer.h
deleted file mode 100644
index a58f5416c4..0000000000
--- a/Source/Core/VideoBackends/Software/HwRasterizer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2009 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <map>
-
-#include "VideoBackends/OGL/GLUtil.h"
-#include "VideoBackends/Software/BPMemLoader.h"
-
-struct OutputVertexData;
-
-namespace HwRasterizer
-{
- void Init();
- void Shutdown();
-
- void Prepare();
-
- void BeginTriangles();
- void EndTriangles();
-
- void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2);
-
- void Clear();
-
- struct TexCacheEntry
- {
- TexImage0 texImage0;
- TexImage1 texImage1;
- TexImage2 texImage2;
- TexImage3 texImage3;
- TexTLUT texTlut;
-
- GLuint texture;
-
- TexCacheEntry();
-
- void Create();
- void Destroy();
- void Update();
- };
-
- typedef std::map<u32, TexCacheEntry> TextureCache;
- static TextureCache textures;
-}
diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp
index 9b6b9f593a..0db2765944 100644
--- a/Source/Core/VideoBackends/Software/Rasterizer.cpp
+++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp
@@ -7,7 +7,6 @@
#include "Common/CommonTypes.h"
#include "VideoBackends/Software/BPMemLoader.h"
#include "VideoBackends/Software/EfbInterface.h"
-#include "VideoBackends/Software/HwRasterizer.h"
#include "VideoBackends/Software/NativeVertexFormat.h"
#include "VideoBackends/Software/Rasterizer.h"
#include "VideoBackends/Software/SWStatistics.h"
@@ -129,7 +128,7 @@ inline void Draw(s32 x, s32 y, s32 xi, s32 yi)
s32 z = (s32)MathUtil::Clamp<float>(ZSlope.GetValue(dx, dy), 0.0f, 16777215.0f);
- if (!BoundingBox::active && bpmem.UseEarlyDepthTest() && g_SWVideoConfig.bZComploc)
+ if (bpmem.UseEarlyDepthTest() && g_SWVideoConfig.bZComploc)
{
// TODO: Test if perf regs are incremented even if test is disabled
EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_INPUT_ZCOMPLOC);
@@ -332,12 +331,6 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
{
INCSTAT(swstats.thisFrame.numTrianglesDrawn);
- if (g_SWVideoConfig.bHwRasterizer && !BoundingBox::active)
- {
- HwRasterizer::DrawTriangleFrontFace(v0, v1, v2);
- return;
- }
-
// adapted from http://devmaster.net/posts/6145/advanced-rasterization
// 28.4 fixed-pou32 coordinates. rounded to nearest and adjusted to match hardware output
@@ -425,279 +418,86 @@ void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVer
if (DY23 < 0 || (DY23 == 0 && DX23 > 0)) C2++;
if (DY31 < 0 || (DY31 == 0 && DX31 > 0)) C3++;
- // If drawing, rasterize every block
- if (!BoundingBox::active)
- {
- // Start in corner of 8x8 block
- minx &= ~(BLOCK_SIZE - 1);
- miny &= ~(BLOCK_SIZE - 1);
+ // Start in corner of 8x8 block
+ minx &= ~(BLOCK_SIZE - 1);
+ miny &= ~(BLOCK_SIZE - 1);
- // Loop through blocks
- for (s32 y = miny; y < maxy; y += BLOCK_SIZE)
+ // Loop through blocks
+ for (s32 y = miny; y < maxy; y += BLOCK_SIZE)
+ {
+ for (s32 x = minx; x < maxx; x += BLOCK_SIZE)
{
- for (s32 x = minx; x < maxx; x += BLOCK_SIZE)
+ // Corners of block
+ s32 x0 = x << 4;
+ s32 x1 = (x + BLOCK_SIZE - 1) << 4;
+ s32 y0 = y << 4;
+ s32 y1 = (y + BLOCK_SIZE - 1) << 4;
+
+ // Evaluate half-space functions
+ bool a00 = C1 + DX12 * y0 - DY12 * x0 > 0;
+ bool a10 = C1 + DX12 * y0 - DY12 * x1 > 0;
+ bool a01 = C1 + DX12 * y1 - DY12 * x0 > 0;
+ bool a11 = C1 + DX12 * y1 - DY12 * x1 > 0;
+ int a = (a00 << 0) | (a10 << 1) | (a01 << 2) | (a11 << 3);
+
+ bool b00 = C2 + DX23 * y0 - DY23 * x0 > 0;
+ bool b10 = C2 + DX23 * y0 - DY23 * x1 > 0;
+ bool b01 = C2 + DX23 * y1 - DY23 * x0 > 0;
+ bool b11 = C2 + DX23 * y1 - DY23 * x1 > 0;
+ int b = (b00 << 0) | (b10 << 1) | (b01 << 2) | (b11 << 3);
+
+ bool c00 = C3 + DX31 * y0 - DY31 * x0 > 0;
+ bool c10 = C3 + DX31 * y0 - DY31 * x1 > 0;
+ bool c01 = C3 + DX31 * y1 - DY31 * x0 > 0;
+ bool c11 = C3 + DX31 * y1 - DY31 * x1 > 0;
+ int c = (c00 << 0) | (c10 << 1) | (c01 << 2) | (c11 << 3);
+
+ // Skip block when outside an edge
+ if (a == 0x0 || b == 0x0 || c == 0x0)
+ continue;
+
+ BuildBlock(x, y);
+
+ // Accept whole block when totally covered
+ if (a == 0xF && b == 0xF && c == 0xF)
{
- // Corners of block
- s32 x0 = x << 4;
- s32 x1 = (x + BLOCK_SIZE - 1) << 4;
- s32 y0 = y << 4;
- s32 y1 = (y + BLOCK_SIZE - 1) << 4;
-
- // Evaluate half-space functions
- bool a00 = C1 + DX12 * y0 - DY12 * x0 > 0;
- bool a10 = C1 + DX12 * y0 - DY12 * x1 > 0;
- bool a01 = C1 + DX12 * y1 - DY12 * x0 > 0;
- bool a11 = C1 + DX12 * y1 - DY12 * x1 > 0;
- int a = (a00 << 0) | (a10 << 1) | (a01 << 2) | (a11 << 3);
-
- bool b00 = C2 + DX23 * y0 - DY23 * x0 > 0;
- bool b10 = C2 + DX23 * y0 - DY23 * x1 > 0;
- bool b01 = C2 + DX23 * y1 - DY23 * x0 > 0;
- bool b11 = C2 + DX23 * y1 - DY23 * x1 > 0;
- int b = (b00 << 0) | (b10 << 1) | (b01 << 2) | (b11 << 3);
-
- bool c00 = C3 + DX31 * y0 - DY31 * x0 > 0;
- bool c10 = C3 + DX31 * y0 - DY31 * x1 > 0;
- bool c01 = C3 + DX31 * y1 - DY31 * x0 > 0;
- bool c11 = C3 + DX31 * y1 - DY31 * x1 > 0;
- int c = (c00 << 0) | (c10 << 1) | (c01 << 2) | (c11 << 3);
-
- // Skip block when outside an edge
- if (a == 0x0 || b == 0x0 || c == 0x0)
- continue;
-
- BuildBlock(x, y);
-
- // Accept whole block when totally covered
- if (a == 0xF && b == 0xF && c == 0xF)
+ for (s32 iy = 0; iy < BLOCK_SIZE; iy++)
{
- for (s32 iy = 0; iy < BLOCK_SIZE; iy++)
+ for (s32 ix = 0; ix < BLOCK_SIZE; ix++)
{
- for (s32 ix = 0; ix < BLOCK_SIZE; ix++)
- {
- Draw(x + ix, y + iy, ix, iy);
- }
+ Draw(x + ix, y + iy, ix, iy);
}
}
- else // Partially covered block
+ }
+ else // Partially covered block
+ {
+ s32 CY1 = C1 + DX12 * y0 - DY12 * x0;
+ s32 CY2 = C2 + DX23 * y0 - DY23 * x0;
+ s32 CY3 = C3 + DX31 * y0 - DY31 * x0;
+
+ for (s32 iy = 0; iy < BLOCK_SIZE; iy++)
{
- s32 CY1 = C1 + DX12 * y0 - DY12 * x0;
- s32 CY2 = C2 + DX23 * y0 - DY23 * x0;
- s32 CY3 = C3 + DX31 * y0 - DY31 * x0;
+ s32 CX1 = CY1;
+ s32 CX2 = CY2;
+ s32 CX3 = CY3;
- for (s32 iy = 0; iy < BLOCK_SIZE; iy++)
+ for (s32 ix = 0; ix < BLOCK_SIZE; ix++)
{
- s32 CX1 = CY1;
- s32 CX2 = CY2;
- s32 CX3 = CY3;
-
- for (s32 ix = 0; ix < BLOCK_SIZE; ix++)
+ if (CX1 > 0 && CX2 > 0 && CX3 > 0)
{
- if (CX1 > 0 && CX2 > 0 && CX3 > 0)
- {
- Draw(x + ix, y + iy, ix, iy);
- }
-
- CX1 -= FDY12;
- CX2 -= FDY23;
- CX3 -= FDY31;
+ Draw(x + ix, y + iy, ix, iy);
}
- CY1 += FDX12;
- CY2 += FDX23;
- CY3 += FDX31;
+ CX1 -= FDY12;
+ CX2 -= FDY23;
+ CX3 -= FDY31;
}
- }
- }
- }
- }
- else
- {
- // Calculating bbox
- // First check for alpha channel - don't do anything it if always fails,
- // Change bbox to primitive size if it always passes
- AlphaTest::TEST_RESULT alphaRes = bpmem.alpha_test.TestResult();
-
- if (alphaRes != AlphaTest::UNDETERMINED)
- {
- if (alphaRes == AlphaTest::PASS)
- {
- BoundingBox::coords[BoundingBox::TOP] = std::min(BoundingBox::coords[BoundingBox::TOP], (u16) miny);
- BoundingBox::coords[BoundingBox::LEFT] = std::min(BoundingBox::coords[BoundingBox::LEFT], (u16) minx);
- BoundingBox::coords[BoundingBox::BOTTOM] = std::max(BoundingBox::coords[BoundingBox::BOTTOM], (u16) maxy);
- BoundingBox::coords[BoundingBox::RIGHT] = std::max(BoundingBox::coords[BoundingBox::RIGHT], (u16) maxx);
- }
- return;
- }
-
- // If we are calculating bbox with alpha, we only need to find the
- // topmost, leftmost, bottom most and rightmost pixels to be drawn.
- // So instead of drawing every single one of the triangle's pixels,
- // four loops are run: one for the top pixel, one for the left, one for
- // the bottom and one for the right. As soon as a pixel that is to be
- // drawn is found, the loop breaks. This enables a ~150% speedbost in
- // bbox calculation, albeit at the cost of some ugly repetitive code.
- const s32 FLEFT = minx << 4;
- const s32 FRIGHT = maxx << 4;
- s32 FTOP = miny << 4;
- s32 FBOTTOM = maxy << 4;
-
- // Start checking for bbox top
- s32 CY1 = C1 + DX12 * FTOP - DY12 * FLEFT;
- s32 CY2 = C2 + DX23 * FTOP - DY23 * FLEFT;
- s32 CY3 = C3 + DX31 * FTOP - DY31 * FLEFT;
-
- // Loop
- for (s32 y = miny; y <= maxy; ++y)
- {
- if (y >= BoundingBox::coords[BoundingBox::TOP])
- break;
- s32 CX1 = CY1;
- s32 CX2 = CY2;
- s32 CX3 = CY3;
-
- for (s32 x = minx; x <= maxx; ++x)
- {
- if (CX1 > 0 && CX2 > 0 && CX3 > 0)
- {
- // Build the new raster block every other pixel
- PrepareBlock(x, y);
- Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
-
- if (y >= BoundingBox::coords[BoundingBox::TOP])
- break;
+ CY1 += FDX12;
+ CY2 += FDX23;
+ CY3 += FDX31;
}
-
- CX1 -= FDY12;
- CX2 -= FDY23;
- CX3 -= FDY31;
}
-
- CY1 += FDX12;
- CY2 += FDX23;
- CY3 += FDX31;
- }
-
- // Update top limit
- miny = std::max((s32) BoundingBox::coords[BoundingBox::TOP], miny);
- FTOP = miny << 4;
-
- // Checking for bbox left
- s32 CX1 = C1 + DX12 * FTOP - DY12 * FLEFT;
- s32 CX2 = C2 + DX23 * FTOP - DY23 * FLEFT;
- s32 CX3 = C3 + DX31 * FTOP - DY31 * FLEFT;
-
- // Loop
- for (s32 x = minx; x <= maxx; ++x)
- {
- if (x >= BoundingBox::coords[BoundingBox::LEFT])
- break;
-
- CY1 = CX1;
- CY2 = CX2;
- CY3 = CX3;
-
- for (s32 y = miny; y <= maxy; ++y)
- {
- if (CY1 > 0 && CY2 > 0 && CY3 > 0)
- {
- PrepareBlock(x, y);
- Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
-
- if (x >= BoundingBox::coords[BoundingBox::LEFT])
- break;
- }
-
- CY1 += FDX12;
- CY2 += FDX23;
- CY3 += FDX31;
- }
-
- CX1 -= FDY12;
- CX2 -= FDY23;
- CX3 -= FDY31;
- }
-
- // Update left limit
- minx = std::max((s32) BoundingBox::coords[BoundingBox::LEFT], minx);
-
- // Checking for bbox bottom
- CY1 = C1 + DX12 * FBOTTOM - DY12 * FRIGHT;
- CY2 = C2 + DX23 * FBOTTOM - DY23 * FRIGHT;
- CY3 = C3 + DX31 * FBOTTOM - DY31 * FRIGHT;
-
- // Loop
- for (s32 y = maxy; y >= miny; --y)
- {
- CX1 = CY1;
- CX2 = CY2;
- CX3 = CY3;
-
- if (y <= BoundingBox::coords[BoundingBox::BOTTOM])
- break;
-
- for (s32 x = maxx; x >= minx; --x)
- {
- if (CX1 > 0 && CX2 > 0 && CX3 > 0)
- {
- // Build the new raster block every other pixel
- PrepareBlock(x, y);
- Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
-
- if (y <= BoundingBox::coords[BoundingBox::BOTTOM])
- break;
- }
-
- CX1 += FDY12;
- CX2 += FDY23;
- CX3 += FDY31;
- }
-
- CY1 -= FDX12;
- CY2 -= FDX23;
- CY3 -= FDX31;
- }
-
- // Update bottom limit
- maxy = std::min((s32) BoundingBox::coords[BoundingBox::BOTTOM], maxy);
- FBOTTOM = maxy << 4;
-
- // Checking for bbox right
- CX1 = C1 + DX12 * FBOTTOM - DY12 * FRIGHT;
- CX2 = C2 + DX23 * FBOTTOM - DY23 * FRIGHT;
- CX3 = C3 + DX31 * FBOTTOM - DY31 * FRIGHT;
-
- // Loop
- for (s32 x = maxx; x >= minx; --x)
- {
- if (x <= BoundingBox::coords[BoundingBox::RIGHT])
- break;
-
- CY1 = CX1;
- CY2 = CX2;
- CY3 = CX3;
-
- for (s32 y = maxy; y >= miny; --y)
- {
- if (CY1 > 0 && CY2 > 0 && CY3 > 0)
- {
- // Build the new raster block every other pixel
- PrepareBlock(x, y);
- Draw(x, y, x & (BLOCK_SIZE - 1), y & (BLOCK_SIZE - 1));
-
- if (x <= BoundingBox::coords[BoundingBox::RIGHT])
- break;
- }
-
- CY1 -= FDX12;
- CY2 -= FDX23;
- CY3 -= FDX31;
- }
-
- CX1 += FDY12;
- CX2 += FDY23;
- CX3 += FDY31;
}
}
}
diff --git a/Source/Core/VideoBackends/Software/SWRenderer.cpp b/Source/Core/VideoBackends/Software/SWRenderer.cpp
index 761cc667df..df005fee40 100644
--- a/Source/Core/VideoBackends/Software/SWRenderer.cpp
+++ b/Source/Core/VideoBackends/Software/SWRenderer.cpp
@@ -211,8 +211,7 @@ void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidt
void SWRenderer::Swap(u32 fbWidth, u32 fbHeight)
{
GLInterface->Update(); // just updates the render window position and the backbuffer size
- if (!g_SWVideoConfig.bHwRasterizer)
- SWRenderer::DrawTexture(GetCurrentColorTexture(), fbWidth, fbHeight);
+ SWRenderer::DrawTexture(GetCurrentColorTexture(), fbWidth, fbHeight);
swstats.frameCount++;
SWRenderer::SwapBuffer();
diff --git a/Source/Core/VideoBackends/Software/SWVideoConfig.cpp b/Source/Core/VideoBackends/Software/SWVideoConfig.cpp
index 0d5fd12489..4bd011e2df 100644
--- a/Source/Core/VideoBackends/Software/SWVideoConfig.cpp
+++ b/Source/Core/VideoBackends/Software/SWVideoConfig.cpp
@@ -14,7 +14,6 @@ SWVideoConfig::SWVideoConfig()
bHideCursor = false;
renderToMainframe = false;
- bHwRasterizer = false;
bBypassXFB = false;
bShowStats = false;
@@ -42,7 +41,6 @@ void SWVideoConfig::Load(const char* ini_file)
hardware->Get("RenderToMainframe", &renderToMainframe, false);
IniFile::Section* rendering = iniFile.GetOrCreateSection("Rendering");
- rendering->Get("HwRasterizer", &bHwRasterizer, false);
rendering->Get("BypassXFB", &bBypassXFB, false);
rendering->Get("ZComploc", &bZComploc, true);
rendering->Get("ZFreeze", &bZFreeze, true);
@@ -71,7 +69,6 @@ void SWVideoConfig::Save(const char* ini_file)
hardware->Set("RenderToMainframe", renderToMainframe);
IniFile::Section* rendering = iniFile.GetOrCreateSection("Rendering");
- rendering->Set("HwRasterizer", bHwRasterizer);
rendering->Set("BypassXFB", bBypassXFB);
rendering->Set("ZComploc", bZComploc);
rendering->Set("ZFreeze", bZFreeze);
diff --git a/Source/Core/VideoBackends/Software/SWVideoConfig.h b/Source/Core/VideoBackends/Software/SWVideoConfig.h
index cd3ec9f0c3..7a58af41a6 100644
--- a/Source/Core/VideoBackends/Software/SWVideoConfig.h
+++ b/Source/Core/VideoBackends/Software/SWVideoConfig.h
@@ -20,7 +20,6 @@ struct SWVideoConfig : NonCopyable
bool bHideCursor;
bool renderToMainframe;
- bool bHwRasterizer;
bool bBypassXFB;
// Emulation features
diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp
index b49fa8fc4f..93dd37f03f 100644
--- a/Source/Core/VideoBackends/Software/SWmain.cpp
+++ b/Source/Core/VideoBackends/Software/SWmain.cpp
@@ -17,12 +17,12 @@
#include "Core/HW/VideoInterface.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
+#include "VideoBackends/OGL/GLUtil.h"
#include "VideoBackends/OGL/GLExtensions/GLExtensions.h"
#include "VideoBackends/Software/BPMemLoader.h"
#include "VideoBackends/Software/Clipper.h"
#include "VideoBackends/Software/DebugUtil.h"
#include "VideoBackends/Software/EfbInterface.h"
-#include "VideoBackends/Software/HwRasterizer.h"
#include "VideoBackends/Software/OpcodeDecoder.h"
#include "VideoBackends/Software/Rasterizer.h"
#include "VideoBackends/Software/SWCommandProcessor.h"
@@ -91,7 +91,6 @@ bool VideoSoftware::Initialize(void *window_handle)
OpcodeDecoder::Init();
Clipper::Init();
Rasterizer::Init();
- HwRasterizer::Init();
SWRenderer::Init();
DebugUtil::Init();
@@ -155,7 +154,6 @@ void VideoSoftware::EmuStateChange(EMUSTATE_CHANGE newState)
void VideoSoftware::Shutdown()
{
// TODO: should be in Video_Cleanup
- HwRasterizer::Shutdown();
SWRenderer::Shutdown();
DebugUtil::Shutdown();
@@ -190,7 +188,6 @@ void VideoSoftware::Video_Prepare()
// Do our OSD callbacks
OSD::DoCallbacks(OSD::OSD_INIT);
- HwRasterizer::Prepare();
SWRenderer::Prepare();
INFO_LOG(VIDEO, "Video backend initialized.");
@@ -221,14 +218,11 @@ void VideoSoftware::Video_EndField()
Core::Callback_VideoCopiedToXFB(false);
return;
}
- if (!g_SWVideoConfig.bHwRasterizer)
+ if (!g_SWVideoConfig.bBypassXFB)
{
- if (!g_SWVideoConfig.bBypassXFB)
- {
- EfbInterface::yuv422_packed *xfb = (EfbInterface::yuv422_packed *) Memory::GetPointer(s_beginFieldArgs.xfbAddr);
+ EfbInterface::yuv422_packed *xfb = (EfbInterface::yuv422_packed *) Memory::GetPointer(s_beginFieldArgs.xfbAddr);
- SWRenderer::UpdateColorTexture(xfb, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight);
- }
+ SWRenderer::UpdateColorTexture(xfb, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight);
}
// Ideally we would just move all the OpenGL context stuff to the CPU thread,
diff --git a/Source/Core/VideoBackends/Software/Software.vcxproj b/Source/Core/VideoBackends/Software/Software.vcxproj
index 161154df62..8874bce821 100644
--- a/Source/Core/VideoBackends/Software/Software.vcxproj
+++ b/Source/Core/VideoBackends/Software/Software.vcxproj
@@ -41,7 +41,6 @@
<ClCompile Include="DebugUtil.cpp" />
<ClCompile Include="EfbCopy.cpp" />
<ClCompile Include="EfbInterface.cpp" />
- <ClCompile Include="HwRasterizer.cpp" />
<ClCompile Include="OpcodeDecoder.cpp" />
<ClCompile Include="RasterFont.cpp" />
<ClCompile Include="Rasterizer.cpp" />
@@ -65,7 +64,6 @@
<ClInclude Include="DebugUtil.h" />
<ClInclude Include="EfbCopy.h" />
<ClInclude Include="EfbInterface.h" />
- <ClInclude Include="HwRasterizer.h" />
<ClInclude Include="NativeVertexFormat.h" />
<ClInclude Include="OpcodeDecoder.h" />
<ClInclude Include="RasterFont.h" />
@@ -95,4 +93,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp
index 6ea6eab051..552b60a99a 100644
--- a/Source/Core/VideoBackends/Software/Tev.cpp
+++ b/Source/Core/VideoBackends/Software/Tev.cpp
@@ -650,125 +650,120 @@ void Tev::Draw()
if (!TevAlphaTest(output[ALP_C]))
return;
- // This part is only needed if we are not simply computing bbox
- // (i. e., only needed when using the SW renderer)
- if (!BoundingBox::active)
+ // z texture
+ if (bpmem.ztex2.op)
{
- // z texture
- if (bpmem.ztex2.op)
+ u32 ztex = bpmem.ztex1.bias;
+ switch (bpmem.ztex2.type)
{
- u32 ztex = bpmem.ztex1.bias;
- switch (bpmem.ztex2.type)
- {
- case 0: // 8 bit
- ztex += TexColor[ALP_C];
- break;
- case 1: // 16 bit
- ztex += TexColor[ALP_C] << 8 | TexColor[RED_C];
- break;
- case 2: // 24 bit
- ztex += TexColor[RED_C] << 16 | TexColor[GRN_C] << 8 | TexColor[BLU_C];
- break;
- }
-
- if (bpmem.ztex2.op == ZTEXTURE_ADD)
- ztex += Position[2];
-
- Position[2] = ztex & 0x00ffffff;
+ case 0: // 8 bit
+ ztex += TexColor[ALP_C];
+ break;
+ case 1: // 16 bit
+ ztex += TexColor[ALP_C] << 8 | TexColor[RED_C];
+ break;
+ case 2: // 24 bit
+ ztex += TexColor[RED_C] << 16 | TexColor[GRN_C] << 8 | TexColor[BLU_C];
+ break;
}
- // fog
- if (bpmem.fog.c_proj_fsel.fsel)
- {
- float ze;
+ if (bpmem.ztex2.op == ZTEXTURE_ADD)
+ ztex += Position[2];
- if (bpmem.fog.c_proj_fsel.proj == 0)
- {
- // perspective
- // ze = A/(B - (Zs >> B_SHF))
- s32 denom = bpmem.fog.b_magnitude - (Position[2] >> bpmem.fog.b_shift);
- //in addition downscale magnitude and zs to 0.24 bits
- ze = (bpmem.fog.a.GetA() * 16777215.0f) / (float)denom;
- }
- else
- {
- // orthographic
- // ze = a*Zs
- //in addition downscale zs to 0.24 bits
- ze = bpmem.fog.a.GetA() * ((float)Position[2] / 16777215.0f);
+ Position[2] = ztex & 0x00ffffff;
+ }
- }
+ // fog
+ if (bpmem.fog.c_proj_fsel.fsel)
+ {
+ float ze;
- if (bpmem.fogRange.Base.Enabled)
- {
- // TODO: This is untested and should definitely be checked against real hw.
- // - No idea if offset is really normalized against the viewport width or against the projection matrix or yet something else
- // - scaling of the "k" coefficient isn't clear either.
-
- // First, calculate the offset from the viewport center (normalized to 0..1)
- float offset = (Position[0] - (bpmem.fogRange.Base.Center - 342)) / (float)xfmem.viewport.wd;
-
- // Based on that, choose the index such that points which are far away from the z-axis use the 10th "k" value and such that central points use the first value.
- float floatindex = 9.f - std::abs(offset) * 9.f;
- floatindex = (floatindex < 0.f) ? 0.f : (floatindex > 9.f) ? 9.f : floatindex; // TODO: This shouldn't be necessary!
-
- // Get the two closest integer indices, look up the corresponding samples
- int indexlower = (int)floor(floatindex);
- int indexupper = indexlower + 1;
- // Look up coefficient... Seems like multiplying by 4 makes Fortune Street work properly (fog is too strong without the factor)
- float klower = bpmem.fogRange.K[indexlower/2].GetValue(indexlower%2) * 4.f;
- float kupper = bpmem.fogRange.K[indexupper/2].GetValue(indexupper%2) * 4.f;
-
- // linearly interpolate the samples and multiple ze by the resulting adjustment factor
- float factor = indexupper - floatindex;
- float k = klower * factor + kupper * (1.f - factor);
- float x_adjust = sqrt(offset*offset + k*k)/k;
- ze *= x_adjust; // NOTE: This is basically dividing by a cosine (hidden behind GXInitFogAdjTable): 1/cos = c/b = sqrt(a^2+b^2)/b
- }
+ if (bpmem.fog.c_proj_fsel.proj == 0)
+ {
+ // perspective
+ // ze = A/(B - (Zs >> B_SHF))
+ s32 denom = bpmem.fog.b_magnitude - (Position[2] >> bpmem.fog.b_shift);
+ //in addition downscale magnitude and zs to 0.24 bits
+ ze = (bpmem.fog.a.GetA() * 16777215.0f) / (float)denom;
+ }
+ else
+ {
+ // orthographic
+ // ze = a*Zs
+ //in addition downscale zs to 0.24 bits
+ ze = bpmem.fog.a.GetA() * ((float)Position[2] / 16777215.0f);
- ze -= bpmem.fog.c_proj_fsel.GetC();
+ }
- // clamp 0 to 1
- float fog = (ze<0.0f) ? 0.0f : ((ze>1.0f) ? 1.0f : ze);
+ if (bpmem.fogRange.Base.Enabled)
+ {
+ // TODO: This is untested and should definitely be checked against real hw.
+ // - No idea if offset is really normalized against the viewport width or against the projection matrix or yet something else
+ // - scaling of the "k" coefficient isn't clear either.
+
+ // First, calculate the offset from the viewport center (normalized to 0..1)
+ float offset = (Position[0] - (bpmem.fogRange.Base.Center - 342)) / (float)xfmem.viewport.wd;
+
+ // Based on that, choose the index such that points which are far away from the z-axis use the 10th "k" value and such that central points use the first value.
+ float floatindex = 9.f - std::abs(offset) * 9.f;
+ floatindex = (floatindex < 0.f) ? 0.f : (floatindex > 9.f) ? 9.f : floatindex; // TODO: This shouldn't be necessary!
+
+ // Get the two closest integer indices, look up the corresponding samples
+ int indexlower = (int)floor(floatindex);
+ int indexupper = indexlower + 1;
+ // Look up coefficient... Seems like multiplying by 4 makes Fortune Street work properly (fog is too strong without the factor)
+ float klower = bpmem.fogRange.K[indexlower/2].GetValue(indexlower%2) * 4.f;
+ float kupper = bpmem.fogRange.K[indexupper/2].GetValue(indexupper%2) * 4.f;
+
+ // linearly interpolate the samples and multiple ze by the resulting adjustment factor
+ float factor = indexupper - floatindex;
+ float k = klower * factor + kupper * (1.f - factor);
+ float x_adjust = sqrt(offset*offset + k*k)/k;
+ ze *= x_adjust; // NOTE: This is basically dividing by a cosine (hidden behind GXInitFogAdjTable): 1/cos = c/b = sqrt(a^2+b^2)/b
+ }
- switch (bpmem.fog.c_proj_fsel.fsel)
- {
- case 4: // exp
- fog = 1.0f - pow(2.0f, -8.0f * fog);
- break;
- case 5: // exp2
- fog = 1.0f - pow(2.0f, -8.0f * fog * fog);
- break;
- case 6: // backward exp
- fog = 1.0f - fog;
- fog = pow(2.0f, -8.0f * fog);
- break;
- case 7: // backward exp2
- fog = 1.0f - fog;
- fog = pow(2.0f, -8.0f * fog * fog);
- break;
- }
+ ze -= bpmem.fog.c_proj_fsel.GetC();
- // lerp from output to fog color
- u32 fogInt = (u32)(fog * 256);
- u32 invFog = 256 - fogInt;
+ // clamp 0 to 1
+ float fog = (ze<0.0f) ? 0.0f : ((ze>1.0f) ? 1.0f : ze);
- output[RED_C] = (output[RED_C] * invFog + fogInt * bpmem.fog.color.r) >> 8;
- output[GRN_C] = (output[GRN_C] * invFog + fogInt * bpmem.fog.color.g) >> 8;
- output[BLU_C] = (output[BLU_C] * invFog + fogInt * bpmem.fog.color.b) >> 8;
+ switch (bpmem.fog.c_proj_fsel.fsel)
+ {
+ case 4: // exp
+ fog = 1.0f - pow(2.0f, -8.0f * fog);
+ break;
+ case 5: // exp2
+ fog = 1.0f - pow(2.0f, -8.0f * fog * fog);
+ break;
+ case 6: // backward exp
+ fog = 1.0f - fog;
+ fog = pow(2.0f, -8.0f * fog);
+ break;
+ case 7: // backward exp2
+ fog = 1.0f - fog;
+ fog = pow(2.0f, -8.0f * fog * fog);
+ break;
}
- bool late_ztest = !bpmem.zcontrol.early_ztest || !g_SWVideoConfig.bZComploc;
- if (late_ztest && bpmem.zmode.testenable)
- {
- // TODO: Check against hw if these values get incremented even if depth testing is disabled
- EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_INPUT);
+ // lerp from output to fog color
+ u32 fogInt = (u32)(fog * 256);
+ u32 invFog = 256 - fogInt;
- if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2]))
- return;
+ output[RED_C] = (output[RED_C] * invFog + fogInt * bpmem.fog.color.r) >> 8;
+ output[GRN_C] = (output[GRN_C] * invFog + fogInt * bpmem.fog.color.g) >> 8;
+ output[BLU_C] = (output[BLU_C] * invFog + fogInt * bpmem.fog.color.b) >> 8;
+ }
- EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_OUTPUT);
- }
+ bool late_ztest = !bpmem.zcontrol.early_ztest || !g_SWVideoConfig.bZComploc;
+ if (late_ztest && bpmem.zmode.testenable)
+ {
+ // TODO: Check against hw if these values get incremented even if depth testing is disabled
+ EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_INPUT);
+
+ if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2]))
+ return;
+
+ EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_OUTPUT);
}
// branchless bounding box update
@@ -777,12 +772,6 @@ void Tev::Draw()
BoundingBox::coords[BoundingBox::TOP] = std::min((u16)Position[1], BoundingBox::coords[BoundingBox::TOP]);
BoundingBox::coords[BoundingBox::BOTTOM] = std::max((u16)Position[1], BoundingBox::coords[BoundingBox::BOTTOM]);
- // if we are only calculating the bounding box,
- // there's no need to actually draw anything
- if (BoundingBox::active)
- return;
-
-
#if ALLOW_TEV_DUMPS
if (g_SWVideoConfig.bDumpTevStages)
{