linux/softrend: builds & runs, doesn't push to screen yet

This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2015-12-04 00:53:42 +01:00
parent f5f3332b09
commit 5e377399d3
8 changed files with 144 additions and 97 deletions

View File

@ -41,6 +41,8 @@ ifdef CPP_REC
RZDCY_MODULES += rec-cpp/
endif
RZDCY_MODULES += rend/soft/
ifndef NO_REND
RZDCY_MODULES += rend/gles/
else

View File

@ -371,24 +371,21 @@ bool rend_init()
renderer = rend_norend();
#else
#if HOST_OS == OS_WINDOWS
switch (settings.pvr.rend) {
default:
case 0:
renderer = rend_GLES2();
break;
#if HOST_OS == OS_WINDOWS
case 1:
renderer = rend_D3D11();
break;
#endif
case 2:
renderer = rend_softrend();
break;
}
#else
renderer = rend_GLES2();
#endif
#endif

View File

@ -5,37 +5,37 @@
struct EvdevControllerMapping
{
const char* name;
const int Btn_A;
const int Btn_B;
const int Btn_C;
const int Btn_D;
const int Btn_X;
const int Btn_Y;
const int Btn_Z;
const int Btn_Start;
const int Btn_Escape;
const int Btn_DPad_Left;
const int Btn_DPad_Right;
const int Btn_DPad_Up;
const int Btn_DPad_Down;
const int Btn_DPad2_Left;
const int Btn_DPad2_Right;
const int Btn_DPad2_Up;
const int Btn_DPad2_Down;
const int Btn_Trigger_Left;
const int Btn_Trigger_Right;
const int Axis_DPad_X;
const int Axis_DPad_Y;
const int Axis_DPad2_X;
const int Axis_DPad2_Y;
const int Axis_Analog_X;
const int Axis_Analog_Y;
const int Axis_Trigger_Left;
const int Axis_Trigger_Right;
const bool Axis_Analog_X_Inverted;
const bool Axis_Analog_Y_Inverted;
const bool Axis_Trigger_Left_Inverted;
const bool Axis_Trigger_Right_Inverted;
int Btn_A;
int Btn_B;
int Btn_C;
int Btn_D;
int Btn_X;
int Btn_Y;
int Btn_Z;
int Btn_Start;
int Btn_Escape;
int Btn_DPad_Left;
int Btn_DPad_Right;
int Btn_DPad_Up;
int Btn_DPad_Down;
int Btn_DPad2_Left;
int Btn_DPad2_Right;
int Btn_DPad2_Up;
int Btn_DPad2_Down;
int Btn_Trigger_Left;
int Btn_Trigger_Right;
int Axis_DPad_X;
int Axis_DPad_Y;
int Axis_DPad2_X;
int Axis_DPad2_Y;
int Axis_Analog_X;
int Axis_Analog_Y;
int Axis_Trigger_Left;
int Axis_Trigger_Right;
bool Axis_Analog_X_Inverted;
bool Axis_Analog_Y_Inverted;
bool Axis_Trigger_Left_Inverted;
bool Axis_Trigger_Right_Inverted;
};
struct EvdevAxisData

View File

