graphicsdevice can now download textures too + resurrected wiHelper::screenshot() function

This commit is contained in:
turanszkij
2018-08-18 16:30:10 +01:00
parent 03dccc024b
commit a74ccbf48f
11 changed files with 119 additions and 39 deletions
+2 -1
View File
@@ -2,6 +2,7 @@
#define _CRT_SECURE_NO_WARNINGS
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
+1 -1
View File
@@ -647,7 +647,7 @@ void wiEmittedParticle::UpdateRenderData(GRAPHICSTHREAD threadID)
if (DEBUG)
{
device->DownloadBuffer(counterBuffer, debugDataReadbackBuffer, &debugData, threadID);
device->DownloadResource(counterBuffer, debugDataReadbackBuffer, &debugData, threadID);
}
}
+2
View File
@@ -37,6 +37,7 @@ uint32_t GraphicsDevice::GetFormatStride(FORMAT value)
case FORMAT_R32G32_FLOAT:
return 8;
break;
case FORMAT_R11G11B10_FLOAT:
case FORMAT_R16G16_FLOAT:
case FORMAT_R32_FLOAT:
case FORMAT_R32_UINT:
@@ -44,6 +45,7 @@ uint32_t GraphicsDevice::GetFormatStride(FORMAT value)
case FORMAT_R8G8B8A8_SINT:
case FORMAT_R8G8B8A8_UNORM:
case FORMAT_R8G8B8A8_SNORM:
case FORMAT_R10G10B10A2_UNORM:
return 4;
break;
case FORMAT_R16_FLOAT:
+2 -2
View File
@@ -23,7 +23,7 @@ namespace wiGraphicsTypes
bool TESSELLATION, MULTITHREADED_RENDERING, CONSERVATIVE_RASTERIZATION, RASTERIZER_ORDERED_VIEWS, UNORDEREDACCESSTEXTURE_LOAD_EXT;
public:
GraphicsDevice()
:FRAMECOUNT(0), VSYNC(true), SCREENWIDTH(0), SCREENHEIGHT(0), FULLSCREEN(false), RESOLUTIONCHANGED(false), BACKBUFFER_FORMAT(FORMAT_R10G10B10A2_UNORM),
:FRAMECOUNT(0), VSYNC(true), SCREENWIDTH(0), SCREENHEIGHT(0), FULLSCREEN(false), RESOLUTIONCHANGED(false), BACKBUFFER_FORMAT(FORMAT_R8G8B8A8_UNORM/*FORMAT_R10G10B10A2_UNORM*/),
TESSELLATION(false), MULTITHREADED_RENDERING(false), CONSERVATIVE_RASTERIZATION(false),RASTERIZER_ORDERED_VIEWS(false), UNORDEREDACCESSTEXTURE_LOAD_EXT(false)
{}
@@ -145,7 +145,7 @@ namespace wiGraphicsTypes
virtual void UpdateBuffer(GPUBuffer* buffer, const void* data, GRAPHICSTHREAD threadID, int dataSize = -1) = 0;
virtual void* AllocateFromRingBuffer(GPURingBuffer* buffer, size_t dataSize, UINT& offsetIntoBuffer, GRAPHICSTHREAD threadID) = 0;
virtual void InvalidateBufferAccess(GPUBuffer* buffer, GRAPHICSTHREAD threadID) = 0;
virtual bool DownloadBuffer(GPUBuffer* bufferToDownload, GPUBuffer* bufferDest, void* dataDest, GRAPHICSTHREAD threadID) = 0;
virtual bool DownloadResource(GPUResource* resourceToDownload, GPUResource* resourceDest, void* dataDest, GRAPHICSTHREAD threadID) = 0;
virtual void QueryBegin(GPUQuery *query, GRAPHICSTHREAD threadID) = 0;
virtual void QueryEnd(GPUQuery *query, GRAPHICSTHREAD threadID) = 0;
virtual bool QueryRead(GPUQuery *query, GRAPHICSTHREAD threadID) = 0;
+61 -14
View File
@@ -1581,6 +1581,11 @@ Texture2D GraphicsDevice_DX11::GetBackBuffer()
Texture2D result;
result.resource_DX11 = (wiCPUHandle)backBuffer;
backBuffer->AddRef();
D3D11_TEXTURE2D_DESC desc;
backBuffer->GetDesc(&desc);
result.desc = _ConvertTextureDesc_Inv(&desc);
return result;
}
@@ -3639,24 +3644,66 @@ void GraphicsDevice_DX11::InvalidateBufferAccess(GPUBuffer* buffer, GRAPHICSTHRE
{
deviceContexts[threadID]->Unmap((ID3D11Resource*)buffer->resource_DX11, 0);
}
bool GraphicsDevice_DX11::DownloadBuffer(GPUBuffer* bufferToDownload, GPUBuffer* bufferDest, void* dataDest, GRAPHICSTHREAD threadID)
bool GraphicsDevice_DX11::DownloadResource(GPUResource* resourceToDownload, GPUResource* resourceDest, void* dataDest, GRAPHICSTHREAD threadID)
{
assert(bufferToDownload->desc.ByteWidth <= bufferDest->desc.ByteWidth);
assert(bufferDest->desc.Usage & USAGE_STAGING);
assert(dataDest != nullptr);
deviceContexts[threadID]->CopyResource((ID3D11Resource*)bufferDest->resource_DX11, (ID3D11Resource*)bufferToDownload->resource_DX11);
D3D11_MAPPED_SUBRESOURCE mappedResource = {};
HRESULT hr = deviceContexts[threadID]->Map((ID3D11Resource*)bufferDest->resource_DX11, 0, D3D11_MAP_READ, /*async ? D3D11_MAP_FLAG_DO_NOT_WAIT :*/ 0, &mappedResource);
bool result = SUCCEEDED(hr);
if (result)
// Download Buffer:
{
memcpy(dataDest, mappedResource.pData, bufferToDownload->desc.ByteWidth);
deviceContexts[threadID]->Unmap((ID3D11Resource*)bufferDest->resource_DX11, 0);
GPUBuffer* bufferToDownload = dynamic_cast<GPUBuffer*>(resourceToDownload);
GPUBuffer* bufferDest = dynamic_cast<GPUBuffer*>(resourceDest);
if (bufferToDownload != nullptr && bufferDest != nullptr)
{
assert(bufferToDownload->desc.ByteWidth <= bufferDest->desc.ByteWidth);
assert(bufferDest->desc.Usage & USAGE_STAGING);
assert(dataDest != nullptr);
deviceContexts[threadID]->CopyResource((ID3D11Resource*)bufferDest->resource_DX11, (ID3D11Resource*)bufferToDownload->resource_DX11);
D3D11_MAPPED_SUBRESOURCE mappedResource = {};
HRESULT hr = deviceContexts[threadID]->Map((ID3D11Resource*)bufferDest->resource_DX11, 0, D3D11_MAP_READ, /*async ? D3D11_MAP_FLAG_DO_NOT_WAIT :*/ 0, &mappedResource);
bool result = SUCCEEDED(hr);
if (result)
{
memcpy(dataDest, mappedResource.pData, bufferToDownload->desc.ByteWidth);
deviceContexts[threadID]->Unmap((ID3D11Resource*)bufferDest->resource_DX11, 0);
}
return result;
}
}
return result;
// Download Texture:
{
Texture* textureToDownload = dynamic_cast<Texture*>(resourceToDownload);
Texture* textureDest = dynamic_cast<Texture*>(resourceDest);
if (textureToDownload != nullptr && textureDest != nullptr)
{
assert(textureToDownload->desc.Width <= textureDest->desc.Width);
assert(textureToDownload->desc.Height <= textureDest->desc.Height);
assert(textureToDownload->desc.Depth <= textureDest->desc.Depth);
assert(textureDest->desc.Usage & USAGE_STAGING);
assert(dataDest != nullptr);
deviceContexts[threadID]->CopyResource((ID3D11Resource*)textureDest->resource_DX11, (ID3D11Resource*)textureToDownload->resource_DX11);
D3D11_MAPPED_SUBRESOURCE mappedResource = {};
HRESULT hr = deviceContexts[threadID]->Map((ID3D11Resource*)textureDest->resource_DX11, 0, D3D11_MAP_READ, 0, &mappedResource);
bool result = SUCCEEDED(hr);
if (result)
{
UINT cpycount = max(1, textureToDownload->desc.Width) * max(1, textureToDownload->desc.Height) * max(1, textureToDownload->desc.Depth);
UINT cpystride = GetFormatStride(textureToDownload->desc.Format);
UINT cpysize = cpycount * cpystride;
memcpy(dataDest, mappedResource.pData, cpysize);
deviceContexts[threadID]->Unmap((ID3D11Resource*)textureDest->resource_DX11, 0);
}
return result;
}
}
return false;
}
void GraphicsDevice_DX11::WaitForGPU()
+1 -1
View File
@@ -149,7 +149,7 @@ namespace wiGraphicsTypes
virtual void UpdateBuffer(GPUBuffer* buffer, const void* data, GRAPHICSTHREAD threadID, int dataSize = -1) override;
virtual void* AllocateFromRingBuffer(GPURingBuffer* buffer, size_t dataSize, UINT& offsetIntoBuffer, GRAPHICSTHREAD threadID) override;
virtual void InvalidateBufferAccess(GPUBuffer* buffer, GRAPHICSTHREAD threadID) override;
virtual bool DownloadBuffer(GPUBuffer* bufferToDownload, GPUBuffer* bufferDest, void* dataDest, GRAPHICSTHREAD threadID) override;
virtual bool DownloadResource(GPUResource* resourceToDownload, GPUResource* resourceDest, void* dataDest, GRAPHICSTHREAD threadID) override;
virtual void QueryBegin(GPUQuery *query, GRAPHICSTHREAD threadID) override;
virtual void QueryEnd(GPUQuery *query, GRAPHICSTHREAD threadID) override;
virtual bool QueryRead(GPUQuery *query, GRAPHICSTHREAD threadID) override;
+1 -1
View File
@@ -3908,7 +3908,7 @@ namespace wiGraphicsTypes
void GraphicsDevice_DX12::InvalidateBufferAccess(GPUBuffer* buffer, GRAPHICSTHREAD threadID)
{
}
bool GraphicsDevice_DX12::DownloadBuffer(GPUBuffer* bufferToDownload, GPUBuffer* bufferDest, void* dataDest, GRAPHICSTHREAD threadID)
bool GraphicsDevice_DX12::DownloadResource(GPUResource* resourceToDownload, GPUResource* resourceDest, void* dataDest, GRAPHICSTHREAD threadID)
{
return false;
}
+1 -1
View File
@@ -241,7 +241,7 @@ namespace wiGraphicsTypes
virtual void UpdateBuffer(GPUBuffer* buffer, const void* data, GRAPHICSTHREAD threadID, int dataSize = -1) override;
virtual void* AllocateFromRingBuffer(GPURingBuffer* buffer, size_t dataSize, UINT& offsetIntoBuffer, GRAPHICSTHREAD threadID) override;
virtual void InvalidateBufferAccess(GPUBuffer* buffer, GRAPHICSTHREAD threadID) override;
virtual bool DownloadBuffer(GPUBuffer* bufferToDownload, GPUBuffer* bufferDest, void* dataDest, GRAPHICSTHREAD threadID) override;
virtual bool DownloadResource(GPUResource* resourceToDownload, GPUResource* resourceDest, void* dataDest, GRAPHICSTHREAD threadID) override;
virtual void QueryBegin(GPUQuery *query, GRAPHICSTHREAD threadID) override;
virtual void QueryEnd(GPUQuery *query, GRAPHICSTHREAD threadID) override;
virtual bool QueryRead(GPUQuery *query, GRAPHICSTHREAD threadID) override;
+1 -1
View File
@@ -5157,7 +5157,7 @@ namespace wiGraphicsTypes
{
//vkUnmapMemory(device, static_cast<VkDeviceMemory>(buffer->resourceMemory_Vulkan));
}
bool GraphicsDevice_Vulkan::DownloadBuffer(GPUBuffer* bufferToDownload, GPUBuffer* bufferDest, void* dataDest, GRAPHICSTHREAD threadID)
bool GraphicsDevice_Vulkan::DownloadResource(GPUResource* resourceToDownload, GPUResource* resourceDest, void* dataDest, GRAPHICSTHREAD threadID)
{
return false;
}
+1 -1
View File
@@ -281,7 +281,7 @@ namespace wiGraphicsTypes
virtual void UpdateBuffer(GPUBuffer* buffer, const void* data, GRAPHICSTHREAD threadID, int dataSize = -1) override;
virtual void* AllocateFromRingBuffer(GPURingBuffer* buffer, size_t dataSize, UINT& offsetIntoBuffer, GRAPHICSTHREAD threadID) override;
virtual void InvalidateBufferAccess(GPUBuffer* buffer, GRAPHICSTHREAD threadID) override;
virtual bool DownloadBuffer(GPUBuffer* bufferToDownload, GPUBuffer* bufferDest, void* dataDest, GRAPHICSTHREAD threadID) override;
virtual bool DownloadResource(GPUResource* resourceToDownload, GPUResource* resourceDest, void* dataDest, GRAPHICSTHREAD threadID) override;
virtual void QueryBegin(GPUQuery *query, GRAPHICSTHREAD threadID) override;
virtual void QueryEnd(GPUQuery *query, GRAPHICSTHREAD threadID) override;
virtual bool QueryRead(GPUQuery *query, GRAPHICSTHREAD threadID) override;
+46 -16
View File
@@ -3,6 +3,8 @@
#include "wiBackLog.h"
#include "wiWindowRegistration.h"
#include "Utility/stb_image_write.h"
#include <locale>
#include <direct.h>
#include <chrono>
@@ -74,22 +76,50 @@ namespace wiHelper
void screenshot(const std::string& name)
{
//CreateDirectoryA("screenshots", 0);
//stringstream ss("");
//if (name.length() <= 0)
// ss << GetOriginalWorkingDirectory() << "screenshots/sc_" << getCurrentDateTimeAsString() << ".png";
//else
// ss << name;
//if (SUCCEEDED(wiRenderer::GetDevice()->SaveTexturePNG(ss.str(), &wiRenderer::GetDevice()->GetBackBuffer(), GRAPHICSTHREAD_IMMEDIATE)))
//{
// ss << " Saved successfully!";
// wiBackLog::post(ss.str().c_str());
//}
//else
//{
// wiBackLog::post("Screenshot failed");
//}
messageBox("Please reimplement wiHelper::screenshot functionality!");
CreateDirectoryA("screenshots", 0);
stringstream ss("");
if (name.length() <= 0)
ss << GetOriginalWorkingDirectory() << "screenshots/sc_" << getCurrentDateTimeAsString() << ".jpg";
else
ss << name;
using namespace wiGraphicsTypes;
GraphicsDevice* device = wiRenderer::GetDevice();
device->WaitForGPU();
static Texture2D tex = device->GetBackBuffer();
TextureDesc desc = tex.GetDesc();
UINT data_count = desc.Width * desc.Height;
UINT data_stride = device->GetFormatStride(desc.Format);
UINT data_size = data_count * data_stride;
static unsigned char* data = nullptr;
static Texture2D* stagingTex = nullptr;
if (stagingTex == nullptr)
{
TextureDesc staging_desc = desc;
staging_desc.Usage = USAGE_STAGING;
staging_desc.CPUAccessFlags = CPU_ACCESS_READ;
staging_desc.BindFlags = 0;
staging_desc.MiscFlags = 0;
HRESULT hr = device->CreateTexture2D(&staging_desc, nullptr, &stagingTex);
assert(SUCCEEDED(hr));
data = new unsigned char[data_size];
}
bool download_success = device->DownloadResource(&tex, stagingTex, data, GRAPHICSTHREAD_IMMEDIATE);
assert(download_success);
// TODO: png would be better, but it has some problems now...
//int write_result = stbi_write_png(ss.str().c_str(), (int)desc.Width, (int)desc.Height, 4, data, (int)data_stride);
int write_result = stbi_write_jpg(ss.str().c_str(), (int)desc.Width, (int)desc.Height, 4, data, 100);
//int write_result = stbi_write_bmp(ss.str().c_str(), (int)desc.Width, (int)desc.Height, 4, data);
assert(write_result);
}
string getCurrentDateTimeAsString()