graphicsdevice can now download textures too + resurrected wiHelper::screenshot() function
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -647,7 +647,7 @@ void wiEmittedParticle::UpdateRenderData(GRAPHICSTHREAD threadID)
|
||||
|
||||
if (DEBUG)
|
||||
{
|
||||
device->DownloadBuffer(counterBuffer, debugDataReadbackBuffer, &debugData, threadID);
|
||||
device->DownloadResource(counterBuffer, debugDataReadbackBuffer, &debugData, threadID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user