@ -21,7 +21,7 @@
#include "hw/sh4/dyna/shil_canonical.h"
#define MIPS_COUNTER 0
#define MIPS_COUNTER 1
struct DynaRBI : RuntimeBlockInfo
{

View File

@ -625,6 +625,17 @@ int screen_height;
void gl_swap()
{
static FILE* fd = fopen(cfgLoadStr("record", "rawvid","").c_str(), "wb");
if (fd) {
int bytesz = screen_width* screen_height * 3;
u8* img = new u8[bytesz];
glReadPixels(0,0,screen_width,screen_height,GL_RGB, GL_UNSIGNED_BYTE,img);
fwrite(img, 1, bytesz, fd);
fflush(fd);
}
glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget());
Window win;

View File

@ -20,6 +20,8 @@ Compression
look into it, but afaik PVRC is not realtime doable
*/
#include <xmmintrin.h>
u16 temp_tex_buffer[1024*1024];
extern u32 decoded_colors[3][65536];
@ -308,32 +310,28 @@ struct TextureCacheData
glGenerateMipmap(GL_TEXTURE_2D);
}
else {
#if HOST_OS == OS_WINDOWS
if (textype == GL_UNSIGNED_SHORT_5_6_5)
tex_type = 0;
else if (textype == GL_UNSIGNED_SHORT_5_5_5_1)
tex_type = 1;
else if (textype == GL_UNSIGNED_SHORT_4_4_4_4)
tex_type = 2;
if (pData) {
_mm_free(pData);
if (textype == GL_UNSIGNED_SHORT_5_6_5)
tex_type = 0;
else if (textype == GL_UNSIGNED_SHORT_5_5_5_1)
tex_type = 1;
else if (textype == GL_UNSIGNED_SHORT_4_4_4_4)
tex_type = 2;
if (pData) {
_mm_free(pData);
}
pData = (u16*)_mm_malloc(w * h * 16, 16);
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
u32* data = (u32*)&pData[(x + y*w) * 8];
data[0] = decoded_colors[tex_type][temp_tex_buffer[(x + 1) % w + (y + 1) % h * w]];
data[1] = decoded_colors[tex_type][temp_tex_buffer[(x + 0) % w + (y + 1) % h * w]];
data[2] = decoded_colors[tex_type][temp_tex_buffer[(x + 1) % w + (y + 0) % h * w]];
data[3] = decoded_colors[tex_type][temp_tex_buffer[(x + 0) % w + (y + 0) % h * w]];
}
pData = (u16*)_mm_malloc(w * h * 16, 16);
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
u32* data = (u32*)&pData[(x + y*w) * 8];
data[0] = decoded_colors[tex_type][temp_tex_buffer[(x + 1) % w + (y + 1) % h * w]];
data[1] = decoded_colors[tex_type][temp_tex_buffer[(x + 0) % w + (y + 1) % h * w]];
data[2] = decoded_colors[tex_type][temp_tex_buffer[(x + 1) % w + (y + 0) % h * w]];
data[3] = decoded_colors[tex_type][temp_tex_buffer[(x + 0) % w + (y + 0) % h * w]];
}
}
#else
die("Softrend only works for windows");
#endif
}
}
}
@ -342,12 +340,11 @@ struct TextureCacheData
void Delete()
{
#if HOST_OS == OS_WINDOWS
if (pData) {
_mm_free(pData);
pData = 0;
}
#endif
if (pData) {
_mm_free(pData);
pData = 0;
}
if (texID) {
glDeleteTextures(1, &texID);
}

View File

@ -1,7 +1,7 @@
#include <omp.h>
#include "hw\pvr\Renderer_if.h"
#include "hw\pvr\pvr_mem.h"
#include "oslib\oslib.h"
#include "hw/pvr/Renderer_if.h"
#include "hw/pvr/pvr_mem.h"
#include "oslib/oslib.h"
/*
SSE/MMX based softrend
@ -17,8 +17,9 @@
#include <mmintrin.h>
#include <xmmintrin.h>
#include <emmintrin.h>
#include <smmintrin.h>
BITMAPINFOHEADER bi = { sizeof(BITMAPINFOHEADER), 0, 0, 1, 32, BI_RGB };
#include <cmath>
#include "rend/gles/gles.h"
@ -34,7 +35,20 @@ u32 decoded_colors[3][65536];
DECL_ALIGN(32) u32 render_buffer[MAX_RENDER_PIXELS * 2]; //Color + depth
DECL_ALIGN(32) u32 pixels[MAX_RENDER_PIXELS];
#if HOST_OS != OS_WINDOWS
struct RECT {
int top, left, bottom, right;
};
#endif
union m128i {
__m128i mm;
int8_t m128i_i8[16];
int16_t m128i_i16[8];
int32_t m128i_i32[4];
uint32_t m128i_u32[4];
};
static __m128 _mm_load_scaled_float(float v, float s)
{
@ -51,7 +65,7 @@ static __m128i _mm_broadcast_int(int v)
}
static __m128 _mm_load_ps_r(float a, float b, float c, float d)
{
__declspec(align(128)) float v[4];
DECL_ALIGN(128) float v[4];
v[0] = a;
v[1] = b;
v[2] = c;
@ -67,14 +81,14 @@ __forceinline int iround(float x)
float mmin(float a, float b, float c, float d)
{
int rv = min(a, b);
float rv = min(a, b);
rv = min(c, rv);
return max(d, rv);
}
float mmax(float a, float b, float c, float d)
{
int rv = max(a, b);
float rv = max(a, b);
rv = max(c, rv);
return min(d, rv);
}
@ -237,11 +251,17 @@ typedef void(*RendtriangleFn)(PolyParam* pp, int vertex_offset, const Vertex &v1
RendtriangleFn RendtriangleFns[3][2][2][2][4][2];
__m128i const_setAlpha = { 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000 };
__m128i shuffle_alpha = {
__m128i const_setAlpha;
__m128i shuffle_alpha
#if HOST_OS == OS_WINDOWS
= {
0x0E, 0x80, 0x0E, 0x80, 0x0E, 0x80, 0x0E, 0x80,
0x06, 0x80, 0x06, 0x80, 0x06, 0x80, 0x06, 0x80
};
}
#endif
;
TPL_DECL_pixel
static void PixelFlush(PolyParam* pp, text_info* texture, __m128 x, __m128 y, u8* cb, __m128 oldmask, IPs& ip)
@ -303,8 +323,10 @@ static void PixelFlush(PolyParam* pp, text_info* texture, __m128 x, __m128 y, u8
__m128i vfi = _mm_cvttps_epi32(_mm_mul_ps(vf, _mm_set1_ps(256)));
//(int)v<<x+(int)u
__m128i textadr = _mm_add_epi32(_mm_slli_epi32(vi, 16), ui);//texture addresses ! 4x of em !
__m128i textel;
m128i textadr;
textadr.mm = _mm_add_epi32(_mm_slli_epi32(vi, 16), ui);//texture addresses ! 4x of em !
m128i textel;
for (int i = 0; i < 4; i++) {
u32 u = textadr.m128i_i16[i * 2 + 0];
@ -383,13 +405,13 @@ static void PixelFlush(PolyParam* pp, text_info* texture, __m128 x, __m128 y, u8
}
if (pp_IgnoreTexA) {
textel = _mm_or_si128(textel, const_setAlpha);
textel.mm = _mm_or_si128(textel.mm, const_setAlpha);
}
if (pp_ShadInstr == 0){
//color.rgb = texcol.rgb;
//color.a = texcol.a;
rv = textel;
rv = textel.mm;
}
else if (pp_ShadInstr == 1) {
//color.rgb *= texcol.rgb;
@ -403,8 +425,8 @@ static void PixelFlush(PolyParam* pp, text_info* texture, __m128 x, __m128 y, u8
__m128i hi_rv = _mm_cvtepu8_epi16(_mm_shuffle_epi32(rv, _MM_SHUFFLE(1, 0, 3, 2)));
__m128i lo_fb = _mm_cvtepu8_epi16(textel);
__m128i hi_fb = _mm_cvtepu8_epi16(_mm_shuffle_epi32(textel, _MM_SHUFFLE(1, 0, 3, 2)));
__m128i lo_fb = _mm_cvtepu8_epi16(textel.mm);
__m128i hi_fb = _mm_cvtepu8_epi16(_mm_shuffle_epi32(textel.mm, _MM_SHUFFLE(1, 0, 3, 2)));
lo_rv = _mm_mullo_epi16(lo_rv, lo_fb);
@ -420,8 +442,8 @@ static void PixelFlush(PolyParam* pp, text_info* texture, __m128 x, __m128 y, u8
__m128i hi_rv = _mm_cvtepu8_epi16(_mm_shuffle_epi32(rv, _MM_SHUFFLE(1, 0, 3, 2)));
__m128i lo_fb = _mm_cvtepu8_epi16(textel);
__m128i hi_fb = _mm_cvtepu8_epi16(_mm_shuffle_epi32(textel, _MM_SHUFFLE(1, 0, 3, 2)));
__m128i lo_fb = _mm_cvtepu8_epi16(textel.mm);
__m128i hi_fb = _mm_cvtepu8_epi16(_mm_shuffle_epi32(textel.mm, _MM_SHUFFLE(1, 0, 3, 2)));
__m128i lo_rv_alpha = _mm_shuffle_epi8(lo_fb, shuffle_alpha);
__m128i hi_rv_alpha = _mm_shuffle_epi8(hi_fb, shuffle_alpha);
@ -444,8 +466,8 @@ static void PixelFlush(PolyParam* pp, text_info* texture, __m128 x, __m128 y, u8
__m128i hi_rv = _mm_cvtepu8_epi16(_mm_shuffle_epi32(rv, _MM_SHUFFLE(1, 0, 3, 2)));
__m128i lo_fb = _mm_cvtepu8_epi16(textel);
__m128i hi_fb = _mm_cvtepu8_epi16(_mm_shuffle_epi32(textel, _MM_SHUFFLE(1, 0, 3, 2)));
__m128i lo_fb = _mm_cvtepu8_epi16(textel.mm);
__m128i hi_fb = _mm_cvtepu8_epi16(_mm_shuffle_epi32(textel.mm, _MM_SHUFFLE(1, 0, 3, 2)));
lo_rv = _mm_mullo_epi16(lo_rv, lo_fb);
@ -460,7 +482,7 @@ static void PixelFlush(PolyParam* pp, text_info* texture, __m128 x, __m128 y, u8
//textadr = _mm_add_epi32(textadr, _mm_setr_epi32(tex_addr, tex_addr, tex_addr, tex_addr));
//rv = textel; // _mm_xor_si128(rv, textadr);
//rv = textel.mm; // _mm_xor_si128(rv, textadr);
}
}
@ -471,12 +493,17 @@ static void PixelFlush(PolyParam* pp, text_info* texture, __m128 x, __m128 y, u8
__m128i fb = *(__m128i*)cb;
#if 1
m128i mm_rv, mm_fb;
mm_rv.mm = rv;
mm_fb.mm = fb;
//ALPHA_TEST
for (int i = 0; i < 4; i++) {
if (rv.m128i_i8[i * 4 + 3] < PT_ALPHA_REF) {
rv.m128i_u32[i] = fb.m128i_u32[i];
if (mm_rv.m128i_i8[i * 4 + 3] < PT_ALPHA_REF) {
mm_rv.m128i_u32[i] = mm_fb.m128i_u32[i];
}
}
rv = mm_rv.mm;
#else
__m128i ALPHA_TEST = _mm_set1_epi8(PT_ALPHA_REF);
__m128i mask = _mm_cmplt_epi8(_mm_subs_epu16(ALPHA_TEST, rv), _mm_setzero_si128());
@ -673,15 +700,15 @@ static void Rendtriangle(PolyParam* pp, int vertex_offset, const Vertex &v1, con
u8* cb_y = (u8*)colorBuffer;
cb_y += miny*stride_bytes + minx*(q * 4);
IPs __declspec(align(64)) ip;
DECL_ALIGN(64) IPs ip;
ip.Setup(pp, &texture, v1, v2, v3, minx, miny, q);
__m128 y_ps = _mm_broadcast_float(miny);
__m128 minx_ps = _mm_load_scaled_float(minx - q, 1);
static __declspec(align(16)) float ones_ps[4] = { 1, 1, 1, 1 };
static __declspec(align(16)) float q_ps[4] = { q, q, q, q };
static DECL_ALIGN(16) float ones_ps[4] = { 1, 1, 1, 1 };
static DECL_ALIGN(16) float q_ps[4] = { q, q, q, q };
// Loop through blocks
for (int y = spany; y > 0; y -= q)
@ -871,13 +898,20 @@ struct softrend : Renderer
return !is_rtt;
}
#if HOST_OS == OS_WINDOWS
HWND hWnd;
HBITMAP hBMP = 0, holdBMP;
HDC hmem;
BITMAPINFOHEADER bi = { sizeof(BITMAPINFOHEADER), 0, 0, 1, 32, BI_RGB };
#endif
virtual bool Init() {
const_setAlpha = _mm_set1_epi32(0xFF000000);
#if HOST_OS == OS_WINDOWS
hWnd = (HWND)libPvr_GetRenderTarget();
bi.biWidth = 640;
@ -897,6 +931,7 @@ struct softrend : Renderer
hmem = CreateCompatibleDC(hdc);
holdBMP = (HBITMAP)SelectObject(hmem, hBMP);
ReleaseDC(hWnd, hdc);
#endif
#define REP_16(x) ((x)* 16 + (x))
#define REP_32(x) ((x)* 8 + (x)/4)
@ -1116,10 +1151,12 @@ struct softrend : Renderer
}
virtual void Term() {
#if HOST_OS == OS_WINDOWS
if (hBMP) {
DeleteObject(SelectObject(hmem, holdBMP));
DeleteDC(hmem);
}
#endif
}
virtual void Present() {
@ -1139,6 +1176,7 @@ struct softrend : Renderer
}
}
#if HOST_OS == OS_WINDOWS
SetDIBits(hmem, hBMP, 0, 480, pixels, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
RECT clientRect;
@ -1153,6 +1191,7 @@ struct softrend : Renderer
BitBlt(hdc, x, y, 640 , 480 , hmem, 0, 0, SRCCOPY);
ReleaseDC(hWnd, hdc);
#endif
}
};

View File

@ -84,8 +84,9 @@ else ifneq (,$(findstring x64,$(platform)))
X64_REC := 1
NOT_ARM := 1
USE_X11 := 1
CFLAGS += -D TARGET_LINUX_x64 -D TARGET_NO_AREC -fsingle-precision-constant
CFLAGS += -D TARGET_LINUX_x64 -D TARGET_NO_AREC -fsingle-precision-constant -msse4.1 -fopenmp
CXXFLAGS += -fexceptions
LDFLAGS += -fopenmp
# Generic 32 bit ARMhf (a.k.a. ARMv7h)
else ifneq (,$(findstring armv7h,$(platform)))