static bool cg_d3d9_renderchain_init_shader_fvf(void *data, void *pass_data) { CGparameter param; unsigned index, i, count; unsigned tex_index = 0; bool texcoord0_taken = false; bool texcoord1_taken = false; bool stream_taken[4] = {false}; cg_renderchain_t *chain = (cg_renderchain_t*)data; Pass *pass = (Pass*)pass_data; static const D3DVERTEXELEMENT decl_end = D3DDECL_END(); D3DVERTEXELEMENT decl[MAXD3DDECLLENGTH] = {{0}}; if (cgD3D9GetVertexDeclaration(pass->vPrg, decl) == CG_FALSE) return false; for (count = 0; count < MAXD3DDECLLENGTH; count++) { if (memcmp(&decl_end, &decl[count], sizeof(decl_end)) == 0) break; } /* This is completely insane. * We do not have a good and easy way of setting up our * attribute streams, so we have to do it ourselves, yay! * * Stream 0 => POSITION * Stream 1 => TEXCOORD0 * Stream 2 => TEXCOORD1 * Stream 3 => COLOR (Not really used for anything.) * Stream {4..N} => Texture coord streams for varying resources * which have no semantics. */ std::vector<bool> indices(count); param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vPrg, CG_PROGRAM), "POSITION"); if (!param) param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vPrg, CG_PROGRAM), "POSITION0"); if (param) { static const D3DVERTEXELEMENT element = { 0, 0 * sizeof(float), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }; stream_taken[0] = true; index = cgGetParameterResourceIndex(param); decl[index] = element; indices[index] = true; RARCH_LOG("[FVF]: POSITION semantic found.\n"); } param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vPrg, CG_PROGRAM), "TEXCOORD"); if (!param) param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vPrg, CG_PROGRAM), "TEXCOORD0"); if (param) { static const D3DVERTEXELEMENT tex_coord0 = DECL_FVF_TEXCOORD(1, 3, 0); stream_taken[1] = true; texcoord0_taken = true; RARCH_LOG("[FVF]: TEXCOORD0 semantic found.\n"); index = cgGetParameterResourceIndex(param); decl[index] = tex_coord0; indices[index] = true; } param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vPrg, CG_PROGRAM), "TEXCOORD1"); if (param) { static const D3DVERTEXELEMENT tex_coord1 = DECL_FVF_TEXCOORD(2, 5, 1); stream_taken[2] = true; texcoord1_taken = true; RARCH_LOG("[FVF]: TEXCOORD1 semantic found.\n"); index = cgGetParameterResourceIndex(param); decl[index] = tex_coord1; indices[index] = true; } param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vPrg, CG_PROGRAM), "COLOR"); if (!param) param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vPrg, CG_PROGRAM), "COLOR0"); if (param) { static const D3DVERTEXELEMENT color = DECL_FVF_COLOR(3, 7, 0); stream_taken[3] = true; RARCH_LOG("[FVF]: COLOR0 semantic found.\n"); index = cgGetParameterResourceIndex(param); decl[index] = color; indices[index] = true; } /* Stream {0, 1, 2, 3} might be already taken. Find first vacant stream. */ for (index = 0; index < 4; index++) { if (stream_taken[index] == false) break; } /* Find first vacant texcoord declaration. */ if (texcoord0_taken && texcoord1_taken) tex_index = 2; else if (texcoord1_taken && !texcoord0_taken) tex_index = 0; else if (texcoord0_taken && !texcoord1_taken) tex_index = 1; for (i = 0; i < count; i++) { if (indices[i]) pass->attrib_map.push_back(0); else { D3DVERTEXELEMENT elem = DECL_FVF_TEXCOORD(index, 3, tex_index); pass->attrib_map.push_back(index); decl[i] = elem; /* Find next vacant stream. */ while ((++index < 4) && stream_taken[index]) index++; /* Find next vacant texcoord declaration. */ if ((++tex_index == 1) && texcoord1_taken) tex_index++; } } if (FAILED(chain->dev->CreateVertexDeclaration( decl, &pass->vertex_decl))) return false; return true; }
static bool d3d9_cg_renderchain_init_shader_fvf( d3d9_renderchain_t *chain, struct shader_pass *pass) { CGparameter param; unsigned index, i, count; unsigned tex_index = 0; bool texcoord0_taken = false; bool texcoord1_taken = false; bool stream_taken[4] = {false}; static const D3DVERTEXELEMENT9 decl_end = D3DDECL_END(); D3DVERTEXELEMENT9 decl[MAXD3DDECLLENGTH] = {{0}}; bool *indices = NULL; if (cgD3D9GetVertexDeclaration(pass->vprg, decl) == CG_FALSE) return false; for (count = 0; count < MAXD3DDECLLENGTH; count++) { if (string_is_equal_fast(&decl_end, &decl[count], sizeof(decl_end))) break; } /* This is completely insane. * We do not have a good and easy way of setting up our * attribute streams, so we have to do it ourselves, yay! * * Stream 0 => POSITION * Stream 1 => TEXCOORD0 * Stream 2 => TEXCOORD1 * Stream 3 => COLOR (Not really used for anything.) * Stream {4..N} => Texture coord streams for varying resources * which have no semantics. */ indices = (bool*)calloc(1, count * sizeof(*indices)); param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vprg, CG_PROGRAM), "POSITION"); if (!param) param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vprg, CG_PROGRAM), "POSITION0"); if (param) { static const D3DVERTEXELEMENT9 element = { 0, 0 * sizeof(float), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }; stream_taken[0] = true; index = cgGetParameterResourceIndex(param); decl[index] = element; indices[index] = true; RARCH_LOG("[D3D9 Cg]: FVF POSITION semantic found.\n"); } param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vprg, CG_PROGRAM), "TEXCOORD"); if (!param) param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vprg, CG_PROGRAM), "TEXCOORD0"); if (param) { static const D3DVERTEXELEMENT9 tex_coord0 = D3D9_DECL_FVF_TEXCOORD(1, 3, 0); stream_taken[1] = true; texcoord0_taken = true; RARCH_LOG("[D3D9 Cg]: FVF TEXCOORD0 semantic found.\n"); index = cgGetParameterResourceIndex(param); decl[index] = tex_coord0; indices[index] = true; } param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vprg, CG_PROGRAM), "TEXCOORD1"); if (param) { static const D3DVERTEXELEMENT9 tex_coord1 = D3D9_DECL_FVF_TEXCOORD(2, 5, 1); stream_taken[2] = true; texcoord1_taken = true; RARCH_LOG("[D3D9 Cg]: FVF TEXCOORD1 semantic found.\n"); index = cgGetParameterResourceIndex(param); decl[index] = tex_coord1; indices[index] = true; } param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vprg, CG_PROGRAM), "COLOR"); if (!param) param = d3d9_cg_find_param_from_semantic(cgGetFirstParameter(pass->vprg, CG_PROGRAM), "COLOR0"); if (param) { static const D3DVERTEXELEMENT9 color = DECL_FVF_COLOR(3, 7, 0); stream_taken[3] = true; RARCH_LOG("[D3D9 Cg]: FVF COLOR0 semantic found.\n"); index = cgGetParameterResourceIndex(param); decl[index] = color; indices[index] = true; } /* Stream {0, 1, 2, 3} might be already taken. Find first vacant stream. */ for (index = 0; index < 4; index++) { if (stream_taken[index] == false) break; } /* Find first vacant texcoord declaration. */ if (texcoord0_taken && texcoord1_taken) tex_index = 2; else if (texcoord1_taken && !texcoord0_taken) tex_index = 0; else if (texcoord0_taken && !texcoord1_taken) tex_index = 1; for (i = 0; i < count; i++) { if (indices[i]) unsigned_vector_list_append((struct unsigned_vector_list *) pass->attrib_map, 0); else { D3DVERTEXELEMENT9 elem = D3D9_DECL_FVF_TEXCOORD(index, 3, tex_index); unsigned_vector_list_append((struct unsigned_vector_list *) pass->attrib_map, index); decl[i] = elem; /* Find next vacant stream. */ while ((++index < 4) && stream_taken[index]) index++; /* Find next vacant texcoord declaration. */ if ((++tex_index == 1) && texcoord1_taken) tex_index++; } } free(indices); return d3d9_vertex_declaration_new(chain->dev, decl, (void**)&pass->vertex_decl); }
bool RenderChain::init_fvf(Pass &pass) { static const D3DVERTEXELEMENT decl_end = D3DDECL_END(); static const D3DVERTEXELEMENT position_decl = DECL_FVF_POSITION(0); static const D3DVERTEXELEMENT tex_coord0 = DECL_FVF_TEXCOORD(1, 3, 0); static const D3DVERTEXELEMENT tex_coord1 = DECL_FVF_TEXCOORD(2, 5, 1); static const D3DVERTEXELEMENT color = DECL_FVF_COLOR(3, 7, 0); D3DVERTEXELEMENT decl[MAXD3DDECLLENGTH] = {{0}}; if (cgD3D9GetVertexDeclaration(pass.vPrg, decl) == CG_FALSE) return false; unsigned count; for (count = 0; count < MAXD3DDECLLENGTH; count++) { if (memcmp(&decl_end, &decl[count], sizeof(decl_end)) == 0) break; } // This is completely insane. // We do not have a good and easy way of setting up our // attribute streams, so we have to do it ourselves, yay! // Stream 0 => POSITION // Stream 1 => TEXCOORD0 // Stream 2 => TEXCOORD1 // Stream 3 => COLOR // Not really used for anything. // Stream {4..N} => Texture coord streams for varying resources which have no semantics. std::vector<bool> indices(count); bool texcoord0_taken = false; bool texcoord1_taken = false; bool stream_taken[4] = {false}; CGparameter param = find_param_from_semantic(pass.vPrg, "POSITION"); if (!param) param = find_param_from_semantic(pass.vPrg, "POSITION0"); if (param) { stream_taken[0] = true; RARCH_LOG("[FVF]: POSITION semantic found.\n"); unsigned index = cgGetParameterResourceIndex(param); decl[index] = position_decl; indices[index] = true; } param = find_param_from_semantic(pass.vPrg, "TEXCOORD"); if (!param) param = find_param_from_semantic(pass.vPrg, "TEXCOORD0"); if (param) { stream_taken[1] = true; texcoord0_taken = true; RARCH_LOG("[FVF]: TEXCOORD0 semantic found.\n"); unsigned index = cgGetParameterResourceIndex(param); decl[index] = tex_coord0; indices[index] = true; } param = find_param_from_semantic(pass.vPrg, "TEXCOORD1"); if (param) { stream_taken[2] = true; texcoord1_taken = true; RARCH_LOG("[FVF]: TEXCOORD1 semantic found.\n"); unsigned index = cgGetParameterResourceIndex(param); decl[index] = tex_coord1; indices[index] = true; } param = find_param_from_semantic(pass.vPrg, "COLOR"); if (!param) param = find_param_from_semantic(pass.vPrg, "COLOR0"); if (param) { stream_taken[3] = true; RARCH_LOG("[FVF]: COLOR0 semantic found.\n"); unsigned index = cgGetParameterResourceIndex(param); decl[index] = color; indices[index] = true; } // Stream {0, 1, 2, 3} might be already taken. Find first vacant stream. unsigned index; for (index = 0; index < 4 && stream_taken[index]; index++); // Find first vacant texcoord declaration. unsigned tex_index = 0; if (texcoord0_taken && texcoord1_taken) tex_index = 2; else if (texcoord1_taken && !texcoord0_taken) tex_index = 0; else if (texcoord0_taken && !texcoord1_taken) tex_index = 1; for (unsigned i = 0; i < count; i++) { if (indices[i]) pass.attrib_map.push_back(0); else { pass.attrib_map.push_back(index); D3DVERTEXELEMENT elem = DECL_FVF_TEXCOORD(index, 3, tex_index); decl[i] = elem; // Find next vacant stream. index++; while (index < 4 && stream_taken[index]) index++; // Find next vacant texcoord declaration. tex_index++; if (tex_index == 1 && texcoord1_taken) tex_index++; } } if (FAILED(dev->CreateVertexDeclaration(decl, &pass.vertex_decl))) return false; return true; }