(HLSL) Add skeleton gfx/shader_hlsl.c (for initial use with 360)

This commit is contained in:
Twinaphex 2012-04-14 20:33:56 +02:00
parent d95f5131c0
commit 6f56942d44
6 changed files with 255 additions and 80 deletions

View File

@ -282,7 +282,7 @@ static const char g_strFontShader[] =
"uniform float4 Color : register(c1);\n"
"uniform float2 TexScale : register(c2);\n"
"sampler FontTexture : register(s0);\n"
"VS_OUT FontVertexShader( VS_IN In )\n"
"VS_OUT main_vertex( VS_IN In )\n"
"{\n"
"VS_OUT Out;\n"
"Out.Position.x = (In.Pos.x-0.5);\n"
@ -295,7 +295,7 @@ static const char g_strFontShader[] =
"Out.ChannelSelector = In.ChannelSelector;\n"
"return Out;\n"
"}\n"
"float4 FontPixelShader( VS_OUT In ) : COLOR0\n"
"float4 main_fragment( VS_OUT In ) : COLOR0\n"
"{\n"
"float4 FontTexel = tex2D( FontTexture, In.TexCoord0 );\n"
"if( dot( In.ChannelSelector, float4(1,1,1,1) ) )\n"
@ -364,7 +364,7 @@ static HRESULT xdk360_video_font_create_shaders (xdk360_video_font_t * font)
ID3DXBuffer* pShaderCode;
hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 ,
NULL, NULL, "FontVertexShader", "vs.2.0", 0,&pShaderCode, NULL, NULL );
NULL, NULL, "main_vertex", "vs.2.0", 0,&pShaderCode, NULL, NULL );
if (SUCCEEDED(hr))
{
hr = pd3dDevice->CreateVertexShader( ( unsigned long * )pShaderCode->GetBufferPointer(),
@ -376,7 +376,7 @@ static HRESULT xdk360_video_font_create_shaders (xdk360_video_font_t * font)
{
// Step #3, create my pixel shader
hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 ,
NULL, NULL, "FontPixelShader", "ps.2.0", 0,&pShaderCode, NULL, NULL );
NULL, NULL, "main_fragment", "ps.2.0", 0,&pShaderCode, NULL, NULL );
if ( SUCCEEDED(hr))
{
hr = pd3dDevice->CreatePixelShader( ( DWORD* )pShaderCode->GetBufferPointer(),

View File

@ -19,6 +19,7 @@
#include "../driver.h"
#include "xdk360_video.h"
#include "xdk360_video_resources.h"
#include "../gfx/hlsl_shader.h"
#include "../console/console_ext.h"
#include "../general.h"
#include "../message.h"
@ -33,17 +34,6 @@ static bool g_first_msg;
unsigned g_frame_count;
void *g_d3d;
struct hlsl_program_t
{
D3DXHANDLE vid_size_f;
D3DXHANDLE tex_size_f;
D3DXHANDLE out_size_f;
D3DXHANDLE vid_size_v;
D3DXHANDLE tex_size_v;
D3DXHANDLE out_size_v;
XMMATRIX modelViewProj;
} hlsl_program;
struct XPR_HEADER
{
unsigned long dwMagic;
@ -199,11 +189,11 @@ static void xdk360_gfx_free(void * data)
if (!vid)
return;
hlsl_deinit();
D3DResource_Release((D3DResource *)vid->lpTexture);
D3DResource_Release((D3DResource *)vid->vertex_buf);
D3DResource_Release((D3DResource *)vid->pVertexDecl);
D3DResource_Release((D3DResource *)vid->pPixelShader);
D3DResource_Release((D3DResource *)vid->pVertexShader);
D3DResource_Release((D3DResource *)vid->v_decl);
D3DDevice_Release(vid->xdk360_render_device);
Direct3D_Release();
@ -298,7 +288,8 @@ static void xdk360_set_orientation(void * data, uint32_t orientation)
break;
}
hlsl_program.modelViewProj = XMMatrixRotationZ(angle);
hlsl_use(vid->xdk360_render_device, 0);
hlsl_set_proj_matrix(XMMatrixRotationZ(angle));
}
static void xdk360_set_aspect_ratio(void * data, uint32_t aspectratio_index)
@ -355,54 +346,7 @@ static void *xdk360_gfx_init(const video_info_t *video, const input_driver_t **i
// D3DCREATE_HARDWARE_VERTEXPROCESSING is ignored on 360
ret = Direct3D_CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &vid->d3dpp, &vid->xdk360_render_device);
ID3DXBuffer* pShaderCodeV = NULL;
ID3DXBuffer* pShaderCodeP = NULL;
ID3DXBuffer* pErrorMsg = NULL;
ret = D3DXCompileShaderFromFile(
g_settings.video.cg_shader_path, //filepath
NULL, //macros
NULL, //includes
"main_vertex", // main function
"vs_2_0", // shader profile
0, // flags
&pShaderCodeV, // compiled operations
&pErrorMsg, // errors
NULL); // constants
if (SUCCEEDED(ret))
{
SSNES_LOG("Vertex shader program from [%s] successfully compiled.\n", "game:\\media\\shaders\\stock.cg");
ret = D3DXCompileShaderFromFile(
g_settings.video.cg_shader_path, //filepath
NULL, //macros
NULL, //includes
"main_fragment", // main function
"ps_2_0", // shader profile
0, // flags
&pShaderCodeP, // compiled operations
&pErrorMsg, // errors
NULL); // constants
}
if (FAILED(ret))
{
if(pErrorMsg)
SSNES_LOG("%s\n", (char*)pErrorMsg->GetBufferPointer());
D3DDevice_Release(vid->xdk360_render_device);
Direct3D_Release();
free(vid);
return NULL;
}
else
{
SSNES_LOG("Pixel shader program from [%s] successfully compiled.\n", "game:\\media\\shaders\\stock.cg");
}
vid->pVertexShader = D3DDevice_CreateVertexShader((const DWORD*)pShaderCodeV->GetBufferPointer());
vid->pPixelShader = D3DDevice_CreatePixelShader((const DWORD*)pShaderCodeP->GetBufferPointer());
pShaderCodeV->Release();
pShaderCodeP->Release();
hlsl_init(NULL);
vid->lpTexture = (D3DTexture*) D3DDevice_CreateTexture(512, 512, 1, 1, 0, D3DFMT_LIN_X1R5G5B5,
0, D3DRTYPE_TEXTURE);
@ -435,7 +379,7 @@ static void *xdk360_gfx_init(const video_info_t *video, const input_driver_t **i
D3DDECL_END()
};
vid->pVertexDecl = D3DDevice_CreateVertexDeclaration(VertexElements);
vid->v_decl = D3DDevice_CreateVertexDeclaration(VertexElements);
D3DDevice_Clear(vid->xdk360_render_device, 0, NULL, D3DCLEAR_TARGET,
0xff000000, 1.0f, 0, FALSE);
@ -459,10 +403,10 @@ static bool xdk360_gfx_frame(void *data, const void *frame,
unsigned width, unsigned height, unsigned pitch, const char *msg)
{
xdk360_video_t *vid = (xdk360_video_t*)data;
g_frame_count++;
D3DDevice_Clear(vid->xdk360_render_device, 0, NULL, D3DCLEAR_TARGET,
0xff000000, 1.0f, 0, FALSE);
g_frame_count++;
if (vid->last_width != width || vid->last_height != height)
{
@ -490,9 +434,8 @@ static bool xdk360_gfx_frame(void *data, const void *frame,
vid->last_height = height;
}
vid->xdk360_render_device->SetVertexShaderConstantF(0, (FLOAT*)&hlsl_program.modelViewProj, 4);
//TODO: Update the shader constants
hlsl_use(vid->xdk360_render_device, 0);
hlsl_set_params(vid->xdk360_render_device);
D3DLOCKED_RECT d3dlr;
D3DTexture_LockRect(vid->lpTexture, 0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
@ -510,10 +453,7 @@ static bool xdk360_gfx_frame(void *data, const void *frame,
D3DDevice_SetSamplerState(vid->xdk360_render_device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
D3DDevice_SetSamplerState(vid->xdk360_render_device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
D3DDevice_SetVertexShader(vid->xdk360_render_device, vid->pVertexShader);
D3DDevice_SetPixelShader(vid->xdk360_render_device, vid->pPixelShader);
D3DDevice_SetVertexDeclaration(vid->xdk360_render_device, vid->pVertexDecl);
D3DDevice_SetVertexDeclaration(vid->xdk360_render_device, vid->v_decl);
D3DDevice_SetStreamSource_Inline(vid->xdk360_render_device, 0, vid->vertex_buf, 0,
sizeof(DrawVerticeFormats));

View File

@ -48,11 +48,9 @@ typedef struct xdk360_video
unsigned last_height;
IDirect3D9* xdk360_device;
IDirect3DDevice9* xdk360_render_device;
IDirect3DVertexShader9 *pVertexShader;
IDirect3DPixelShader9* pPixelShader;
IDirect3DVertexDeclaration9* pVertexDecl;
IDirect3DVertexBuffer9* vertex_buf;
IDirect3DTexture9* lpTexture;
IDirect3DVertexDeclaration9* v_decl;
D3DPRESENT_PARAMETERS d3dpp;
XVIDEO_MODE video_mode;
} xdk360_video_t;

View File

@ -715,7 +715,7 @@ static bool load_imports(const char *dir_path, config_file_t *conf)
state_tracker = state_tracker_init(&tracker_info);
if (!state_tracker)
SSNES_WARN("Failed to init state tracker.\n");
SSNES_WARN("Failed to initialize state tracker.\n");
#ifdef HAVE_PYTHON
if (script)

203
gfx/shader_hlsl.c Normal file
View File

@ -0,0 +1,203 @@
/* SSNES - A frontend for libretro.
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
* Copyright (C) 2011-2012 - Daniel De Matteis
*
* SSNES is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with SSNES.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "shader_hlsl.h"
#ifdef _XBOX
#include <xtl.h>
#endif
struct hlsl_program
{
IDirect3DVertexShader9 *vprg;
IDirect3DPixelShader9 *fprg;
D3DXHANDLE vid_size_f;
D3DXHANDLE tex_size_f;
D3DXHANDLE out_size_f;
D3DXHANDLE vid_size_v;
D3DXHANDLE tex_size_v;
D3DXHANDLE out_size_v;
XMMATRIX mvp;
};
static struct hlsl_program prg[SSNES_HLSL_MAX_SHADERS];
static bool hlsl_active = false;
static const char *stock_hlsl_program =
"void main_vertex"
"("
" float2 position : POSITION,"
" float2 texCoord : TEXCOORD0,"
" uniform float4x4 modelViewProj : register(c0),"
" out float4 oPosition : POSITION,"
" out float2 otexCoord : TEXCOORD"
")"
"{"
" oPosition = mul(modelViewProj, float4(position, 0.0, 1.0));"
" otexCoord = texCoord;"
"}"
""
"struct output"
"{"
" float4 color: COLOR;"
"}"
""
"struct input"
"{"
" float2 video_size;"
" float2 texture_size;"
" float2 output_size;"
"}"
""
"output main_fragment(float2 tex : TEXCOORD0, uniform sampler2D decal : register(s0), uniform input IN)"
"{"
" output OUT;"
" OUT.color = tex2D(decal, tex);"
" return OUT;"
"}";
void hlsl_set_proj_matrix(XMMATRIX rotation_value)
{
if (hlsl_active && prg[active_index].mvp)
prg[active_index].mvp = rotation_value;
}
void hlsl_set_params(IDirect3DDevice9 * device)
{
if (!hlsl_active)
return;
if (prg[active_index].mvp)
device->SetVertexShaderConstantF(0, (FLOAT*)&prg[active_index].mvp, 4);
}
static bool load_program(unsigned index, const char *prog, bool path_is_file)
{
bool ret, ret_fp, ret_vp;
ID3DXBuffer *listing_f = NULL;
ID3DXBuffer *listing_v = NULL;
ID3DXBuffer *code_f = NULL;
ID3DXBuffer *code_v = NULL;
ret = true;
if (path_is_file)
{
ret_fp = D3DXCompileShaderFromFile(prog, NULL, NULL, "main_fragment", "ps_2_0", 0, &code_f, &listing_f, NULL);
ret_vp = D3DXCompileShaderFromFile(prog, NULL, NULL, "main_vertex", "vs_2_0", 0, &code_v, &listing_v, NULL);
}
else
{
ret_fp = D3DXCompileShader(prog, sizeof(prog), NULL, NULL, "main_fragment", "ps_2_0", 0, &code_f, &listing_f, NULL );
ret_vp = D3DXCompileShader(prog, sizeof(prog), NULL, NULL, "main_vertex", "vs_2_0", 0, &code_v, &listing_v, NULL );
}
if (FAILED(ret_fp) || FAILED(ret_vp))
{
SSNES_ERR("HLSL error:\n");
if(listing_f)
SSNES_ERR("Fragment:\n%s\n", (char*)listing_f->GetBufferPointer());
if(listing_v)
SSNES_ERR("Vertex:\n%s\n", (char*)listing_v->GetBufferPointer());
ret = false;
goto end;
}
prg[index].fprg = D3DDevice_CreatePixelShader((const DWORD*)code_f->GetBufferPointer());
prg[index].vprg = D3DDevice_CreateVertexShader((const DWORD*)code_v->GetBufferPointer());
code_f->Release();
code_v->Release();
end:
free(listing_f);
free(listing_v);
return ret;
}
static bool load_stock(void)
{
if (!load_program(0, stock_hlsl_program, false))
{
SSNES_ERR("Failed to compile passthrough shader, is something wrong with your environment?\n");
return false;
}
return true;
}
static bool load_plain(const char *path)
{
if (!load_stock())
return false;
#if 0
SSNES_LOG("Loading HLSL file: %s\n", path);
if (!load_program(1, path, true))
return false;
#endif
return true;
}
static void hlsl_deinit_progs(void)
{
D3DResource_Release((D3DResource *)vid->pPixelShader);
D3DResource_Release((D3DResource *)vid->pVertexShader);
}
static void hlsl_deinit_state(void)
{
hlsl_active = false;
hlsl_deinit_progs();
}
bool hlsl_init(const char *path)
{
if (strstr(path, ".cgp"))
{
if (!load_preset(path))
return false;
}
else
{
if (!load_plain(path))
return false;
}
hlsl_active = true;
return true;
}
void hlsl_use(IDirect3DDevice9 * device, unsigned index)
{
if (hlsl_active && prg[index].vprg && prg[index].fprg)
{
active_index = index;
D3DDevice_SetVertexShader(device, prg[index].vprg);
D3DDevice_SetPixelShader(device, prg[index].fprg);
}
}
// Full deinit.
void hlsl_deinit(void)
{
if (!hlsl_active)
return;
hlsl_deinit_state();
}

34
gfx/shader_hlsl.h Normal file
View File

@ -0,0 +1,34 @@
/* SSNES - A frontend for libretro.
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
*
* SSNES is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with SSNES.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __SSNES_HLSL_H
#define __SSNES_HLSL_H
#include <stdint.h>
bool hlsl_init(const char *path);
void hlsl_deinit(void);
void hlsl_set_proj_matrix(XMMATRIX rotation_value);
void hlsl_set_params(IDirect3DDevice9 * device);
void hlsl_use(IDirect3DDevice9 * device, unsigned index);
#define SSNES_HLSL_MAX_SHADERS 16
#endif