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