mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
d3d12: Try implement mipmap
The mipmap level below 0 are currently wrong, find out why
This commit is contained in:
parent
d23cf861f1
commit
178d0e0e85
4 changed files with 103 additions and 62 deletions
|
@ -88,7 +88,7 @@ D3D12_RESOURCE_DESC getBufferResourceDesc(size_t sizeInByte)
|
|||
}
|
||||
|
||||
inline
|
||||
D3D12_RESOURCE_DESC getTexture2DResourceDesc(size_t width, size_t height, DXGI_FORMAT dxgiFormat)
|
||||
D3D12_RESOURCE_DESC getTexture2DResourceDesc(size_t width, size_t height, DXGI_FORMAT dxgiFormat, size_t mipmapLevels)
|
||||
{
|
||||
D3D12_RESOURCE_DESC result;
|
||||
result = {};
|
||||
|
@ -98,7 +98,7 @@ D3D12_RESOURCE_DESC getTexture2DResourceDesc(size_t width, size_t height, DXGI_F
|
|||
result.Format = dxgiFormat;
|
||||
result.DepthOrArraySize = 1;
|
||||
result.SampleDesc.Count = 1;
|
||||
result.MipLevels = 1;
|
||||
result.MipLevels = mipmapLevels;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -545,7 +545,7 @@ D3D12GSRender::D3D12GSRender()
|
|||
m_device->CreateCommittedResource(
|
||||
&hp,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&getTexture2DResourceDesc(2, 2, DXGI_FORMAT_R8G8B8A8_UNORM),
|
||||
&getTexture2DResourceDesc(2, 2, DXGI_FORMAT_R8G8B8A8_UNORM, 1),
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&m_dummyTexture))
|
||||
|
@ -1150,7 +1150,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
|
|||
{
|
||||
D3D12_HEAP_PROPERTIES heapProp = {};
|
||||
heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
D3D12_RESOURCE_DESC resdesc = getTexture2DResourceDesc(m_surface_clip_w, m_surface_clip_h, DXGI_FORMAT_R8_UNORM);
|
||||
D3D12_RESOURCE_DESC resdesc = getTexture2DResourceDesc(m_surface_clip_w, m_surface_clip_h, DXGI_FORMAT_R8_UNORM, 1);
|
||||
resdesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||
|
||||
size_t sizeInByte = m_surface_clip_w * m_surface_clip_h * 2;
|
||||
|
|
|
@ -180,7 +180,7 @@ ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device,
|
|||
D3D12_HEAP_PROPERTIES heapProp = {};
|
||||
heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
|
||||
D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, dxgiFormat);
|
||||
D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, dxgiFormat, 1);
|
||||
resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
|
||||
device->CreateCommittedResource(
|
||||
|
@ -235,7 +235,7 @@ ID3D12Resource * RenderTargets::bindAddressAsDepthStencil(ID3D12Device * device,
|
|||
assert(0);
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, dxgiFormat);
|
||||
D3D12_RESOURCE_DESC resourceDesc = getTexture2DResourceDesc(width, height, dxgiFormat, 1);
|
||||
resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||
|
||||
device->CreateCommittedResource(
|
||||
|
|
|
@ -136,6 +136,14 @@ D3D12_FILTER getSamplerFilter(u32 minFilter, u32 magFilter)
|
|||
return D3D12_ENCODE_BASIC_FILTER(min, mag, mip, D3D12_FILTER_REDUCTION_TYPE_STANDARD);
|
||||
}
|
||||
|
||||
struct MipmapLevelInfo
|
||||
{
|
||||
size_t offset;
|
||||
size_t width;
|
||||
size_t height;
|
||||
size_t rowPitch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a texture residing in default heap and generate uploads commands in commandList,
|
||||
* using a temporary texture buffer.
|
||||
|
@ -302,7 +310,7 @@ ID3D12Resource *uploadSingleTexture(
|
|||
size_t rowPitch = powerOf2Align(blockSizeInByte * widthInBlocks, 256);
|
||||
|
||||
ID3D12Resource *Texture;
|
||||
size_t textureSize = rowPitch * heightInBlocks;
|
||||
size_t textureSize = rowPitch * heightInBlocks * 4; // * 3 for mipmap levels
|
||||
assert(textureBuffersHeap.canAlloc(textureSize));
|
||||
size_t heapOffset = textureBuffersHeap.alloc(textureSize);
|
||||
|
||||
|
@ -321,60 +329,85 @@ ID3D12Resource *uploadSingleTexture(
|
|||
check(Texture->Map(0, nullptr, (void**)&textureData));
|
||||
|
||||
// Upload with correct rowpitch
|
||||
for (unsigned row = 0; row < heightInBlocks; row++)
|
||||
std::vector<MipmapLevelInfo> mipinfos;
|
||||
size_t offsetInDst = 0, offsetInSrc = 0;
|
||||
size_t currentHeight = heightInBlocks, currentWidth = widthInBlocks;
|
||||
|
||||
unsigned tmp = texture.GetMipmap();
|
||||
if (tmp > 1)
|
||||
printf("here");
|
||||
for (unsigned mipLevel = 0; mipLevel < texture.GetMipmap(); mipLevel++)
|
||||
{
|
||||
switch (format)
|
||||
MipmapLevelInfo currentMipmapLevelInfo = {};
|
||||
currentMipmapLevelInfo.offset = offsetInDst;
|
||||
currentMipmapLevelInfo.height = currentHeight;
|
||||
currentMipmapLevelInfo.width = currentWidth;
|
||||
|
||||
for (unsigned row = 0; row < currentHeight; row++)
|
||||
{
|
||||
case CELL_GCM_TEXTURE_A8R8G8B8:
|
||||
{
|
||||
if (is_swizzled)
|
||||
switch (format)
|
||||
{
|
||||
u32 *src, *dst;
|
||||
u32 log2width, log2height;
|
||||
case CELL_GCM_TEXTURE_A8R8G8B8:
|
||||
{
|
||||
currentMipmapLevelInfo.rowPitch = powerOf2Align(currentWidth * blockSizeInByte, 256);
|
||||
if (is_swizzled)
|
||||
{
|
||||
u32 *src, *dst;
|
||||
u32 log2width, log2height;
|
||||
|
||||
src = (u32*)pixels;
|
||||
dst = (u32*)textureData;
|
||||
src = (u32*)pixels + offsetInSrc;
|
||||
dst = (u32*)textureData + offsetInDst;
|
||||
|
||||
log2width = (u32)(logf((float)w) / logf(2.f));
|
||||
log2height = (u32)(logf((float)h) / logf(2.f));
|
||||
log2width = (u32)(logf((float)currentWidth) / logf(2.f));
|
||||
log2height = (u32)(logf((float)currentHeight) / logf(2.f));
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int j = 0; j < w; j++)
|
||||
dst[(row * currentMipmapLevelInfo.rowPitch / 4) + j] = src[LinearToSwizzleAddress(j, row, 0, log2width, log2height, 0)];
|
||||
}
|
||||
else
|
||||
memcpy((char*)textureData + offsetInDst + row * currentMipmapLevelInfo.rowPitch, (char*)pixels + offsetInSrc + row * currentWidth * blockSizeInByte, currentWidth * blockSizeInByte);
|
||||
break;
|
||||
}
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4:
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
{
|
||||
currentMipmapLevelInfo.rowPitch = rowPitch;
|
||||
unsigned short *dst = (unsigned short *)textureData, *src = (unsigned short *)pixels;
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int j = 0; j < w; j++)
|
||||
dst[(row * rowPitch / 4) + j] = src[LinearToSwizzleAddress(j, row, 0, log2width, log2height, 0)];
|
||||
{
|
||||
u16 tmp = src[offsetInSrc / 2 + row * srcPitch / 2 + j];
|
||||
dst[offsetInDst / 2 + row * rowPitch / 2 + j] = (tmp >> 8) | (tmp << 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
streamBuffer((char*)textureData + row * rowPitch, (char*)pixels + row * srcPitch, srcPitch);
|
||||
break;
|
||||
}
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4:
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
{
|
||||
unsigned short *dst = (unsigned short *)textureData, *src = (unsigned short *)pixels;
|
||||
|
||||
for (int j = 0; j < w; j++)
|
||||
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
|
||||
{
|
||||
u16 tmp = src[row * srcPitch / 2 + j];
|
||||
dst[row * rowPitch / 2 + j] = (tmp >> 8) | (tmp << 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT:
|
||||
{
|
||||
unsigned short *dst = (unsigned short *)textureData, *src = (unsigned short *)pixels;
|
||||
currentMipmapLevelInfo.rowPitch = rowPitch;
|
||||
unsigned short *dst = (unsigned short *)textureData, *src = (unsigned short *)pixels;
|
||||
|
||||
for (int j = 0; j < w * 4; j++)
|
||||
{
|
||||
unsigned short tmp = src[row * w * 4 + j];
|
||||
dst[row * w * 4 + j] = (tmp >> 8) | (tmp << 8);
|
||||
for (int j = 0; j < w * 4; j++)
|
||||
{
|
||||
unsigned short tmp = src[offsetInSrc / 2 + row * w * 4 + j];
|
||||
dst[offsetInDst / 2 + row * w * 4 + j] = (tmp >> 8) | (tmp << 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
currentMipmapLevelInfo.rowPitch = rowPitch;
|
||||
streamBuffer((char*)textureData + offsetInDst + row * rowPitch, (char*)pixels + offsetInSrc + row * srcPitch, srcPitch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
streamBuffer((char*)textureData + row * rowPitch, (char*)pixels + row * srcPitch, srcPitch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
offsetInDst += currentHeight * currentMipmapLevelInfo.rowPitch;
|
||||
offsetInDst = powerOf2Align(offsetInDst, 256);
|
||||
offsetInSrc += currentHeight * currentWidth * blockSizeInByte;
|
||||
mipinfos.push_back(currentMipmapLevelInfo);
|
||||
currentHeight /= 2;
|
||||
currentWidth /= 2;
|
||||
}
|
||||
Texture->Unmap(0, nullptr);
|
||||
|
||||
|
@ -387,25 +420,33 @@ ID3D12Resource *uploadSingleTexture(
|
|||
check(device->CreatePlacedResource(
|
||||
textureHeap.m_heap,
|
||||
heapOffset2,
|
||||
&getTexture2DResourceDesc(w, h, dxgiFormat),
|
||||
&getTexture2DResourceDesc(w, h, dxgiFormat, texture.GetMipmap()),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&vramTexture)
|
||||
));
|
||||
textureHeap.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset2, textureSize, vramTexture));
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {};
|
||||
dst.pResource = vramTexture;
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
src.pResource = Texture;
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
src.PlacedFootprint.Footprint.Depth = 1;
|
||||
src.PlacedFootprint.Footprint.Width = (UINT)w;
|
||||
src.PlacedFootprint.Footprint.Height = (UINT)h;
|
||||
src.PlacedFootprint.Footprint.RowPitch = (UINT)rowPitch;
|
||||
src.PlacedFootprint.Footprint.Format = dxgiFormat;
|
||||
|
||||
commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
|
||||
size_t miplevel = 0;
|
||||
for (const MipmapLevelInfo mli : mipinfos)
|
||||
{
|
||||
D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {};
|
||||
dst.pResource = vramTexture;
|
||||
dst.SubresourceIndex = miplevel;
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
src.PlacedFootprint.Offset = mli.offset;
|
||||
src.pResource = Texture;
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
src.PlacedFootprint.Footprint.Depth = 1;
|
||||
src.PlacedFootprint.Footprint.Width = (UINT)mli.width;
|
||||
src.PlacedFootprint.Footprint.Height = (UINT)mli.height;
|
||||
src.PlacedFootprint.Footprint.RowPitch = (UINT)mli.rowPitch;
|
||||
src.PlacedFootprint.Footprint.Format = dxgiFormat;
|
||||
|
||||
commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
|
||||
miplevel++;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
|
@ -461,7 +502,7 @@ size_t D3D12GSRender::UploadTextures()
|
|||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
|
||||
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Format = dxgiFormat;
|
||||
srvDesc.Texture2D.MipLevels = 1;
|
||||
srvDesc.Texture2D.MipLevels = m_textures[i].GetMipmap();
|
||||
|
||||
switch (format)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue