summaryrefslogtreecommitdiffstats
path: root/tools/render-test/surface.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-06-28 11:14:48 -0700
committerGitHub <noreply@github.com>2018-06-28 11:14:48 -0700
commitdfe13b54286b27dd15f591455bbb86b7798285c2 (patch)
tree4a11f01feaae059b6c11bdfbe12a614228af6dd5 /tools/render-test/surface.cpp
parent22033f06573f900dc030c487b2c30feddf3d8f16 (diff)
Share graphics API layer between tests/examples (#603)
The `render-test` project has an in-progress graphics API abstraction layer, and it makes sense to share this code with our examples rather than write a bunch of redundant code between examples and tests. Most of this change is just moving files from `tools/render-test/*` to a new library project at `tools/slang-graphics/`. The most complicated code change there is renaming from `render_test` to `slang_graphics`. The existing `hello` example was ported to use the graphics API layer instead of raw D3D11 API calls. It is still hard-coded to use the D3D11 back-end and the `SLANG_DXBC` target, so more work is needed if we want to actually support multiple APIs in the examples. I also went ahead and implemented an extremely rudimentary set of APIs to abstract over the Windows platform calls that were being made in the example, so that we could potentially run that same example on other platforms. I did *not* port `render-test` to use those APIs, and I also did not implement them for anything but Windows (my assumption is that for most other platforms we would just use SDL2, and require people to ensure it is installed to their machine before building Slang examples).
Diffstat (limited to 'tools/render-test/surface.cpp')
-rw-r--r--tools/render-test/surface.cpp222
1 files changed, 0 insertions, 222 deletions
diff --git a/tools/render-test/surface.cpp b/tools/render-test/surface.cpp
deleted file mode 100644
index eabe555c3..000000000
--- a/tools/render-test/surface.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-// surface.cpp
-#include "surface.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "../../source/core/list.h"
-
-namespace renderer_test {
-using namespace Slang;
-
-class MallocSurfaceAllocator: public SurfaceAllocator
-{
- public:
-
- virtual Slang::Result allocate(int width, int height, Format format, int alignment, Surface& surface) override;
- virtual void deallocate(Surface& surface) override;
-};
-
-static MallocSurfaceAllocator s_mallocSurfaceAllocator;
-
-/// Get the malloc allocator
-/* static */SurfaceAllocator* SurfaceAllocator::getMallocAllocator()
-{
- return &s_mallocSurfaceAllocator;
-}
-
-Slang::Result MallocSurfaceAllocator::allocate(int width, int height, Format format, int alignment, Surface& surface)
-{
- assert(surface.m_data == nullptr);
-
- // Calculate row size
-
- const int rowSizeInBytes = Surface::calcRowSize(format, width);
- const int numRows = Surface::calcNumRows(format, height);
-
- alignment = (alignment <= 0) ? int(sizeof(void*)) : alignment;
- // It must be a power of 2
- assert( ((alignment - 1) & alignment) == 0);
-
- // Align rowSize
- const int alignedRowSizeInBytes = (rowSizeInBytes + alignment - 1) & -alignment;
-
- size_t totalSize = numRows * alignedRowSizeInBytes;
-
- uint8_t* data = (uint8_t*)::malloc(totalSize);
- if (!data)
- {
- return SLANG_E_OUT_OF_MEMORY;
- }
-
- surface.m_data = data;
- surface.m_width = width;
- surface.m_height = height;
- surface.m_format = format;
- surface.m_numRows = numRows;
- surface.m_rowStrideInBytes = alignedRowSizeInBytes;
-
- surface.m_allocator = this;
- return SLANG_OK;
-}
-
-void MallocSurfaceAllocator::deallocate(Surface& surface)
-{
- assert(surface.m_data);
- // Make sure it's not an inverted, cos otherwise m_data is not the start address
- assert(surface.m_rowStrideInBytes > 0);
- ::free(surface.m_data);
-}
-
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Surface !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-/* static */int Surface::calcRowSize(Format format, int width)
-{
- size_t pixelSize = RendererUtil::getFormatSize(format);
- if (pixelSize == 0)
- {
- return 0;
- }
- return int(pixelSize * width);
-}
-
-/* static */int Surface::calcNumRows(Format format, int height)
-{
- // Don't have any compressed types, so number of rows is same as the height
- return height;
-}
-
-void Surface::init()
-{
- m_width = 0;
- m_height = 0;
- m_format = Format::Unknown;
- m_data = nullptr;
- m_numRows = 0;
- m_rowStrideInBytes = 0;
- // NOTE! does not clear the allocator.
- // If called with an allocation memory will leak!
-}
-
-Surface::~Surface()
-{
- if (m_data && m_allocator)
- {
- m_allocator->deallocate(*this);
- }
-}
-
-void Surface::deallocate()
-{
- if (m_data && m_allocator)
- {
- m_allocator->deallocate(*this);
- init();
- }
-}
-
-Result Surface::allocate(int width, int height, Format format, int alignment, SurfaceAllocator* allocator)
-{
- deallocate();
- allocator = allocator ? allocator : m_allocator;
- if (!allocator)
- {
- // An allocator needs to be set on the surface, or one passed in.
- return SLANG_FAIL;
- }
- return allocator->allocate(width, height, format, alignment, *this);
-}
-
-void Surface::setUnowned(int width, int height, Format format, int strideInBytes, void* data)
-{
- deallocate();
-
- // This is unowned
- m_allocator = nullptr;
-
- m_width = width;
- m_height = height;
- m_format = format;
- m_rowStrideInBytes = strideInBytes;
- m_data = (uint8_t*)data;
-
- m_numRows = Surface::calcNumRows(format, height);
-
- const int rowSizeInBytes = Surface::calcRowSize(format, width);
- assert((strideInBytes > 0 && rowSizeInBytes <= strideInBytes) || (strideInBytes < 0 && rowSizeInBytes <= -strideInBytes));
-}
-
-void Surface::zeroContents()
-{
- const int rowSizeInBytes = Surface::calcRowSize(m_format, m_width);
-
- const int stride = m_rowStrideInBytes;
- uint8_t* dst = m_data;
-
- for (int i = 0; i < m_numRows; i++, dst += stride)
- {
- ::memset(dst, 0, rowSizeInBytes);
- }
-}
-
-void Surface::flipInplaceVertically()
-{
- // Can only flip when m_height matches number of rows
- assert(m_numRows == m_height);
-
- const int rowSizeInBytes = Surface::calcRowSize(m_format, m_width);
- if (rowSizeInBytes <= 0 || m_numRows <= 1)
- {
- return;
- }
-
- uint8_t* top = m_data;
- uint8_t* bottom = m_data + (m_numRows - 1) * m_rowStrideInBytes;
-
- List<uint8_t> bufferList;
- bufferList.SetSize(rowSizeInBytes);
- uint8_t* buffer = bufferList.Buffer();
-
- const int stride = m_rowStrideInBytes;
-
- const int num = m_height >> 1;
- for (int i = 0; i < num; ++i, top += stride, bottom -= stride)
- {
- ::memcpy(buffer, top, rowSizeInBytes);
- ::memcpy(top, bottom, rowSizeInBytes);
- ::memcpy(bottom, buffer, rowSizeInBytes);
- }
-}
-
-SlangResult Surface::set(int width, int height, Format format, int srcRowStride, const void* data, SurfaceAllocator* allocator)
-{
- if (hasContents() && m_width == width && m_height == height && m_format == format)
- {
- // I can just overwrite the contents that is there
- }
- else
- {
- SLANG_RETURN_ON_FAIL(allocate(width, height, format, 0, allocator));
- }
-
- // Okay just need to set the contents
-
- {
- const size_t rowSize = calcRowSize(format, width);
-
- const uint8_t* srcRow = (const uint8_t*)data;
- uint8_t* dstRow = (uint8_t*)m_data;
-
- for (int i = 0; i < m_numRows; i++)
- {
- ::memcpy(dstRow, srcRow, rowSize);
-
- srcRow += srcRowStride;
- dstRow += m_rowStrideInBytes;
- }
- }
-
- return SLANG_OK;
-}
-
-} // renderer_test