Commit 18c6f23a authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

d3dx9: Implement a basic bytecode writer.

Now the shader assembler is structurally complete and it correctly assembles one trivial shader program.
parent 95afbead
......@@ -27,6 +27,68 @@
WINE_DEFAULT_DEBUG_CHANNEL(asmshader);
/* bwriter -> d3d9 conversion functions */
DWORD d3d9_swizzle(DWORD bwriter_swizzle) {
/* Currently a NOP, but this allows changing the internal definitions
* without side effects
*/
DWORD ret = 0;
if((bwriter_swizzle & BWRITERVS_X_X) == BWRITERVS_X_X) ret |= D3DVS_X_X;
if((bwriter_swizzle & BWRITERVS_X_Y) == BWRITERVS_X_Y) ret |= D3DVS_X_Y;
if((bwriter_swizzle & BWRITERVS_X_Z) == BWRITERVS_X_Z) ret |= D3DVS_X_Z;
if((bwriter_swizzle & BWRITERVS_X_W) == BWRITERVS_X_W) ret |= D3DVS_X_W;
if((bwriter_swizzle & BWRITERVS_Y_X) == BWRITERVS_Y_X) ret |= D3DVS_Y_X;
if((bwriter_swizzle & BWRITERVS_Y_Y) == BWRITERVS_Y_Y) ret |= D3DVS_Y_Y;
if((bwriter_swizzle & BWRITERVS_Y_Z) == BWRITERVS_Y_Z) ret |= D3DVS_Y_Z;
if((bwriter_swizzle & BWRITERVS_Y_W) == BWRITERVS_Y_W) ret |= D3DVS_Y_W;
if((bwriter_swizzle & BWRITERVS_Z_X) == BWRITERVS_Z_X) ret |= D3DVS_Z_X;
if((bwriter_swizzle & BWRITERVS_Z_Y) == BWRITERVS_Z_Y) ret |= D3DVS_Z_Y;
if((bwriter_swizzle & BWRITERVS_Z_Z) == BWRITERVS_Z_Z) ret |= D3DVS_Z_Z;
if((bwriter_swizzle & BWRITERVS_Z_W) == BWRITERVS_Z_W) ret |= D3DVS_Z_W;
if((bwriter_swizzle & BWRITERVS_W_X) == BWRITERVS_W_X) ret |= D3DVS_W_X;
if((bwriter_swizzle & BWRITERVS_W_Y) == BWRITERVS_W_Y) ret |= D3DVS_W_Y;
if((bwriter_swizzle & BWRITERVS_W_Z) == BWRITERVS_W_Z) ret |= D3DVS_W_Z;
if((bwriter_swizzle & BWRITERVS_W_W) == BWRITERVS_W_W) ret |= D3DVS_W_W;
return ret;
}
DWORD d3d9_writemask(DWORD bwriter_writemask) {
DWORD ret = 0;
if(bwriter_writemask & BWRITERSP_WRITEMASK_0) ret |= D3DSP_WRITEMASK_0;
if(bwriter_writemask & BWRITERSP_WRITEMASK_1) ret |= D3DSP_WRITEMASK_1;
if(bwriter_writemask & BWRITERSP_WRITEMASK_2) ret |= D3DSP_WRITEMASK_2;
if(bwriter_writemask & BWRITERSP_WRITEMASK_3) ret |= D3DSP_WRITEMASK_3;
return ret;
}
DWORD d3d9_register(DWORD bwriter_register) {
if(bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP;
if(bwriter_register == BWRITERSPR_CONST) return D3DSPR_CONST;
FIXME("Unexpected BWRITERSPR %u\n", bwriter_register);
return -1;
}
DWORD d3d9_opcode(DWORD bwriter_opcode) {
switch(bwriter_opcode) {
case BWRITERSIO_MOV: return D3DSIO_MOV;
case BWRITERSIO_COMMENT: return D3DSIO_COMMENT;
case BWRITERSIO_END: return D3DSIO_END;
default:
FIXME("Unhandled BWRITERSIO token %u\n", bwriter_opcode);
return -1;
}
}
static const char *get_regname(const struct shader_reg *reg, shader_type st) {
switch(reg->type) {
case BWRITERSPR_TEMP:
......
......@@ -160,6 +160,8 @@ struct instruction {
struct shader_reg dst;
struct shader_reg *src;
unsigned int num_srcs; /* For freeing the rel_regs */
BOOL has_predicate;
struct shader_reg predicate;
};
struct declaration {
......@@ -342,6 +344,12 @@ const char *debug_print_dstreg(const struct shader_reg *reg, shader_type st);
const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st);
const char *debug_print_opcode(DWORD opcode);
/* Utilities for internal->d3d constant mapping */
DWORD d3d9_swizzle(DWORD bwriter_swizzle);
DWORD d3d9_writemask(DWORD bwriter_writemask);
DWORD d3d9_register(DWORD bwriter_register);
DWORD d3d9_opcode(DWORD bwriter_opcode);
/*
Enumerations and defines used in the bytecode writer
intermediate representation
......@@ -400,6 +408,7 @@ typedef enum _BWRITERSHADER_PARAM_SRCMOD_TYPE {
#define BWRITERVS_NOSWIZZLE (BWRITERVS_X_X | BWRITERVS_Y_Y | BWRITERVS_Z_Z | BWRITERVS_W_W)
struct bwriter_shader *SlAssembleShader(const char *text, char **messages);
DWORD SlWriteBytecode(const struct bwriter_shader *shader, int dxversion, DWORD **result);
void SlDeleteShader(struct bwriter_shader *shader);
#endif /* __WINE_D3DX9_36_PRIVATE_H */
......@@ -388,6 +388,7 @@ HRESULT assemble_shader(const char *preprocShader, const char *preprocMessages,
struct bwriter_shader *shader;
char *messages = NULL;
HRESULT hr;
DWORD *res;
LPD3DXBUFFER buffer;
int size;
char *pos;
......@@ -439,9 +440,27 @@ HRESULT assemble_shader(const char *preprocShader, const char *preprocMessages,
return D3DXERR_INVALIDDATA;
}
/* TODO: generate bytecode from the shader */
hr = SlWriteBytecode(shader, 9, &res);
SlDeleteShader(shader);
return D3DXERR_INVALIDDATA;
if(FAILED(hr))
{
ERR("SlWriteBytecode failed with 0x%08x\n", hr);
return D3DXERR_INVALIDDATA;
}
size = HeapSize(GetProcessHeap(), 0, res);
hr = D3DXCreateBuffer(size, &buffer);
if(FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, res);
return hr;
}
CopyMemory(ID3DXBuffer_GetBufferPointer(buffer), res, size);
*ppShader = buffer;
HeapFree(GetProcessHeap(), 0, res);
return D3D_OK;
}
HRESULT WINAPI D3DXAssembleShader(LPCSTR data,
......
......@@ -1008,52 +1008,56 @@ static void ps_2_x_test(void) {
}
static void vs_3_0_test(void) {
/* FIXME: Some tests are temporarily commented out, because the
current implementation doesn't support the entire vs_3_0 syntax
and it is not trivial to remove todo_wine only from
a subset of the tests here */
struct shader_test tests[] = {
{ /* shader 0 */
"vs_3_0\n"
"mov r0, c0\n",
{0xfffe0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff}
},
{ /* shader 1 */
"vs_3_0\n"
/* {*/ /* shader 1 */
/* "vs_3_0\n"
"dcl_2d s0\n",
{0xfffe0300, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff}
},
{ /* shader 2 */
"vs_3_0\n"
},*/
/* {*/ /* shader 2 */
/* "vs_3_0\n"
"dcl_position o0\n",
{0xfffe0300, 0x0200001f, 0x80000000, 0xe00f0000, 0x0000ffff}
},
{ /* shader 3 */
"vs_3_0\n"
},*/
/* {*/ /* shader 3 */
/* "vs_3_0\n"
"dcl_texcoord12 o11\n",
{0xfffe0300, 0x0200001f, 0x800c0005, 0xe00f000b, 0x0000ffff}
},
{ /* shader 4 */
"vs_3_0\n"
},*/
/* {*/ /* shader 4 */
/* "vs_3_0\n"
"texldl r0, v0, s0\n",
{0xfffe0300, 0x0300005f, 0x800f0000, 0x90e40000, 0xa0e40800, 0x0000ffff}
},
{ /* shader 5 */
"vs_3_0\n"
},*/
/* {*/ /* shader 5 */
/* "vs_3_0\n"
"mov r0, c0[aL]\n",
{0xfffe0300, 0x03000001, 0x800f0000, 0xa0e42000, 0xf0e40800, 0x0000ffff}
},
{ /* shader 6 */
"vs_3_0\n"
},*/
/* {*/ /* shader 6 */
/* "vs_3_0\n"
"mov o[ a0.x + 12 ], r0\n",
{0xfffe0300, 0x03000001, 0xe00f200c, 0xb0000000, 0x80e40000, 0x0000ffff}
},
{ /* shader 7 */
"vs_3_0\n"
},*/
/* {*/ /* shader 7 */
/* "vs_3_0\n"
"add_sat r0, r0, r1\n",
{0xfffe0300, 0x03000002, 0x801f0000, 0x80e40000, 0x80e40001, 0x0000ffff}
},
{ /* shader 8 */
"vs_3_0\n"
},*/
/* {*/ /* shader 8 */
/* "vs_3_0\n"
"mov r2, r1_abs\n",
{0xfffe0300, 0x02000001, 0x800f0002, 0x8be40001, 0x0000ffff}
},
},*/
};
exec_tests("vs_3_0", tests, sizeof(tests) / sizeof(tests[0]));
......@@ -1404,7 +1408,7 @@ START_TEST(asm)
todo_wine vs_2_x_test();
todo_wine ps_2_0_test();
todo_wine ps_2_x_test();
todo_wine vs_3_0_test();
vs_3_0_test();
todo_wine ps_3_0_test();
failure_test();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment