added D3D11 Texture::get_data implementation

This commit is contained in:
Noel Berry 2020-12-31 00:44:38 -08:00
parent 920e7ac644
commit c22b5a7639

View File

@ -96,11 +96,13 @@ namespace Blah
int m_width; int m_width;
int m_height; int m_height;
TextureFormat m_format; TextureFormat m_format;
DXGI_FORMAT m_dxgi_format;
bool m_is_framebuffer; bool m_is_framebuffer;
int m_size; int m_size;
public: public:
ID3D11Texture2D* texture = nullptr; ID3D11Texture2D* texture = nullptr;
ID3D11Texture2D* staging = nullptr;
ID3D11ShaderResourceView* view = nullptr; ID3D11ShaderResourceView* view = nullptr;
D3D11_Texture(int width, int height, TextureFormat format, bool is_framebuffer) D3D11_Texture(int width, int height, TextureFormat format, bool is_framebuffer)
@ -146,6 +148,8 @@ namespace Blah
break; break;
} }
m_dxgi_format = desc.Format;
auto hr = state.device->CreateTexture2D(&desc, NULL, &texture); auto hr = state.device->CreateTexture2D(&desc, NULL, &texture);
if (!SUCCEEDED(hr)) if (!SUCCEEDED(hr))
{ {
@ -167,8 +171,11 @@ namespace Blah
{ {
if (texture) if (texture)
texture->Release(); texture->Release();
if (staging)
staging->Release();
if (view) if (view)
view->Release(); view->Release();
staging = nullptr;
texture = nullptr; texture = nullptr;
view = nullptr; view = nullptr;
} }
@ -190,6 +197,7 @@ namespace Blah
virtual void set_data(unsigned char* data) override virtual void set_data(unsigned char* data) override
{ {
// bounds
D3D11_BOX box; D3D11_BOX box;
box.left = 0; box.left = 0;
box.right = m_width; box.right = m_width;
@ -198,6 +206,7 @@ namespace Blah
box.front = 0; box.front = 0;
box.back = 1; box.back = 1;
// set data
state.context->UpdateSubresource( state.context->UpdateSubresource(
texture, texture,
0, 0,
@ -209,7 +218,60 @@ namespace Blah
virtual void get_data(unsigned char* data) override virtual void get_data(unsigned char* data) override
{ {
BLAH_ASSERT(false, "Not Implemented Yet"); HRESULT hr;
// bounds
D3D11_BOX box;
box.left = 0;
box.right = m_width;
box.top = 0;
box.bottom = m_height;
box.front = 0;
box.back = 1;
// create staging texture
if (!staging)
{
D3D11_TEXTURE2D_DESC desc;
desc.Width = m_width;
desc.Height = m_height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = m_dxgi_format;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
hr = state.device->CreateTexture2D(&desc, NULL, &staging);
if (!SUCCEEDED(hr))
{
BLAH_ERROR("Failed to create staging texture to get data");
return;
}
}
// copy data to staging texture
state.context->CopySubresourceRegion(
staging, 0,
0, 0, 0,
texture, 0,
&box);
// get data
D3D11_MAPPED_SUBRESOURCE map;
hr = state.context->Map(staging, 0, D3D11_MAP_READ, 0, &map);
if (!SUCCEEDED(hr))
{
BLAH_ERROR("Failed to get texture data");
return;
}
memcpy(data, map.pData, m_size);
state.context->Unmap(staging, 0);
} }
virtual bool is_framebuffer() const override virtual bool is_framebuffer() const override
@ -309,6 +371,7 @@ namespace Blah
StackVector<ShaderData::HLSL_Attribute, 16> attributes; StackVector<ShaderData::HLSL_Attribute, 16> attributes;
Vector<UniformInfo> uniform_list; Vector<UniformInfo> uniform_list;
uint32_t hash = 0; uint32_t hash = 0;
bool valid = false;
D3D11_Shader(const ShaderData* data) D3D11_Shader(const ShaderData* data)
{ {
@ -333,12 +396,8 @@ namespace Blah
if (FAILED(hr)) if (FAILED(hr))
{ {
if (error_blob) Log::error("%s", (char*)error_blob->GetBufferPointer());
{ error_blob->Release();
Log::error("%s", (char*)error_blob->GetBufferPointer());
error_blob->Release();
}
return; return;
} }
} }
@ -360,12 +419,8 @@ namespace Blah
if (FAILED(hr)) if (FAILED(hr))
{ {
if (error_blob) Log::error("%s", (char*)error_blob->GetBufferPointer());
{ error_blob->Release();
Log::error("%s", (char*)error_blob->GetBufferPointer());
error_blob->Release();
}
return; return;
} }
} }
@ -430,6 +485,9 @@ namespace Blah
hash = ((hash << 5) + hash) + it.semantic_name[i]; hash = ((hash << 5) + hash) + it.semantic_name[i];
hash = it.semantic_index << 5 + hash; hash = it.semantic_index << 5 + hash;
} }
// Shader is ready for use!
valid = true;
} }
~D3D11_Shader() ~D3D11_Shader()
@ -528,15 +586,22 @@ namespace Blah
data.pSysMem = indices; data.pSysMem = indices;
// create // create
state.device->CreateBuffer(&desc, &data, &index_buffer); auto hr = state.device->CreateBuffer(&desc, &data, &index_buffer);
BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Index Data");
} }
} }
else if (indices) else if (indices)
{ {
D3D11_MAPPED_SUBRESOURCE resource; D3D11_MAPPED_SUBRESOURCE map;
state.context->Map(index_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
memcpy(resource.pData, indices, index_stride * count); auto hr = state.context->Map(index_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
state.context->Unmap(index_buffer, 0); BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Index Data");
if (SUCCEEDED(hr))
{
memcpy(map.pData, indices, index_stride * count);
state.context->Unmap(index_buffer, 0);
}
} }
} }
@ -569,16 +634,22 @@ namespace Blah
data.pSysMem = vertices; data.pSysMem = vertices;
// create // create
state.device->CreateBuffer(&desc, &data, &vertex_buffer); auto hr = state.device->CreateBuffer(&desc, &data, &vertex_buffer);
BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Vertex Data");
} }
} }
// otherwise just update it // otherwise just update it
else if (vertices) else if (vertices)
{ {
D3D11_MAPPED_SUBRESOURCE resource; D3D11_MAPPED_SUBRESOURCE map;
state.context->Map(vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); auto hr = state.context->Map(vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
memcpy(resource.pData, vertices, vertex_format.stride * count); BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Vertex Data");
state.context->Unmap(vertex_buffer, 0);
if (SUCCEEDED(hr))
{
memcpy(map.pData, vertices, vertex_format.stride * count);
state.context->Unmap(vertex_buffer, 0);
}
} }
} }
@ -726,6 +797,8 @@ namespace Blah
void GraphicsBackend::before_render() void GraphicsBackend::before_render()
{ {
HRESULT hr;
auto next_size = Point(App::draw_width(), App::draw_height()); auto next_size = Point(App::draw_width(), App::draw_height());
if (state.last_size != next_size) if (state.last_size != next_size)
{ {
@ -734,15 +807,17 @@ namespace Blah
state.backbuffer->Release(); state.backbuffer->Release();
// perform resize // perform resize
state.swap_chain->ResizeBuffers(2, next_size.x, next_size.y, DXGI_FORMAT_B8G8R8A8_UNORM, 0); hr = state.swap_chain->ResizeBuffers(2, next_size.x, next_size.y, DXGI_FORMAT_B8G8R8A8_UNORM, 0);
BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Backbuffer on Resize");
state.last_size = next_size; state.last_size = next_size;
// get the new buffer // get the new buffer
ID3D11Texture2D* frame_buffer = nullptr; ID3D11Texture2D* frame_buffer = nullptr;
state.swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer); hr = state.swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&frame_buffer);
if (frame_buffer) if (SUCCEEDED(hr) && frame_buffer)
{ {
state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer); hr = state.device->CreateRenderTargetView(frame_buffer, nullptr, &state.backbuffer);
BLAH_ASSERT(SUCCEEDED(hr), "Failed to update Backbuffer on Resize");
frame_buffer->Release(); frame_buffer->Release();
} }
} }
@ -750,12 +825,14 @@ namespace Blah
void GraphicsBackend::after_render() void GraphicsBackend::after_render()
{ {
state.swap_chain->Present(1, 0); auto hr = state.swap_chain->Present(1, 0);
BLAH_ASSERT(SUCCEEDED(hr), "Failed to Present swap chain");
} }
TextureRef GraphicsBackend::create_texture(int width, int height, TextureFormat format) TextureRef GraphicsBackend::create_texture(int width, int height, TextureFormat format)
{ {
auto result = new D3D11_Texture(width, height, format, false); auto result = new D3D11_Texture(width, height, format, false);
if (result->texture) if (result->texture)
return TextureRef(result); return TextureRef(result);
@ -771,7 +848,7 @@ namespace Blah
ShaderRef GraphicsBackend::create_shader(const ShaderData* data) ShaderRef GraphicsBackend::create_shader(const ShaderData* data)
{ {
auto result = new D3D11_Shader(data); auto result = new D3D11_Shader(data);
if (result->vertex && result->fragment && result->vertex_blob && result->fragment_blob) if (result->valid)
return ShaderRef(result); return ShaderRef(result);
delete result; delete result;