bool ShaderImpl_DirectX9::SetCompiledBinary(const unsigned char *bin, int type) { if(!DrawManager::GetDeviceHandle()) return false; switch(type) { case Shader::TYPE_VERTEX: if (DrawManager::GetDeviceHandle()->CreateVertexShader(reinterpret_cast<const DWORD*>(bin), &_vertexShader) == S_OK) { if(D3DXGetShaderConstantTable(reinterpret_cast<const DWORD*>(bin), &_vs_constTable) == S_OK) { setupConstantData(UNIFORM_VS, _vs_constTable); } return true; } return false; case Shader::TYPE_PIXEL: if (DrawManager::GetDeviceHandle()->CreatePixelShader(reinterpret_cast<const DWORD*>(bin), &_pixelShader) == S_OK) { if(D3DXGetShaderConstantTable(reinterpret_cast<const DWORD*>(bin), &_ps_constTable) == S_OK) { setupConstantData(UNIFORM_PS, _ps_constTable); } return true; } return false; } return false; }
static void test_get_sampler_index(void) { ID3DXConstantTable *ctable; HRESULT res; UINT index; ULONG refcnt; res = D3DXGetShaderConstantTable(ctab_samplers, &ctable); ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on ctab_samplers: got %08x\n", res); index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler1"); ok(index == 0, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 0\n", index); index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler2"); ok(index == 3, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 3\n", index); index = ID3DXConstantTable_GetSamplerIndex(ctable, "nonexistent"); ok(index == -1, "ID3DXConstantTable_GetSamplerIndex found nonexistent sampler: Got %d\n", index); index = ID3DXConstantTable_GetSamplerIndex(ctable, "notsampler"); ok(index == -1, "ID3DXConstantTable_GetSamplerIndex succeeded on non-sampler constant: Got %d\n", index); refcnt = ID3DXConstantTable_Release(ctable); ok(refcnt == 0, "The ID3DXConstantTable reference count was %u, should be 0\n", refcnt); }
bool ILine::LoadVertexShader(const char* i_VertexShaderpath, IDirect3DDevice9 * i_direct3dDevice #ifdef EAE2014_SHOULDALLRETURNVALUESBECHECKED , std::string* o_errorMessage #endif ) { assert(i_direct3dDevice && i_VertexShaderpath); // Load the compiled source file it void * compiledShader; { if (!Material::LoadAndAllocateShaderProgram(i_VertexShaderpath, compiledShader #ifdef EAE2014_SHOULDALLRETURNVALUESBECHECKED , o_errorMessage #endif )) { return false; } } D3DXGetShaderConstantTable(reinterpret_cast<DWORD*>(compiledShader), &m_pvertexShaderConsts); //Get reference to per-instance constant if (m_pvertexShaderConsts != NULL) { if (!LoadVertexShaderConstants(i_VertexShaderpath, m_pvertexShaderConsts, i_direct3dDevice #ifdef EAE2014_SHOULDALLRETURNVALUESBECHECKED , o_errorMessage #endif )) { return false; } } // Create the vertex shader object bool wereThereErrors = false; { HRESULT result = i_direct3dDevice->CreateVertexShader(reinterpret_cast<DWORD*>(compiledShader), &m_vertexShader); if (FAILED(result)) { #ifdef EAE2014_SHOULDALLRETURNVALUESBECHECKED if (o_errorMessage) { *o_errorMessage = "DirectX failed to create the vertex shader"; } #endif wereThereErrors = true; } if (compiledShader) free(compiledShader); } return !wereThereErrors; }
HRESULT APIENTRY D3DProxyDeviceAdv::SetVertexShader(IDirect3DVertexShader9* pvShader) { IDirect3DVertexShader9* pShader = NULL; LPD3DXCONSTANTTABLE pConstantTable = NULL; BYTE *pData = NULL; HRESULT hr = m_pDevice->SetVertexShader(pvShader); m_pDevice->GetVertexShader(&pShader); UINT pSizeOfData; if(NULL == pShader) goto grexit; pShader->GetFunction(NULL,&pSizeOfData); findWeirdMirrorsEdgeShader(pSizeOfData); pData = new BYTE[pSizeOfData]; pShader->GetFunction(pData,&pSizeOfData); bool shaderSeen = hasSeenShader(pSizeOfData); D3DXCONSTANT_DESC pConstantDesc[32]; UINT pConstantNum = 32; D3DXGetShaderConstantTable(reinterpret_cast<DWORD*>(pData),&pConstantTable); if(pConstantTable == NULL) goto grexit; D3DXCONSTANTTABLE_DESC pDesc; pConstantTable->GetDesc(&pDesc); for(UINT i = 0; i < pDesc.Constants; i++) { D3DXHANDLE Handle = pConstantTable->GetConstant(NULL,i); if(Handle == NULL) continue; pConstantTable->GetConstantDesc(Handle,pConstantDesc,&pConstantNum); for(UINT j = 0; j < pConstantNum; j++) { removeExistingMatrices(pConstantDesc[j]); parse4by4Matrices(pConstantDesc[j]); parseIndividualFloats(pConstantDesc[j]); } } grexit: _SAFE_RELEASE(pConstantTable); _SAFE_RELEASE(pShader); if(pData) delete[] pData; return hr; }
CShaderConstTableLite* CShaderConstTableLite::CreateShaderConstTableLite( IMemoryAllocator* allocator, IZ_PCSTR path) { void *buf = ALLOC(allocator, sizeof(CShaderConstTableLite)); VRETURN_NULL(buf != IZ_NULL); IZ_BOOL result = IZ_TRUE; CShaderConstTableLite* instance = new(buf) CShaderConstTableLite; { instance->AddRef(); instance->m_Allocator = allocator; izanagi::CFileInputStream input; result = input.Open(path); VGOTO(result, __EXIT__); void* program = ALLOC(allocator, (size_t)input.GetSize()); result = (program != IZ_NULL); VGOTO(result, __EXIT__); input.Read(program, 0, (size_t)input.GetSize()); // シェーダ定数テーブル取得 HRESULT hr = D3DXGetShaderConstantTable( (const DWORD*)program, &instance->m_ConstTable); result = SUCCEEDED(hr); result = (instance->m_ConstTable != IZ_NULL); IZ_ASSERT(result); FREE(allocator, program); } __EXIT__: if (!result) { SAFE_RELEASE(instance); } return instance; }
//============================================================================== // Shader //------------------------------------------------------------------------------ unsigned int Shader::createPixShader(const char * file) { HRESULT hr; auto pDevice = _renderer->getDevice(); PixShader* pixelShader = new PixShader(); if(!isfile((kBaceShaderFolder + file).c_str())) { MessageBoxA(NULL,"そんなファイルネェ","error",MB_OK); App::instance().exit(); return 0; } DWORD* shader = fileread((kBaceShaderFolder + file).c_str()); // constTable取得 hr = D3DXGetShaderConstantTable(shader, &pixelShader->_constTable); if(FAILED(hr)) { MessageBoxA(NULL,"よくわからんけどエラー",("D3DXGetShaderConstantTable"),MB_OK); App::instance().exit(); SafeDeleteArray(shader); return 0; } // ピクセルシェーダ生成 hr = pDevice->CreatePixelShader(shader, &pixelShader->_shader); if(FAILED(hr)) { MessageBox(NULL,TEXT("PixelShaderFailed"),TEXT("CreatePixelShader"),MB_OK); App::instance().exit(); SafeDeleteArray(shader); return 0; } pixelShader->filename = file; // インサート _pixShaderList.push_back(pixelShader); _pixShaderMap.insert(std::pair<std::string,unsigned int>(file,_pixShaderList.size() - 1)); SafeDeleteArray(shader); return _pixShaderList.size() - 1; }
static void test_setting_arrays_table(IDirect3DDevice9 *device) { static const float farray[8] = { 0.005f, 0.745f, 0.973f, 0.264f, 0.010f, 0.020f, 0.030f, 0.040f}; static const D3DXMATRIX fmtxarray[2] = { {{{0.001f, 0.002f, 0.003f, 0.004f, 0.005f, 0.006f, 0.007f, 0.008f, 0.009f, 0.010f, 0.011f, 0.012f, 0.013f, 0.014f, 0.015f, 0.016f}}}, {{{0.010f, 0.020f, 0.030f, 0.040f, 0.050f, 0.060f, 0.070f, 0.080f, 0.090f, 0.100f, 0.110f, 0.120f, 0.130f, 0.140f, 0.150f, 0.160f}}}}; static const int iarray[4] = {1, 2, 3, 4}; static const D3DXVECTOR4 fvecarray[2] = { {0.745f, 0.997f, 0.353f, 0.237f}, {0.060f, 0.455f, 0.333f, 0.983f}}; ID3DXConstantTable *ctable; HRESULT res; float out[32]; ULONG refcnt; /* Get the constant table from the shader */ res = D3DXGetShaderConstantTable(ctab_arrays, &ctable); ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res); /* Set constants */ /* Make sure that we cannot set registers that do not belong to this constant */ res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 8); ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got 0x%08x\n", res); IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 8); ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3], "The in-bounds elements of the array were not set, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]); ok(out[16] == 0.0f && out[20] == 0.0f && out[24] == 0.0f && out[28] == 0.0f, "The excess elements of the array were set, out={%f, %f, %f, %f}, should be all 0.0f\n", out[16], out[20], out[24], out[28]); /* ivecarray takes up only 1 register, but a matrix takes up 4, so no elements should be set */ res = ID3DXConstantTable_SetMatrix(ctable, device, "ivecarray", &fmtxarray[0]); ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got 0x%08x\n", res); IDirect3DDevice9_GetVertexShaderConstantF(device, 18, out, 4); ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f, "The array was set, out={%f, %f, %f, %f}, should be all 0.0f\n", out[0], out[1], out[2], out[3]); /* Try setting an integer array to an array declared as a float array */ res = ID3DXConstantTable_SetIntArray(ctable, device, "farray", iarray, 4); ok(res == D3D_OK, "ID3DXConstantTable_SetIntArray failed: got 0x%08x\n", res); IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4); ok(out[0] == iarray[0] && out[4] == iarray[1] && out[8] == iarray[2] && out[12] == iarray[3], "SetIntArray did not properly set a float array: out={%f, %f, %f, %f}, should be {%d, %d, %d, %d}\n", out[0], out[4], out[8], out[12], iarray[0], iarray[1], iarray[2], iarray[3]); res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 4); ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got x0%08x\n", res); res = ID3DXConstantTable_SetVectorArray(ctable, device, "fvecarray", fvecarray, 2); ok(res == D3D_OK, "ID3DXConstantTable_SetVectorArray failed: got 0x%08x\n", res); res = ID3DXConstantTable_SetMatrixArray(ctable, device, "fmtxarray", fmtxarray, 2); ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixArray failed: got 0x%08x\n", res); /* Read back constants */ IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4); ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3], "The variable farray was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]); IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 2); ok(out[0] == fvecarray[0].x && out[1] == fvecarray[0].y && out[2] == fvecarray[0].z && out[3] == fvecarray[0].w && out[4] == fvecarray[1].x && out[5] == fvecarray[1].y && out[6] == fvecarray[1].z && out[7] == fvecarray[1].w, "The variable fvecarray was not set correctly, out={{%f, %f, %f, %f}, {%f, %f, %f, %f}}, should be " "{{%f, %f, %f, %f}, {%f, %f, %f, %f}}\n", out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], fvecarray[0].x, fvecarray[0].y, fvecarray[0].z, fvecarray[0].w, fvecarray[1].x, fvecarray[1].y, fvecarray[1].z, fvecarray[1].w); IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 8); /* Just check a few elements in each matrix to make sure fmtxarray was set row-major */ ok(out[0] == S(U(fmtxarray[0]))._11 && out[1] == S(U(fmtxarray[0]))._12 && out[2] == S(U(fmtxarray[0]))._13 && out[3] == S(U(fmtxarray[0]))._14, "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", out[0], out[1], out[2], out[3], S(U(fmtxarray[0]))._11, S(U(fmtxarray[0]))._12, S(U(fmtxarray[0]))._13, S(U(fmtxarray[0]))._14); ok(out[16] == S(U(fmtxarray[1]))._11 && out[17] == S(U(fmtxarray[1]))._12 && out[18] == S(U(fmtxarray[1]))._13 && out[19] == S(U(fmtxarray[1]))._14, "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", out[16], out[17], out[18], out[19], S(U(fmtxarray[1]))._11, S(U(fmtxarray[1]))._12, S(U(fmtxarray[1]))._13, S(U(fmtxarray[1]))._14); refcnt = ID3DXConstantTable_Release(ctable); ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt); }
static void test_setting_basic_table(IDirect3DDevice9 *device) { static const D3DXMATRIX mvp = {{{ 0.514f, 0.626f, 0.804f, 0.786f, 0.238f, 0.956f, 0.374f, 0.483f, 0.109f, 0.586f, 0.900f, 0.255f, 0.898f, 0.411f, 0.932f, 0.275f}}}; static const D3DXVECTOR4 f4 = {0.350f, 0.526f, 0.925f, 0.021f}; static const float f = 0.12543f; static const int i = 321; ID3DXConstantTable *ctable; HRESULT res; float out[16]; ULONG refcnt; /* Get the constant table from the shader itself */ res = D3DXGetShaderConstantTable(ctab_basic, &ctable); ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res); /* Set constants */ res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp); ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable mvp: got 0x%08x\n", res); ID3DXConstantTable_SetInt(ctable, device, "i", i + 1); ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res); /* Check that setting i again will overwrite the previous value */ res = ID3DXConstantTable_SetInt(ctable, device, "i", i); ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res); res = ID3DXConstantTable_SetFloat(ctable, device, "f", f); ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable f: got 0x%08x\n", res); res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4); ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f4: got 0x%08x\n", res); /* Get constants back and validate */ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4); ok(out[0] == S(U(mvp))._11 && out[4] == S(U(mvp))._12 && out[8] == S(U(mvp))._13 && out[12] == S(U(mvp))._14, "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14); ok(out[1] == S(U(mvp))._21 && out[5] == S(U(mvp))._22 && out[9] == S(U(mvp))._23 && out[13] == S(U(mvp))._24, "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24); ok(out[2] == S(U(mvp))._31 && out[6] == S(U(mvp))._32 && out[10] == S(U(mvp))._33 && out[14] == S(U(mvp))._34, "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34); ok(out[3] == S(U(mvp))._41 && out[7] == S(U(mvp))._42 && out[11] == S(U(mvp))._43 && out[15] == S(U(mvp))._44, "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44); IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 1); ok(out[0] == (float)i && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f, "The variable i was not set correctly, out={%f, %f, %f, %f}, should be {%d, 0.0, 0.0, 0.0}\n", out[0], out[1], out[2], out[3], i); IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1); ok(out[0] == f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f, "The variable f was not set correctly, out={%f, %f, %f, %f}, should be {%f, 0.0, 0.0, 0.0}\n", out[0], out[1], out[2], out[3], f); IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1); ok(memcmp(out, (void*)&f4, sizeof(f4)) == 0, "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n", out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w); /* Finally test using a set* function for one type to set a variable of another type (should succeed) */ res = ID3DXConstantTable_SetVector(ctable, device, "f", &f4); ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f: 0x%08x\n", res); IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1); ok(out[0] == f4.x, "The variable f was not set correctly by ID3DXConstantTable_SetVector, got %f, should be %f\n", out[0], f4.x); refcnt = ID3DXConstantTable_Release(ctable); ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt); }
static void test_constant_table(const char *test_name, const DWORD *ctable_fn, const D3DXCONSTANT_DESC *expecteds, UINT count) { UINT i; ID3DXConstantTable *ctable; HRESULT res; /* Get the constant table from the shader itself */ res = D3DXGetShaderConstantTable(ctable_fn, &ctable); ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on %s: got %08x\n", test_name, res); for (i = 0; i < count; i++) { const D3DXCONSTANT_DESC *expected = &expecteds[i]; D3DXHANDLE const_handle; D3DXCONSTANT_DESC actual; UINT pCount = 1; const_handle = ID3DXConstantTable_GetConstantByName(ctable, NULL, expected->Name); res = ID3DXConstantTable_GetConstantDesc(ctable, const_handle, &actual, &pCount); ok(SUCCEEDED(res), "%s in %s: ID3DXConstantTable_GetConstantDesc returned %08x\n", expected->Name, test_name, res); ok(pCount == 1, "%s in %s: Got more or less descriptions: %d\n", expected->Name, test_name, pCount); ok(strcmp(actual.Name, expected->Name) == 0, "%s in %s: Got different names: Got %s, expected %s\n", expected->Name, test_name, actual.Name, expected->Name); ok(actual.RegisterSet == expected->RegisterSet, "%s in %s: Got different register sets: Got %d, expected %d\n", expected->Name, test_name, actual.RegisterSet, expected->RegisterSet); ok(actual.RegisterIndex == expected->RegisterIndex, "%s in %s: Got different register indices: Got %d, expected %d\n", expected->Name, test_name, actual.RegisterIndex, expected->RegisterIndex); ok(actual.RegisterCount == expected->RegisterCount, "%s in %s: Got different register counts: Got %d, expected %d\n", expected->Name, test_name, actual.RegisterCount, expected->RegisterCount); ok(actual.Class == expected->Class, "%s in %s: Got different classes: Got %d, expected %d\n", expected->Name, test_name, actual.Class, expected->Class); ok(actual.Type == expected->Type, "%s in %s: Got different types: Got %d, expected %d\n", expected->Name, test_name, actual.Type, expected->Type); ok(actual.Rows == expected->Rows && actual.Columns == expected->Columns, "%s in %s: Got different dimensions: Got (%d, %d), expected (%d, %d)\n", expected->Name, test_name, actual.Rows, actual.Columns, expected->Rows, expected->Columns); ok(actual.Elements == expected->Elements, "%s in %s: Got different element count: Got %d, expected %d\n", expected->Name, test_name, actual.Elements, expected->Elements); ok(actual.StructMembers == expected->StructMembers, "%s in %s: Got different struct member count: Got %d, expected %d\n", expected->Name, test_name, actual.StructMembers, expected->StructMembers); ok(actual.Bytes == expected->Bytes, "%s in %s: Got different byte count: Got %d, expected %d\n", expected->Name, test_name, actual.Bytes, expected->Bytes); } /* Finally, release the constant table */ ID3DXConstantTable_Release(ctable); }
// technique TechniqueHandle Gfx_Technique_Create(RenderDevice* dev, const TechniqueDescr& descr) { if( descr.ps.valid()==false ) return InvalidResourceHandle(); if( descr.vs.valid()==false ) return InvalidResourceHandle(); if( descr.vf.valid()==false ) return InvalidResourceHandle(); TechniqueDX9 res; res.ps = descr.ps; res.vs = descr.vs; res.vf = descr.vf; ID3DXConstantTable* vsct = NULL; ID3DXConstantTable* psct = NULL; const VertexShaderDX9& vs = dev->resources->vertex_shaders[descr.vs]; const PixelShaderDX9& ps = dev->resources->pixel_shaders[descr.ps]; D3DXGetShaderConstantTable((DWORD*)vs.code.data(), &vsct); D3DXGetShaderConstantTable((DWORD*)ps.code.data(), &psct); dx9_fill_constant_table(res.vs_constants, res.vs_samplers, vsct); dx9_fill_constant_table(res.ps_constants, res.ps_samplers, psct); SafeRelease(vsct); SafeRelease(psct); // create constant bindings [TODO: deal with samplers and vertex streams] const ShaderConstantBindings* bindings = descr.bindings; if( bindings ) { for( uint32 i=0; i<bindings->items.size(); ++i ) { const ShaderConstantBindings::Item& item = bindings->items[i]; if( item.type == ShaderConstantBindings::BindingType_Constant ) { ShaderConstantIndex vs_idx = res.vs_constants.index_from_name(item.name); if( vs_idx.is_valid() ) { TechniqueDX9::Binding b; b.index = vs_idx.index; b.count = rush_min(vs_idx.count, item.count); b.data = item.data; res.vs_bindings.push_back(b); } ShaderConstantIndex ps_idx = res.ps_constants.index_from_name(item.name); if( ps_idx.is_valid() ) { TechniqueDX9::Binding b; b.index = ps_idx.index; b.count = rush_min(ps_idx.count, item.count); b.data = item.data; res.ps_bindings.push_back(b); } } else if( item.type == ShaderConstantBindings::BindingType_Sampler ) { // TODO } } } return dev->resources->techniques.push(res); }
/** * Returns a collection of modified constants for the specified shader. * (may be an empty collection if no modifications apply) * <StrartRegister, StereoShaderConstant<float>> * * Hash the shader and load modification rules: * If rules for this specific shader use those else use default rules. * * For each shader constant: * Check if constant matches a rule (name and/or index). If it does create a stereoshaderconstant * based on rule and add to map of stereoshaderconstants to return. * * @param pActualVertexShader The actual (not wrapped) vertex shader. * @return Collection of stereoshaderconstants for this shader (empty collection if no modifications). ***/ std::map<UINT, StereoShaderConstant<float>> ShaderModificationRepository::GetModifiedConstantsF(IDirect3DVertexShader9* pActualVertexShader) { // All rules are assumed to be valid. Validation of rules should be done when rules are loaded/created std::vector<ConstantModificationRule*> rulesToApply; std::map<UINT, StereoShaderConstant<float>> result; // Hash the shader and load modification rules BYTE *pData = NULL; UINT pSizeOfData; pActualVertexShader->GetFunction(NULL, &pSizeOfData); pData = new BYTE[pSizeOfData]; pActualVertexShader->GetFunction(pData,&pSizeOfData); uint32_t hash; MurmurHash3_x86_32(pData, pSizeOfData, VIREIO_SEED, &hash); if (m_shaderSpecificModificationRuleIDs.count(hash) == 1) { // There are specific modification rules to use with this shader auto itRules = m_shaderSpecificModificationRuleIDs[hash].begin(); while (itRules != m_shaderSpecificModificationRuleIDs[hash].end()) { rulesToApply.push_back(&(m_AllModificationRules[*itRules])); ++itRules; } } else { // No specific rules, use general rules auto itRules = m_defaultModificationRuleIDs.begin(); while (itRules != m_defaultModificationRuleIDs.end()) { rulesToApply.push_back(&(m_AllModificationRules[*itRules])); ++itRules; } } // Load the constant descriptions for this shader and create StereoShaderConstants as the applicable rules require them. LPD3DXCONSTANTTABLE pConstantTable = NULL; D3DXGetShaderConstantTable(reinterpret_cast<DWORD*>(pData), &pConstantTable); if(pConstantTable) { D3DXCONSTANTTABLE_DESC pDesc; pConstantTable->GetDesc(&pDesc); D3DXCONSTANT_DESC pConstantDesc[64]; for(UINT i = 0; i < pDesc.Constants; i++) { D3DXHANDLE handle = pConstantTable->GetConstant(NULL,i); if(handle == NULL) continue; UINT pConstantNum = 64; pConstantTable->GetConstantDesc(handle, pConstantDesc, &pConstantNum); if (pConstantNum >= 64) { OutputDebugString("ShaderModificationRepository::GetModifiedConstantsF - Need larger constant description buffer"); } for(UINT j = 0; j < pConstantNum; j++) { // We are only modifying selected float vectors/matricies. if (pConstantDesc[j].RegisterSet != D3DXRS_FLOAT4) continue; if ( ((pConstantDesc[j].Class == D3DXPC_VECTOR) && (pConstantDesc[j].RegisterCount == 1)) || (((pConstantDesc[j].Class == D3DXPC_MATRIX_ROWS) || (pConstantDesc[j].Class == D3DXPC_MATRIX_COLUMNS)) && (pConstantDesc[j].RegisterCount == 4)) ) { // Check if any rules match this constant auto itRules = rulesToApply.begin(); while (itRules != rulesToApply.end()) { // Type match if ((*itRules)->m_constantType == pConstantDesc[j].Class) { // name match required if ((*itRules)->m_constantName.size() > 0) { bool nameMatch = false; if ((*itRules)->m_allowPartialNameMatch) { nameMatch = std::strstr(pConstantDesc[j].Name, (*itRules)->m_constantName.c_str()) != NULL; /*if (nameMatch) { OutputDebugString("Match\n"); } else { OutputDebugString("No Match\n"); }*/ } else { nameMatch = (*itRules)->m_constantName.compare(pConstantDesc[j].Name) == 0; //OutputDebugString("Full name match only\n"); } if (!nameMatch) { // no match ++itRules; continue; } } // register match required if ((*itRules)->m_startRegIndex != UINT_MAX) { if ((*itRules)->m_startRegIndex != pConstantDesc[j].RegisterIndex) { // no match ++itRules; continue; } } #ifdef _DEBUG // output shader constant + index switch(pConstantDesc[j].Class) { case D3DXPC_VECTOR: OutputDebugString("D3DXPC_VECTOR"); break; case D3DXPC_MATRIX_ROWS: OutputDebugString("D3DXPC_MATRIX_ROWS"); break; case D3DXPC_MATRIX_COLUMNS: OutputDebugString("D3DXPC_MATRIX_COLUMNS"); break; } char buf[32]; sprintf_s(buf,"Register Index: %d", pConstantDesc[j].RegisterIndex); OutputDebugString(buf); #endif // Create StereoShaderConstant<float> and add to result result.insert(std::pair<UINT, StereoShaderConstant<>>(pConstantDesc[j].RegisterIndex, CreateStereoConstantFrom(*itRules, pConstantDesc[j].RegisterIndex, pConstantDesc[j].RegisterCount))); // only the first matching rule is applied to a constant break; } ++itRules; } } } } } _SAFE_RELEASE(pConstantTable); if (pData) delete[] pData; return result; }
HRESULT D3D9RenderImpl::SetPixelShader(DWORD* buffer) { HR(D3DXGetShaderConstantTable(buffer, &m_pPixelConstantTable)); return m_pDevice->CreatePixelShader(buffer, &m_pPixelShader); }
HRESULT D3D9RenderImpl::SetVertexShader(DWORD* buffer) { HR(D3DXGetShaderConstantTable(buffer, &m_pVertexConstantTable)); return m_pDevice->CreateVertexShader(buffer, &m_pVertexShader); }