Last active
August 21, 2016 12:31
-
-
Save yorung/9d900576c48464d4dc93b4252bc198c5 to your computer and use it in GitHub Desktop.
[DX12] Create texture from dds files.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct DDSHeader { | |
uint32_t h3[3]; | |
int h, w; | |
uint32_t h2[2]; | |
int mipCnt; | |
uint32_t h13[13]; | |
uint32_t fourcc, bitsPerPixel, rMask, gMask, bMask, aMask, caps1, caps2; | |
bool IsCubeMap() const { return caps2 == 0xFE00; } | |
int GetArraySize() const { return IsCubeMap() ? 6 : 1; } | |
int GetMipCnt() const { return std::max(mipCnt, 1); } | |
}; | |
struct TexDesc { | |
IVec2 size; | |
int arraySize = 1; | |
bool isCubeMap = false; | |
}; | |
struct AFTexSubresourceData | |
{ | |
const void* ptr; | |
uint32_t pitch; | |
uint32_t pitchSlice; | |
}; | |
static ComPtr<ID3D12Resource> LoadDDSTexture(const char* name, TexDesc& texDesc) | |
{ | |
int size; | |
void* img = LoadFile(name, &size); | |
if (!img) { | |
aflog("LoadDDSTexture failed! %s", name); | |
return nullptr; | |
} | |
const DDSHeader* hdr = (DDSHeader*)img; | |
AFDTFormat format = AFDT_INVALID; | |
int(*pitchCalcurator)(int, int) = nullptr; | |
switch (hdr->fourcc) { | |
case 0x31545844: //'1TXD': | |
format = AFDT_BC1_UNORM; | |
pitchCalcurator = [](int w, int h) { return ((w + 3) / 4) * ((h + 3) / 4) * 8; }; | |
break; | |
case 0x33545844: //'3TXD': | |
format = AFDT_BC2_UNORM; | |
pitchCalcurator = [](int w, int h) { return ((w + 3) / 4) * ((h + 3) / 4) * 16; }; | |
break; | |
case 0x35545844: //'5TXD': | |
format = AFDT_BC3_UNORM; | |
pitchCalcurator = [](int w, int h) { return ((w + 3) / 4) * ((h + 3) / 4) * 16; }; | |
break; | |
default: | |
ArrangeRawDDS(img, size); | |
format = AFDT_R8G8B8A8_UNORM; | |
pitchCalcurator = [](int w, int h) { return w * h * 4; }; | |
break; | |
} | |
texDesc.size.x = hdr->w; | |
texDesc.size.y = hdr->h; | |
texDesc.arraySize = hdr->GetArraySize(); | |
texDesc.isCubeMap = hdr->IsCubeMap(); | |
int arraySize = hdr->GetArraySize(); | |
int mipCnt = hdr->GetMipCnt(); | |
std::vector<AFTexSubresourceData> r; | |
int offset = 128; | |
for (int a = 0; a < arraySize; a++) { | |
for (int m = 0; m < mipCnt; m++) { | |
int w = std::max(1, hdr->w >> m); | |
int h = std::max(1, hdr->h >> m); | |
int size = pitchCalcurator(w, h); | |
r.push_back({ (char*)img + offset, (uint32_t)pitchCalcurator(w, 1), (uint32_t)size }); | |
offset += size; | |
} | |
} | |
ComPtr<ID3D12Resource> tex = afCreateTexture2D(format, texDesc, mipCnt, &r[0]); | |
assert(tex); | |
free(img); | |
return tex; | |
} | |
static const D3D12_HEAP_PROPERTIES defaultHeapProperties = { D3D12_HEAP_TYPE_DEFAULT, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_MEMORY_POOL_UNKNOWN, 1, 1 }; | |
ComPtr<ID3D12Resource> afCreateTexture2D(AFDTFormat format, const struct TexDesc& desc, int mipCount, const AFTexSubresourceData datas[]) | |
{ | |
D3D12_RESOURCE_DESC resourceDesc = { D3D12_RESOURCE_DIMENSION_TEXTURE2D, 0, (UINT64)desc.size.x, (UINT)desc.size.y, (UINT16)desc.arraySize, (UINT16)mipCount, format, {1, 0} }; | |
ComPtr<ID3D12Resource> tex; | |
HRESULT hr = deviceMan.GetDevice()->CreateCommittedResource(&defaultHeapProperties, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, nullptr, IID_PPV_ARGS(&tex)); | |
afWriteTexture(tex, desc, mipCount, datas); | |
return tex; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment