diff --git a/gfx/d3d9/d3d.cpp b/gfx/d3d9/d3d.cpp index 6b02ab1d68..536f14bd41 100644 --- a/gfx/d3d9/d3d.cpp +++ b/gfx/d3d9/d3d.cpp @@ -15,6 +15,11 @@ * If not, see . */ +#ifdef _XBOX +#include +#include +#endif + #include "d3d.hpp" #include "render_chain.hpp" #include "../../file.h" @@ -31,8 +36,17 @@ #define HAVE_SHADERS #endif +#ifdef HAVE_HLSL +#include "../../gfx/shader_hlsl.h" +#endif + #include "d3d_shared.h" +#ifdef _XBOX +#include "../../xdk/xdk_resources.h" +#include "render_chain_xdk.h" +#endif + #ifdef HAVE_MONITOR static BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) @@ -169,6 +183,13 @@ static bool d3d_init_chain(d3d_video_t *d3d, const video_info_t *video_info) video_info->input_scale * RARCH_SCALE_BASE; d3d_deinit_chain(d3d); +#ifdef _XBOX + if (!renderchain_init(d3d, info)) + { + RARCH_ERR("[D3D]: Failed to init render chain.\n"); + return false; + } +#else d3d->chain = new renderchain_t(); if (!d3d->chain) return false; @@ -211,18 +232,138 @@ static bool d3d_init_chain(d3d_video_t *d3d, const video_info_t *video_info) RARCH_ERR("[D3D9]: Failed to init LUTs.\n"); return false; } +#endif +#ifndef _XBOX #ifndef DONT_HAVE_STATE_TRACKER if (!d3d_init_imports(d3d)) { RARCH_ERR("[D3D9]: Failed to init imports.\n"); return false; } +#endif #endif return true; } +#ifdef _XBOX +static void d3d_reinit_renderchain(void *data, + const video_info_t *video) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + + d3d->pixel_size = video->rgb32 ? + sizeof(uint32_t) : sizeof(uint16_t); + d3d->tex_w = d3d->tex_h = + RARCH_SCALE_BASE * video->input_scale; + + RARCH_LOG( + "Reinitializing renderchain - and textures (%u x %u @ %u bpp)\n", + d3d->tex_w, d3d->tex_h, d3d->pixel_size * CHAR_BIT); + + d3d_deinit_chain(d3d); + d3d_init_chain(d3d, video); +} +#endif + +#ifdef _XBOX +#ifdef HAVE_RMENU +extern struct texture_image *menu_texture; +#endif + +#ifdef _XBOX1 +static bool texture_image_render(void *data, + struct texture_image *out_img, + int x, int y, int w, int h, bool force_fullscreen) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev; + + if (out_img->pixels == NULL || out_img->vertex_buf == NULL) + return false; + + float fX = static_cast(x); + float fY = static_cast(y); + + // create the new vertices + Vertex newVerts[] = + { + // x, y, z, color, u ,v + {fX, fY, 0.0f, 0, 0, 0}, + {fX + w, fY, 0.0f, 0, 1, 0}, + {fX + w, fY + h, 0.0f, 0, 1, 1}, + {fX, fY + h, 0.0f, 0, 0, 1} + }; + + // load the existing vertices + Vertex *pCurVerts; + + HRESULT ret = out_img->vertex_buf->Lock(0, 0, + (unsigned char**)&pCurVerts, 0); + + if (FAILED(ret)) + return false; + + // copy the new verts over the old verts + memcpy(pCurVerts, newVerts, 4 * sizeof(Vertex)); + out_img->vertex_buf->Unlock(); + + d3d->dev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + d3d->dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + d3d->dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + /* Also blend the texture with the set alpha value. */ + d3d->dev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + d3d->dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + d3d->dev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + + /* Draw the quad. */ + d3dr->SetTexture(0, out_img->pixels); + D3DDevice_SetStreamSources(d3dr, 0, + out_img->vertex_buf, 0, sizeof(Vertex)); + d3dr->SetVertexShader(D3DFVF_CUSTOMVERTEX); + + if (force_fullscreen) + { + D3DVIEWPORT vp = {0}; + vp.Width = w; + vp.Height = h; + vp.X = 0; + vp.Y = 0; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + d3dr->SetViewport(&vp); + } + D3DDevice_DrawPrimitive(d3dr, D3DPT_QUADLIST, 0, 1); + + return true; +} +#endif + +#ifdef HAVE_MENU +static void d3d_draw_texture(void *data) +{ + d3d_video_t *d3d = (d3d_video_t*)data; +#if defined(HAVE_RMENU) + menu_texture->x = 0; + menu_texture->y = 0; + + if (d3d->menu_texture_enable) + { + d3d->dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); + d3d->dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + d3d->dev->SetRenderState(D3DRS_ALPHABLENDENABLE, true); + texture_image_render(d3d, menu_texture, + menu_texture->x, menu_texture->y, + d3d->screen_width, d3d->screen_height, true); + d3d->dev->SetRenderState(D3DRS_ALPHABLENDENABLE, false); + } +#endif +} +#endif +#endif + #ifdef HAVE_FBO static bool d3d_init_multipass(d3d_video_t *d3d) { @@ -389,13 +530,16 @@ static bool d3d_frame(void *data, const void *frame, d3d->screen_height, d3d->video_info.force_aspect, g_extern.system.aspect_ratio); +#ifndef _XBOX renderchain_set_final_viewport(d3d->chain, &d3d->final_viewport); d3d_recompute_pass_sizes(d3d); +#endif d3d->should_resize = false; } - /* render_chain() only clears out viewport, clear out everything. */ + /* render_chain() only clears out viewport, + * clear out everything. */ screen_vp.X = 0; screen_vp.Y = 0; screen_vp.MinZ = 0; @@ -405,7 +549,8 @@ static bool d3d_frame(void *data, const void *frame, d3dr->SetViewport(&screen_vp); d3dr->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0); - // Insert black frame first, so we can screenshot, etc. + /* Insert black frame first, so we + * can screenshot, etc. */ if (g_settings.video.black_frame_insertion) { D3DDevice_Presents(d3d, d3dr); @@ -414,12 +559,17 @@ static bool d3d_frame(void *data, const void *frame, d3dr->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0); } +#ifdef _XBOX + renderchain_render_pass(d3d, frame, width, height, + pitch, d3d->dev_rotation); +#else if (!renderchain_render(d3d->chain, frame, width, height, pitch, d3d->dev_rotation)) { RARCH_ERR("[D3D]: Failed to render scene.\n"); return false; } +#endif if (d3d->font_ctx && d3d->font_ctx->render_msg && msg) { @@ -440,9 +590,11 @@ static bool d3d_frame(void *data, const void *frame, } #ifdef HAVE_MENU +#ifndef _XBOX if (d3d->menu && d3d->menu->enabled) d3d_overlay_render(d3d, d3d->menu); #endif +#endif #ifdef HAVE_OVERLAY if (d3d->overlays_enabled) @@ -456,6 +608,12 @@ static bool d3d_frame(void *data, const void *frame, if (g_extern.lifecycle_state & (1ULL << MODE_MENU) && driver.menu_ctx && driver.menu_ctx->frame) driver.menu_ctx->frame(); + +#ifdef _XBOX + /* TODO - should be refactored. */ + if (d3d && d3d->menu_texture_enable) + d3d_draw_texture(d3d); +#endif #endif RARCH_PERFORMANCE_STOP(d3d_frame); @@ -477,6 +635,13 @@ static bool d3d_read_viewport(void *data, uint8_t *buffer) RARCH_PERFORMANCE_INIT(d3d_read_viewport); RARCH_PERFORMANCE_START(d3d_read_viewport); bool ret = true; + + (void)data; + (void)buffer; + +#ifdef _XBOX + ret = false; +#else LPDIRECT3DSURFACE target = NULL; LPDIRECT3DSURFACE dest = NULL; @@ -533,6 +698,7 @@ end: target->Release(); if (dest) dest->Release(); +#endif return ret; } @@ -541,12 +707,25 @@ static bool d3d_set_shader(void *data, { d3d_video_t *d3d = (d3d_video_t*)data; std::string shader = ""; - if (path && type == RARCH_SHADER_CG) - shader = path; + + switch (type) + { + case RARCH_SHADER_CG: + if (path) + shader = path; +#ifdef HAVE_HLSL + d3d->shader = &hlsl_backend; +#endif + break; + default: + break; + } std::string old_shader = d3d->cg_shader; bool restore_old = false; +#ifdef HAVE_CG d3d->cg_shader = shader; +#endif if (!d3d_process_shader(d3d) || !d3d_restore(d3d)) { @@ -556,7 +735,9 @@ static bool d3d_set_shader(void *data, if (restore_old) { +#ifdef HAVE_CG d3d->cg_shader = old_shader; +#endif d3d_process_shader(d3d); d3d_restore(d3d); } @@ -576,6 +757,13 @@ static void d3d_set_menu_texture_frame(void *data, { d3d_video_t *d3d = (d3d_video_t*)data; + (void)frame; + (void)rgb32; + (void)width; + (void)height; + (void)alpha; + +#ifndef _XBOX if (!d3d->menu->tex || d3d->menu->tex_w != width || d3d->menu->tex_h != height) { @@ -637,6 +825,7 @@ static void d3d_set_menu_texture_frame(void *data, if (d3d->menu) d3d->menu->tex->UnlockRect(0); } +#endif } static void d3d_set_menu_texture_enable(void *data, @@ -644,11 +833,16 @@ static void d3d_set_menu_texture_enable(void *data, { d3d_video_t *d3d = (d3d_video_t*)data; +#ifdef _XBOX + d3d->menu_texture_enable = state; + d3d->menu_texture_full_screen = full_screen; +#else if (!d3d || !d3d->menu) return; d3d->menu->enabled = state; d3d->menu->fullscreen = full_screen; +#endif } #endif diff --git a/gfx/d3d9/d3d.hpp b/gfx/d3d9/d3d.hpp index add32ab986..c79f84b8da 100644 --- a/gfx/d3d9/d3d.hpp +++ b/gfx/d3d9/d3d.hpp @@ -110,14 +110,25 @@ typedef struct LPDIRECT3DVERTEXBUFFER vert_buf; } overlay_t; -bool d3d_init_shader(void *data); -void d3d_deinit_shader(void *data); +typedef struct Vertex +{ + float x, y; +#if defined(_XBOX1) + float z; + float rhw; +#endif + float u, v; +} Vertex; + +typedef struct gl_shader_backend gl_shader_backend_t; + void d3d_make_d3dpp(void *data, const video_info_t *info, D3DPRESENT_PARAMETERS *d3dpp); typedef struct d3d_video { const d3d_font_renderer_t *font_ctx; const gfx_ctx_driver_t *ctx_driver; + const gl_shader_backend_t *shader; bool should_resize; bool quitting; @@ -129,6 +140,11 @@ typedef struct d3d_video LPDIRECT3DDEVICE dev; #ifndef _XBOX LPD3DXFONT font; +#endif +#if defined(HAVE_D3D9) && defined(_XBOX) + LPDIRECT3DSURFACE lpSurface; + LPDIRECT3DTEXTURE lpTexture_ot_as16srgb; + LPDIRECT3DTEXTURE lpTexture_ot; #endif HRESULT d3d_err; unsigned cur_mon_id; @@ -158,10 +174,28 @@ typedef struct d3d_video std::vector overlays; #endif + bool menu_texture_enable; + bool menu_texture_full_screen; #ifdef HAVE_MENU overlay_t *menu; #endif void *chain; + +#ifdef _XBOX + /* TODO _ should all be refactored */ + // RENDERCHAIN PASS + unsigned pixel_size; + LPDIRECT3DTEXTURE tex; + LPDIRECT3DVERTEXBUFFER vertex_buf; + unsigned last_width; + unsigned last_height; +#ifdef HAVE_D3D9 + LPDIRECT3DVERTEXDECLARATION vertex_decl; +#endif + // RENDERCHAIN PASS -> INFO + unsigned tex_w; + unsigned tex_h; +#endif } d3d_video_t; #ifndef _XBOX diff --git a/gfx/d3d9/d3d_defines.h b/gfx/d3d9/d3d_defines.h index 964f8777e9..d82cf66429 100644 --- a/gfx/d3d9/d3d_defines.h +++ b/gfx/d3d9/d3d_defines.h @@ -67,4 +67,10 @@ #define D3DSAMP_MINFILTER D3DTSS_MINFILTER #endif +#if defined(_XBOX360) +#define D3DFVF_CUSTOMVERTEX 0 +#elif defined(_XBOX1) +#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1) +#endif + #endif diff --git a/gfx/d3d9/xdk_d3d.cpp b/gfx/d3d9/xdk_d3d.cpp index bd9db0ad56..cd3b955d64 100644 --- a/gfx/d3d9/xdk_d3d.cpp +++ b/gfx/d3d9/xdk_d3d.cpp @@ -144,6 +144,7 @@ static void d3d_reinit_renderchain(void *data, d3d_init_chain(d3d, video); } +#ifdef _XBOX #ifdef HAVE_RMENU extern struct texture_image *menu_texture; #endif @@ -218,7 +219,6 @@ static bool texture_image_render(void *data, #endif #ifdef HAVE_MENU - static void d3d_draw_texture(void *data) { d3d_video_t *d3d = (d3d_video_t*)data; @@ -239,9 +239,7 @@ static void d3d_draw_texture(void *data) #endif } #endif - -static void d3d_calculate_rect(void *data, unsigned width, - unsigned height, bool keep, float desired_aspect); +#endif static bool d3d_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, diff --git a/gfx/d3d9/xdk_d3d.h b/gfx/d3d9/xdk_d3d.h index 6a9141e286..6c645c06a0 100644 --- a/gfx/d3d9/xdk_d3d.h +++ b/gfx/d3d9/xdk_d3d.h @@ -30,13 +30,6 @@ #include "../../gfx/gfx_context.h" #include "../../gfx/d3d9/xdk_defines.h" -#define DFONT_MAX 4096 -#if defined(_XBOX360) -#define D3DFVF_CUSTOMVERTEX 0 -#elif defined(_XBOX1) -#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1) -#endif - typedef struct { struct Coords