home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Asuka / source / psa.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  4.9 KB  |  190 lines

  1. //    Asuka - VirtualDub Build/Post-Mortem Utility
  2. //    Copyright (C) 2005 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include "stdafx.h"
  19. #include <vector>
  20. #include <list>
  21. #include <string>
  22. #include <d3d9.h>
  23. #include <d3dx9.h>
  24. #include <objbase.h>
  25. #include <vd2/system/refcount.h>
  26. #include <vd2/system/file.h>
  27. #include <vd2/system/filesys.h>
  28. #include <vd2/system/math.h>
  29. #include <vd2/system/VDString.h>
  30. #include <vd2/system/vdstl.h>
  31.  
  32. #pragma comment(lib, "d3dx9")
  33.  
  34. namespace {
  35.     void DeleteShaderConstantTable(vdfastvector<uint32>& shader) {
  36.         LPCVOID data;
  37.         UINT size;
  38.         if (D3D_OK == D3DXFindShaderComment((const DWORD *)shader.data(), MAKEFOURCC('C', 'T', 'A', 'B'), &data, &size)) {
  39.             ptrdiff_t offset = (char *)data - (char *)shader.data();
  40.  
  41.             VDASSERT(!(offset & 3));
  42.             VDASSERT(offset >= 8);
  43.  
  44.             // convert to dword offset
  45.             offset >>= 2;
  46.             size = (size + 3) >> 2;
  47.  
  48.             VDASSERT(offset + size <= shader.size());
  49.  
  50.             // erase comment token, fourcc, and comment data
  51.             shader.erase(shader.begin() + (offset - 2), shader.begin() + offset + size);
  52.         }
  53.     }
  54. }
  55.  
  56. void tool_psa(const vdfastvector<const char *>& args, const vdfastvector<const char *>& switches) {
  57.     if (args.size() != 2) {
  58.         puts("usage: asuka psa source.psa target.cpp");
  59.         exit(5);
  60.     }
  61.  
  62.     const char *filename = args[0];
  63.  
  64.     printf("Asuka: Assembling pixel shader (Direct3D): %s -> %s.\n", filename, args[1]);
  65.  
  66.     FILE *f = fopen(args[1], "w");
  67.     if (!f) {
  68.         printf("Couldn't open %s for write\n", args[1]);
  69.         exit(10);
  70.     }
  71.  
  72.     fprintf(f, "// Pixel shader data auto-generated by Asuka from %s. DO NOT EDIT!\n", VDFileSplitPath(filename));
  73.  
  74.     VDTextInputFile in(VDTextAToW(filename).c_str());
  75.  
  76.     vdfastvector<char> pstext;
  77.     bool pscapture = false;
  78.     bool hlslmode = false;
  79.     VDStringA psname;
  80.     int line = 0;
  81.  
  82.     for(;;) {
  83.         const char *s = in.GetNextLine();
  84.         ++line;
  85.  
  86.         if (s && (*s == '\t' || *s == 0 || *s == ' ')) {
  87.             while(*s == ' ' || *s == '\t')
  88.                 ++s;
  89.  
  90.             if (pscapture) {
  91.                 pstext.insert(pstext.end(), s, s+strlen(s));
  92.                 pstext.push_back('\n');
  93.             }
  94.             continue;
  95.         }
  96.  
  97.         if (s && !*s)
  98.             continue;
  99.  
  100.         if (pscapture) {
  101.             vdrefptr<ID3DXBuffer> pBuffer;
  102.             vdrefptr<ID3DXBuffer> pErrors;
  103.             HRESULT hr;
  104.             
  105.             if (hlslmode)
  106.                 hr = D3DXCompileShader(pstext.data(), pstext.size(), NULL, NULL, "main", "ps_2_0", 0, ~pBuffer, ~pErrors, NULL);
  107.             else
  108.                 hr = D3DXAssembleShader(pstext.data(), pstext.size(), NULL, NULL, 0, ~pBuffer, ~pErrors);
  109.  
  110.             if (FAILED(hr)) {
  111.                 printf("Effect compilation failed for \"%s\"\n", filename);
  112.  
  113.                 if (pErrors)
  114.                     puts((const char *)pErrors->GetBufferPointer());
  115.  
  116.                 exit(10);
  117.             }
  118.  
  119.             pErrors.clear();
  120.  
  121.             fprintf(f, "\n");
  122.  
  123.             const uint32 *src = (const uint32 *)pBuffer->GetBufferPointer();
  124.             vdfastvector<uint32> shader(src, src + (pBuffer->GetBufferSize() >> 2));
  125.             DeleteShaderConstantTable(shader);
  126.  
  127.             fprintf(f, "static const uint32 %s[]={\n", psname.c_str());
  128.  
  129.             if (hlslmode) {
  130.                 vdrefptr<ID3DXBuffer> disasm;
  131.                 hr = D3DXDisassembleShader((const DWORD *)shader.data(), FALSE, NULL, ~disasm);
  132.                 if (SUCCEEDED(hr)) {
  133.                     VDMemoryStream ms(disasm->GetBufferPointer(), disasm->GetBufferSize());
  134.                     VDTextStream ts(&ms);
  135.  
  136.                     while(const char *s = ts.GetNextLine()) {
  137.                         fprintf(f, "\t// %s\n", s);
  138.                     }
  139.                 }
  140.             }
  141.  
  142.             for(int i=0, count=shader.size(); i<count; i+=8) {
  143.                 fprintf(f, "\t");
  144.                 for(int j=i; j<i+8 && j<count; ++j) {
  145.                     fprintf(f, "0x%08x,", shader[j]);
  146.                 }
  147.                 fprintf(f, "\n");
  148.             }
  149.             fprintf(f, "};\n");
  150.             pscapture = false;
  151.         }
  152.  
  153.         if (!s)
  154.             break;
  155.  
  156.         const char *t = s;
  157.         if (isalpha((unsigned char)*t) || *t == '_') {
  158.             ++t;
  159.  
  160.             while(isalnum((unsigned char)*t) || *t == '_')
  161.                 ++t;
  162.  
  163.             hlslmode = false;
  164.             if (t[0] == ':' && t[1] == ':') {
  165.                 ++t;
  166.                 hlslmode = true;
  167.             }
  168.  
  169.             if (t[0] == ':' && t[1] == 0) {
  170.                 psname.assign(s, hlslmode ? t-1 : t);
  171.                 printf("\tExporting shader %s\n", psname.c_str());
  172.                 pscapture = true;
  173.                 pstext.clear();
  174.  
  175.                 if (hlslmode) {
  176.                     VDStringA s;
  177.                     s.sprintf("#line %d \"%s\"\n", line + 1, filename);
  178.                     pstext.assign(s.begin(), s.end());
  179.                 }
  180.                 continue;
  181.             }
  182.         }
  183.  
  184.         printf("%s(%d,%d): parse error\n", filename, line, (t-s) + 1);
  185.         exit(5);
  186.     }
  187.  
  188.     printf("Asuka: Assembly was successful.\n");
  189. }
  190.