summaryrefslogtreecommitdiff
path: root/tools/gfx/render-gl.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-09-13 15:59:15 -0400
committerGitHub <noreply@github.com>2019-09-13 15:59:15 -0400
commitc2e5d2468ad6a38cdb8a067da0678302f6cc6066 (patch)
tree97c448d28e54068d84c422e9f172996b7a95f1ed /tools/gfx/render-gl.cpp
parent0b6321b3f08c48e37e6b8256d420f05d9727fb5a (diff)
Refactor render-test to make cross platform (#1053)
* First pass of render-test refactor. * Make window construction a function that can choose an implementation. * Remove OpenGL as currently has windows dependency. * Disable Vulkan as Renderer impl has dependency on windows. * Pass Window in as parameter of 'update'. * Add win-window.cpp as was missing. * Fix warning on windows about signs during comparison.
Diffstat (limited to 'tools/gfx/render-gl.cpp')
-rw-r--r--tools/gfx/render-gl.cpp1504
1 files changed, 0 insertions, 1504 deletions
diff --git a/tools/gfx/render-gl.cpp b/tools/gfx/render-gl.cpp
deleted file mode 100644
index 975b4e140..000000000
--- a/tools/gfx/render-gl.cpp
+++ /dev/null
@@ -1,1504 +0,0 @@
-// render-gl.cpp
-#include "render-gl.h"
-
-//WORKING:#include "options.h"
-#include "render.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "core/slang-basic.h"
-#include "core/slang-secure-crt.h"
-#include "external/stb/stb_image_write.h"
-
-#include "surface.h"
-
-// TODO(tfoley): eventually we should be able to run these
-// tests on non-Windows targets to confirm that cross-compilation
-// at least *works* on those platforms...
-#define WIN32_LEAN_AND_MEAN
-#define NOMINMAX
-#include <Windows.h>
-#undef WIN32_LEAN_AND_MEAN
-#undef NOMINMAX
-
-#ifdef _MSC_VER
-#include <stddef.h>
-#if (_MSC_VER < 1900)
-#define snprintf sprintf_s
-#endif
-#endif
-
-#pragma comment(lib, "opengl32")
-
-#include <GL/GL.h>
-#include "external/glext.h"
-
-// We define an "X-macro" for mapping over loadable OpenGL
-// extension entry point that we will use, so that we can
-// easily write generic code to iterate over them.
-#define MAP_GL_EXTENSION_FUNCS(F) \
- F(glCreateProgram, PFNGLCREATEPROGRAMPROC) \
- F(glCreateShader, PFNGLCREATESHADERPROC) \
- F(glShaderSource, PFNGLSHADERSOURCEPROC) \
- F(glCompileShader, PFNGLCOMPILESHADERPROC) \
- F(glGetShaderiv, PFNGLGETSHADERIVPROC) \
- F(glDeleteShader, PFNGLDELETESHADERPROC) \
- F(glAttachShader, PFNGLATTACHSHADERPROC) \
- F(glLinkProgram, PFNGLLINKPROGRAMPROC) \
- F(glGetProgramiv, PFNGLGETPROGRAMIVPROC) \
- F(glGetProgramInfoLog, PFNGLGETPROGRAMINFOLOGPROC) \
- F(glDeleteProgram, PFNGLDELETEPROGRAMPROC) \
- F(glGetShaderInfoLog, PFNGLGETSHADERINFOLOGPROC) \
- F(glGenBuffers, PFNGLGENBUFFERSPROC) \
- F(glBindBuffer, PFNGLBINDBUFFERPROC) \
- F(glBufferData, PFNGLBUFFERDATAPROC) \
- F(glDeleteBuffers, PFNGLDELETEBUFFERSPROC) \
- F(glMapBuffer, PFNGLMAPBUFFERPROC) \
- F(glUnmapBuffer, PFNGLUNMAPBUFFERPROC) \
- F(glUseProgram, PFNGLUSEPROGRAMPROC) \
- F(glBindBufferBase, PFNGLBINDBUFFERBASEPROC) \
- F(glVertexAttribPointer, PFNGLVERTEXATTRIBPOINTERPROC) \
- F(glEnableVertexAttribArray, PFNGLENABLEVERTEXATTRIBARRAYPROC) \
- F(glDisableVertexAttribArray, PFNGLDISABLEVERTEXATTRIBARRAYPROC) \
- F(glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) \
- F(glDispatchCompute, PFNGLDISPATCHCOMPUTEPROC) \
- F(glActiveTexture, PFNGLACTIVETEXTUREPROC) \
- F(glCreateSamplers, PFNGLCREATESAMPLERSPROC) \
- F(glDeleteSamplers, PFNGLDELETESAMPLERSPROC) \
- F(glBindSampler, PFNGLBINDSAMPLERPROC) \
- F(glTexImage3D, PFNGLTEXIMAGE3DPROC) \
- F(glSamplerParameteri, PFNGLSAMPLERPARAMETERIPROC) \
- /* end */
-
-using namespace Slang;
-
-namespace gfx {
-
-class GLRenderer : public Renderer
-{
-public:
-
- // Renderer implementation
- virtual SlangResult initialize(const Desc& desc, void* inWindowHandle) override;
- virtual const List<String>& getFeatures() override { return m_features; }
- virtual void setClearColor(const float color[4]) override;
- virtual void clearFrame() override;
- virtual void presentFrame() override;
- TextureResource::Desc getSwapChainTextureDesc() override;
-
- Result createTextureResource(Resource::Usage initialUsage, const TextureResource::Desc& desc, const TextureResource::Data* initData, TextureResource** outResource) override;
- Result createBufferResource(Resource::Usage initialUsage, const BufferResource::Desc& desc, const void* initData, BufferResource** outResource) override;
- Result createSamplerState(SamplerState::Desc const& desc, SamplerState** outSampler) override;
-
- Result createTextureView(TextureResource* texture, ResourceView::Desc const& desc, ResourceView** outView) override;
- Result createBufferView(BufferResource* buffer, ResourceView::Desc const& desc, ResourceView** outView) override;
-
- Result createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount, InputLayout** outLayout) override;
-
- Result createDescriptorSetLayout(const DescriptorSetLayout::Desc& desc, DescriptorSetLayout** outLayout) override;
- Result createPipelineLayout(const PipelineLayout::Desc& desc, PipelineLayout** outLayout) override;
- Result createDescriptorSet(DescriptorSetLayout* layout, DescriptorSet** outDescriptorSet) override;
-
- Result createProgram(const ShaderProgram::Desc& desc, ShaderProgram** outProgram) override;
- Result createGraphicsPipelineState(const GraphicsPipelineStateDesc& desc, PipelineState** outState) override;
- Result createComputePipelineState(const ComputePipelineStateDesc& desc, PipelineState** outState) override;
-
- virtual SlangResult captureScreenSurface(Surface& surfaceOut) override;
-
- virtual void* map(BufferResource* buffer, MapFlavor flavor) override;
- virtual void unmap(BufferResource* buffer) override;
- virtual void setPrimitiveTopology(PrimitiveTopology topology) override;
-
- virtual void setDescriptorSet(PipelineType pipelineType, PipelineLayout* layout, UInt index, DescriptorSet* descriptorSet) override;
-
- virtual void setVertexBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* strides, const UInt* offsets) override;
- virtual void setIndexBuffer(BufferResource* buffer, Format indexFormat, UInt offset) override;
- virtual void setDepthStencilTarget(ResourceView* depthStencilView) override;
- void setViewports(UInt count, Viewport const* viewports) override;
- void setScissorRects(UInt count, ScissorRect const* rects) override;
- virtual void setPipelineState(PipelineType pipelineType, PipelineState* state) override;
- virtual void draw(UInt vertexCount, UInt startVertex) override;
- virtual void drawIndexed(UInt indexCount, UInt startIndex, UInt baseVertex) override;
- virtual void dispatchCompute(int x, int y, int z) override;
- virtual void submitGpuWork() override {}
- virtual void waitForGpu() override {}
- virtual RendererType getRendererType() const override { return RendererType::OpenGl; }
-
- GLRenderer();
- ~GLRenderer();
-
- protected:
- enum
- {
- kMaxVertexStreams = 16,
- kMaxDescriptorSetCount = 8,
- };
- struct VertexAttributeFormat
- {
- GLint componentCount;
- GLenum componentType;
- GLboolean normalized;
- };
-
- struct VertexAttributeDesc
- {
- VertexAttributeFormat format;
- GLuint streamIndex;
- GLsizei offset;
- };
-
- class InputLayoutImpl: public InputLayout
- {
- public:
- VertexAttributeDesc m_attributes[kMaxVertexStreams];
- UInt m_attributeCount = 0;
- };
-
- class BufferResourceImpl: public BufferResource
- {
- public:
- typedef BufferResource Parent;
-
- BufferResourceImpl(Usage initialUsage, const Desc& desc, WeakSink<GLRenderer>* renderer, GLuint id, GLenum target):
- Parent(desc),
- m_renderer(renderer),
- m_handle(id),
- m_initialUsage(initialUsage),
- m_target(target)
- {}
- ~BufferResourceImpl()
- {
- if (auto renderer = m_renderer->get())
- {
- renderer->glDeleteBuffers(1, &m_handle);
- }
- }
-
- Usage m_initialUsage;
- RefPtr<WeakSink<GLRenderer> > m_renderer;
- GLuint m_handle;
- GLenum m_target;
- };
-
- class TextureResourceImpl: public TextureResource
- {
- public:
- typedef TextureResource Parent;
-
- TextureResourceImpl(Usage initialUsage, const Desc& desc, WeakSink<GLRenderer>* renderer):
- Parent(desc),
- m_initialUsage(initialUsage),
- m_renderer(renderer)
- {
- m_target = 0;
- m_handle = 0;
- }
-
- ~TextureResourceImpl()
- {
- if (m_handle)
- {
- glDeleteTextures(1, &m_handle);
- }
- }
-
- Usage m_initialUsage;
- RefPtr<WeakSink<GLRenderer> > m_renderer;
- GLenum m_target;
- GLuint m_handle;
- };
-
- class SamplerStateImpl : public SamplerState
- {
- public:
- GLuint m_samplerID;
- };
-
- class ResourceViewImpl : public ResourceView
- {
- };
-
- class TextureViewImpl : public ResourceViewImpl
- {
- public:
- RefPtr<TextureResourceImpl> m_resource;
- GLuint m_textureID;
- };
-
- class BufferViewImpl : public ResourceViewImpl
- {
- public:
- RefPtr<BufferResourceImpl> m_resource;
- GLuint m_bufferID;
- };
-
- enum class GLDescriptorSlotType
- {
- ConstantBuffer,
- CombinedTextureSampler,
-
- CountOf,
- };
-
- class DescriptorSetLayoutImpl : public DescriptorSetLayout
- {
- public:
- struct RangeInfo
- {
- GLDescriptorSlotType type;
- UInt arrayIndex;
- };
- List<RangeInfo> m_ranges;
- Int m_counts[int(GLDescriptorSlotType::CountOf)];
- };
-
- class PipelineLayoutImpl : public PipelineLayout
- {
- public:
- struct DescriptorSetInfo
- {
- RefPtr<DescriptorSetLayoutImpl> layout;
- UInt baseArrayIndex[int(GLDescriptorSlotType::CountOf)];
- };
-
- List<DescriptorSetInfo> m_sets;
- };
-
- class DescriptorSetImpl : public DescriptorSet
- {
- public:
- virtual void setConstantBuffer(UInt range, UInt index, BufferResource* buffer) override;
- virtual void setResource(UInt range, UInt index, ResourceView* view) override;
- virtual void setSampler(UInt range, UInt index, SamplerState* sampler) override;
- virtual void setCombinedTextureSampler(
- UInt range,
- UInt index,
- ResourceView* textureView,
- SamplerState* sampler) override;
-
- RefPtr<DescriptorSetLayoutImpl> m_layout;
- List<RefPtr<BufferResourceImpl>> m_constantBuffers;
- List<RefPtr<TextureViewImpl>> m_textures;
- List<RefPtr<SamplerStateImpl>> m_samplers;
- };
-
- class ShaderProgramImpl : public ShaderProgram
- {
- public:
- ShaderProgramImpl(WeakSink<GLRenderer>* renderer, GLuint id):
- m_renderer(renderer),
- m_id(id)
- {
- }
- ~ShaderProgramImpl()
- {
- if (auto renderer = m_renderer->get())
- {
- renderer->glDeleteProgram(m_id);
- }
- }
-
- GLuint m_id;
- RefPtr<WeakSink<GLRenderer> > m_renderer;
- };
-
- class PipelineStateImpl : public PipelineState
- {
- public:
- RefPtr<ShaderProgramImpl> m_program;
- RefPtr<PipelineLayoutImpl> m_pipelineLayout;
- RefPtr<InputLayoutImpl> m_inputLayout;
- };
-
- enum class GlPixelFormat
- {
- Unknown,
- RGBA_Unorm_UInt8,
- CountOf,
- };
-
- struct GlPixelFormatInfo
- {
- GLint internalFormat; // such as GL_RGBA8
- GLenum format; // such as GL_RGBA
- GLenum formatType; // such as GL_UNSIGNED_BYTE
- };
-
-// void destroyBindingEntries(const BindingState::Desc& desc, const BindingDetail* details);
-
- void bindBufferImpl(int target, UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* offsets);
- void flushStateForDraw();
- GLuint loadShader(GLenum stage, char const* source);
- void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message);
-
- /// Returns GlPixelFormat::Unknown if not an equivalent
- static GlPixelFormat _getGlPixelFormat(Format format);
-
- static void APIENTRY staticDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam);
- static VertexAttributeFormat getVertexAttributeFormat(Format format);
-
- static void compileTimeAsserts();
-
- HDC m_hdc;
- HGLRC m_glContext;
- float m_clearColor[4] = { 0, 0, 0, 0 };
-
- RefPtr<PipelineStateImpl> m_currentPipelineState;
- RefPtr<WeakSink<GLRenderer> > m_weakRenderer;
-
- RefPtr<DescriptorSetImpl> m_boundDescriptorSets[kMaxDescriptorSetCount];
-
- GLenum m_boundPrimitiveTopology = GL_TRIANGLES;
- GLuint m_boundVertexStreamBuffers[kMaxVertexStreams];
- UInt m_boundVertexStreamStrides[kMaxVertexStreams];
- UInt m_boundVertexStreamOffsets[kMaxVertexStreams];
-
- Desc m_desc;
-
- List<String> m_features;
-
- // Declare a function pointer for each OpenGL
- // extension function we need to load
-#define DECLARE_GL_EXTENSION_FUNC(NAME, TYPE) TYPE NAME;
- MAP_GL_EXTENSION_FUNCS(DECLARE_GL_EXTENSION_FUNC)
-#undef DECLARE_GL_EXTENSION_FUNC
-
- static const GlPixelFormatInfo s_pixelFormatInfos[]; /// Maps GlPixelFormat to a format info
-};
-
-/* static */GLRenderer::GlPixelFormat GLRenderer::_getGlPixelFormat(Format format)
-{
- switch (format)
- {
- case Format::RGBA_Unorm_UInt8: return GlPixelFormat::RGBA_Unorm_UInt8;
- default: return GlPixelFormat::Unknown;
- }
-}
-
-/* static */ const GLRenderer::GlPixelFormatInfo GLRenderer::s_pixelFormatInfos[] =
-{
- // internalType, format, formatType
- { 0, 0, 0}, // GlPixelFormat::Unknown
- { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE }, // GlPixelFormat::RGBA_Unorm_UInt8
-};
-
-/* static */void GLRenderer::compileTimeAsserts()
-{
- SLANG_COMPILE_TIME_ASSERT(SLANG_COUNT_OF(s_pixelFormatInfos) == int(GlPixelFormat::CountOf));
-}
-
-Renderer* createGLRenderer()
-{
- return new GLRenderer();
-}
-
-void GLRenderer::debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message)
-{
- ::OutputDebugStringA("GL: ");
- ::OutputDebugStringA(message);
- ::OutputDebugStringA("\n");
-
- switch (type)
- {
- case GL_DEBUG_TYPE_ERROR:
- break;
- default:
- break;
- }
-}
-
-
-GLRenderer::GLRenderer()
-{
- m_weakRenderer = new WeakSink<GLRenderer>(this);
-}
-
-GLRenderer::~GLRenderer()
-{
- // We can destroy things whilst in this state
- m_currentPipelineState.setNull();
-
- // By resetting the weak pointer, other objects accessing through WeakSink<GLRenderer> will no longer
- // be able to access this object which is entering a 'being destroyed' to 'destroyed' state
- if (m_weakRenderer)
- {
- SLANG_ASSERT(m_weakRenderer->get() == this);
- m_weakRenderer->detach();
- }
-}
-
-/* static */void APIENTRY GLRenderer::staticDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
-{
- ((GLRenderer*)userParam)->debugCallback(source, type, id, severity, length, message);
-}
-
-/* static */GLRenderer::VertexAttributeFormat GLRenderer::getVertexAttributeFormat(Format format)
-{
- switch (format)
- {
- default: assert(!"unexpected"); return VertexAttributeFormat();
-
-#define CASE(NAME, COUNT, TYPE, NORMALIZED) \
- case Format::NAME: do { VertexAttributeFormat result = {COUNT, TYPE, NORMALIZED}; return result; } while (0)
-
- CASE(RGBA_Float32, 4, GL_FLOAT, GL_FALSE);
- CASE(RGB_Float32, 3, GL_FLOAT, GL_FALSE);
- CASE(RG_Float32, 2, GL_FLOAT, GL_FALSE);
- CASE(R_Float32, 1, GL_FLOAT, GL_FALSE);
-#undef CASE
- }
-}
-
-void GLRenderer::bindBufferImpl(int target, UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* offsets)
-{
- for (UInt ii = 0; ii < slotCount; ++ii)
- {
- UInt slot = startSlot + ii;
-
- BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(buffers[ii]);
- GLuint bufferID = buffer ? buffer->m_handle : 0;
-
- assert(!offsets || !offsets[ii]);
-
- glBindBufferBase(target, (GLuint)slot, bufferID);
- }
-}
-
-void GLRenderer::flushStateForDraw()
-{
- auto inputLayout = m_currentPipelineState->m_inputLayout.Ptr();
- auto attrCount = Index(inputLayout->m_attributeCount);
- for (Index ii = 0; ii < attrCount; ++ii)
- {
- auto& attr = inputLayout->m_attributes[ii];
-
- auto streamIndex = attr.streamIndex;
-
- glBindBuffer(GL_ARRAY_BUFFER, m_boundVertexStreamBuffers[streamIndex]);
-
- glVertexAttribPointer(
- (GLuint)ii,
- attr.format.componentCount,
- attr.format.componentType,
- attr.format.normalized,
- (GLsizei)m_boundVertexStreamStrides[streamIndex],
- (GLvoid*)(attr.offset + m_boundVertexStreamOffsets[streamIndex]));
-
- glEnableVertexAttribArray((GLuint)ii);
- }
- for (Index ii = attrCount; ii < kMaxVertexStreams; ++ii)
- {
- glDisableVertexAttribArray((GLuint)ii);
- }
-
- // Next bind the descriptor sets as required by the layout
- auto pipelineLayout = m_currentPipelineState->m_pipelineLayout;
- auto descriptorSetCount = pipelineLayout->m_sets.getCount();
- for(Index ii = 0; ii < descriptorSetCount; ++ii)
- {
- auto descriptorSet = m_boundDescriptorSets[ii];
- auto descriptorSetInfo = pipelineLayout->m_sets[ii];
- auto descriptorSetLayout = descriptorSetInfo.layout;
-
- // TODO: need to validate that `descriptorSet->m_layout` matches
- // `descriptorSetLayout`.
-
- {
- // First we will bind any uniform buffers that were specified.
-
- auto slotTypeIndex = int(GLDescriptorSlotType::ConstantBuffer);
- auto count = descriptorSetLayout->m_counts[slotTypeIndex];
- auto baseIndex = descriptorSetInfo.baseArrayIndex[slotTypeIndex];
-
- for(Int ii = 0; ii < count; ++ii)
- {
- auto bufferImpl = descriptorSet->m_constantBuffers[ii];
- glBindBufferBase(GL_UNIFORM_BUFFER, GLuint(ii), bufferImpl->m_handle);
- }
- }
-
-
- {
- // Next we will bind any combined texture/sampler slots.
-
- auto slotTypeIndex = int(GLDescriptorSlotType::CombinedTextureSampler);
- auto count = descriptorSetLayout->m_counts[slotTypeIndex];
- auto baseIndex = descriptorSetInfo.baseArrayIndex[slotTypeIndex];
-
- // TODO: We should be able to use a single call to glBindTextures here,
- // rather than a loop. This would also eliminate the need to retain
- // the appropriate target (e.g., `GL_TEXTURE_2D` for binding).
-
- for(Int ii = 0; ii < count; ++ii)
- {
- auto textureViewImpl = descriptorSet->m_textures[ii];
- auto samplerImpl = descriptorSet->m_samplers[ii];
-
- glActiveTexture(GLuint(GL_TEXTURE0 + ii));
- glBindTexture(GL_TEXTURE_2D, textureViewImpl->m_textureID);
-
- glBindSampler(GLuint(baseIndex + ii), samplerImpl->m_samplerID);
- }
- }
- }
-}
-
-GLuint GLRenderer::loadShader(GLenum stage, const char* source)
-{
- // GLSL is monumentally stupid. It officially requires the `#version` directive
- // to be the first thing in the file, which wouldn't be so bad but the API
- // doesn't provide a way to pass a `#define` into your shader other than by
- // prepending it to the whole thing.
- //
- // We are going to solve this problem by doing some surgery on the source
- // that was passed in.
-
- const char* sourceBegin = source;
- const char* sourceEnd = source + strlen(source);
-
- // Look for a version directive in the user-provided source.
- const char* versionBegin = strstr(source, "#version");
- const char* versionEnd = nullptr;
- if (versionBegin)
- {
- // If we found a directive, then scan for the end-of-line
- // after it, and use that to specify the slice.
- versionEnd = strchr(versionBegin, '\n');
- if (!versionEnd)
- {
- versionEnd = sourceEnd;
- }
- else
- {
- versionEnd = versionEnd + 1;
- }
- }
- else
- {
- // If we didn't find a directive, then treat it as being
- // a zero-byte slice at the start of the string
- versionBegin = sourceBegin;
- versionEnd = sourceBegin;
- }
-
- enum { kMaxSourceStringCount = 16 };
- const GLchar* sourceStrings[kMaxSourceStringCount];
- GLint sourceStringLengths[kMaxSourceStringCount];
-
- int sourceStringCount = 0;
-
- const char* stagePrelude = "\n";
- switch (stage)
- {
-#define CASE(NAME) case GL_##NAME##_SHADER: stagePrelude = "#define __GLSL_" #NAME "__ 1\n"; break
-
- CASE(VERTEX);
- CASE(TESS_CONTROL);
- CASE(TESS_EVALUATION);
- CASE(GEOMETRY);
- CASE(FRAGMENT);
- CASE(COMPUTE);
-
-#undef CASE
- }
-
- const char* prelude =
- "#define __GLSL__ 1\n"
- ;
-
-#define ADD_SOURCE_STRING_SPAN(BEGIN, END) \
- sourceStrings[sourceStringCount] = BEGIN; \
- sourceStringLengths[sourceStringCount++] = GLint(END - BEGIN) \
- /* end */
-
-#define ADD_SOURCE_STRING(BEGIN) \
- sourceStrings[sourceStringCount] = BEGIN; \
- sourceStringLengths[sourceStringCount++] = GLint(strlen(BEGIN)) \
- /* end */
-
- ADD_SOURCE_STRING_SPAN(versionBegin, versionEnd);
- ADD_SOURCE_STRING(stagePrelude);
- ADD_SOURCE_STRING(prelude);
- ADD_SOURCE_STRING_SPAN(sourceBegin, versionBegin);
- ADD_SOURCE_STRING_SPAN(versionEnd, sourceEnd);
-
- auto shaderID = glCreateShader(stage);
- glShaderSource(
- shaderID,
- sourceStringCount,
- &sourceStrings[0],
- &sourceStringLengths[0]);
- glCompileShader(shaderID);
-
- GLint success = GL_FALSE;
- glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
- if (!success)
- {
- int maxSize = 0;
- glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &maxSize);
-
- auto infoBuffer = (char*)malloc(maxSize);
-
- int infoSize = 0;
- glGetShaderInfoLog(shaderID, maxSize, &infoSize, infoBuffer);
- if (infoSize > 0)
- {
- fprintf(stderr, "%s", infoBuffer);
- ::OutputDebugStringA(infoBuffer);
- }
-
- glDeleteShader(shaderID);
- return 0;
- }
-
- return shaderID;
-}
-
-#if 0
-void GLRenderer::destroyBindingEntries(const BindingState::Desc& desc, const BindingDetail* details)
-{
- const auto& bindings = desc.m_bindings;
- const int numBindings = int(bindings.Count());
- for (int i = 0; i < numBindings; ++i)
- {
- const auto& binding = bindings[i];
- const auto& detail = details[i];
-
- if (binding.bindingType == BindingType::Sampler && detail.m_samplerHandle != 0)
- {
- glDeleteSamplers(1, &detail.m_samplerHandle);
- }
- }
-}
-#endif
-
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!! Renderer interface !!!!!!!!!!!!!!!!!!!!!!!!!!
-
-SlangResult GLRenderer::initialize(const Desc& desc, void* inWindowHandle)
-{
- auto windowHandle = (HWND)inWindowHandle;
- m_desc = desc;
-
- m_hdc = ::GetDC(windowHandle);
-
- PIXELFORMATDESCRIPTOR pixelFormatDesc = { sizeof(PIXELFORMATDESCRIPTOR) };
- pixelFormatDesc.nVersion = 1;
- pixelFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
- pixelFormatDesc.iPixelType = PFD_TYPE_RGBA;
- pixelFormatDesc.cColorBits = 32;
- pixelFormatDesc.cDepthBits = 24;
- pixelFormatDesc.cStencilBits = 8;
- pixelFormatDesc.iLayerType = PFD_MAIN_PLANE;
-
- int pixelFormatIndex = ChoosePixelFormat(m_hdc, &pixelFormatDesc);
- SetPixelFormat(m_hdc, pixelFormatIndex, &pixelFormatDesc);
-
- m_glContext = wglCreateContext(m_hdc);
- wglMakeCurrent(m_hdc, m_glContext);
-
- auto renderer = glGetString(GL_RENDERER);
-
- if (renderer && desc.adapter.getLength() > 0)
- {
- String lowerAdapter = desc.adapter.toLower();
- String lowerRenderer = String((const char*)renderer).toLower();
-
- // The adapter is not available
- if (lowerRenderer.indexOf(lowerAdapter) == Index(-1))
- {
- return SLANG_E_NOT_AVAILABLE;
- }
- }
-
- auto extensions = glGetString(GL_EXTENSIONS);
-
- // Load each of our extension functions by name
-
-#define LOAD_GL_EXTENSION_FUNC(NAME, TYPE) NAME = (TYPE) wglGetProcAddress(#NAME);
- MAP_GL_EXTENSION_FUNCS(LOAD_GL_EXTENSION_FUNC)
-#undef LOAD_GL_EXTENSION_FUNC
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
-
- glViewport(0, 0, desc.width, desc.height);
-
- if (glDebugMessageCallback)
- {
- glEnable(GL_DEBUG_OUTPUT);
- glDebugMessageCallback(staticDebugCallback, this);
- }
-
- return SLANG_OK;
-}
-
-void GLRenderer::setClearColor(const float color[4])
-{
- glClearColor(color[0], color[1], color[2], color[3]);
-}
-
-void GLRenderer::clearFrame()
-{
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-}
-
-void GLRenderer::presentFrame()
-{
- glFlush();
- ::SwapBuffers(m_hdc);
-}
-
-TextureResource::Desc GLRenderer::getSwapChainTextureDesc()
-{
- TextureResource::Desc desc;
- desc.init2D(Resource::Type::Texture2D, Format::Unknown, m_desc.width, m_desc.height, 1);
- return desc;
-}
-
-SlangResult GLRenderer::captureScreenSurface(Surface& surfaceOut)
-{
- SLANG_RETURN_ON_FAIL(surfaceOut.allocate(m_desc.width, m_desc.height, Format::RGBA_Unorm_UInt8, 1, SurfaceAllocator::getMallocAllocator()));
- glReadPixels(0, 0, m_desc.width, m_desc.height, GL_RGBA, GL_UNSIGNED_BYTE, surfaceOut.m_data);
- surfaceOut.flipInplaceVertically();
- return SLANG_OK;
-}
-
-Result GLRenderer::createTextureResource(Resource::Usage initialUsage, const TextureResource::Desc& descIn, const TextureResource::Data* initData, TextureResource** outResource)
-{
- TextureResource::Desc srcDesc(descIn);
- srcDesc.setDefaults(initialUsage);
-
- GlPixelFormat pixelFormat = _getGlPixelFormat(srcDesc.format);
- if (pixelFormat == GlPixelFormat::Unknown)
- {
- return SLANG_FAIL;
- }
-
- const GlPixelFormatInfo& info = s_pixelFormatInfos[int(pixelFormat)];
-
- const GLint internalFormat = info.internalFormat;
- const GLenum format = info.format;
- const GLenum formatType = info.formatType;
-
- RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(initialUsage, srcDesc, m_weakRenderer));
-
- GLenum target = 0;
- GLuint handle = 0;
- glGenTextures(1, &handle);
-
- const int effectiveArraySize = srcDesc.calcEffectiveArraySize();
-
- assert(initData);
- assert(initData->numSubResources == srcDesc.numMipLevels * srcDesc.size.depth * effectiveArraySize);
-
- // Set on texture so will be freed if failure
- texture->m_handle = handle;
- const void*const*const data = initData->subResources;
-
- switch (srcDesc.type)
- {
- case Resource::Type::Texture1D:
- {
- if (srcDesc.arraySize > 0)
- {
- target = GL_TEXTURE_1D_ARRAY;
- glBindTexture(target, handle);
-
- int slice = 0;
- for (int i = 0; i < effectiveArraySize; i++)
- {
- for (int j = 0; j < srcDesc.numMipLevels; j++)
- {
- glTexImage2D(target, j, internalFormat, srcDesc.size.width, i, 0, format, formatType, data[slice++]);
- }
- }
- }
- else
- {
- target = GL_TEXTURE_1D;
- glBindTexture(target, handle);
- for (int i = 0; i < srcDesc.numMipLevels; i++)
- {
- glTexImage1D(target, i, internalFormat, srcDesc.size.width, 0, format, formatType, data[i]);
- }
- }
- break;
- }
- case Resource::Type::TextureCube:
- case Resource::Type::Texture2D:
- {
- if (srcDesc.arraySize > 0)
- {
- if (srcDesc.type == Resource::Type::TextureCube)
- {
- target = GL_TEXTURE_CUBE_MAP_ARRAY;
- }
- else
- {
- target = GL_TEXTURE_2D_ARRAY;
- }
-
- glBindTexture(target, handle);
-
- int slice = 0;
- for (int i = 0; i < effectiveArraySize; i++)
- {
- for (int j = 0; j < srcDesc.numMipLevels; j++)
- {
- glTexImage3D(target, j, internalFormat, srcDesc.size.width, srcDesc.size.height, slice, 0, format, formatType, data[slice++]);
- }
- }
- }
- else
- {
- if (srcDesc.type == Resource::Type::TextureCube)
- {
- target = GL_TEXTURE_CUBE_MAP;
- glBindTexture(target, handle);
-
- int slice = 0;
- for (int j = 0; j < 6; j++)
- {
- for (int i = 0; i < srcDesc.numMipLevels; i++)
- {
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i, internalFormat, srcDesc.size.width, srcDesc.size.height, 0, format, formatType, data[slice++]);
- }
- }
- }
- else
- {
- target = GL_TEXTURE_2D;
- glBindTexture(target, handle);
- for (int i = 0; i < srcDesc.numMipLevels; i++)
- {
- glTexImage2D(target, i, internalFormat, srcDesc.size.width, srcDesc.size.height, 0, format, formatType, data[i]);
- }
- }
- }
- break;
- }
- case Resource::Type::Texture3D:
- {
- target = GL_TEXTURE_3D;
- glBindTexture(target, handle);
- for (int i = 0; i < srcDesc.numMipLevels; i++)
- {
- glTexImage3D(target, i, internalFormat, srcDesc.size.width, srcDesc.size.height, srcDesc.size.depth, 0, format, formatType, data[i]);
- }
- break;
- }
- default:
- return SLANG_FAIL;
- }
-
- glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
-
- // Assume regular sampling (might be superseded - if a combined sampler wanted)
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8.0f);
-
- texture->m_target = target;
-
- *outResource = texture.detach();
- return SLANG_OK;
-}
-
-static GLenum _calcUsage(Resource::Usage usage)
-{
- typedef Resource::Usage Usage;
- switch (usage)
- {
- case Usage::ConstantBuffer: return GL_DYNAMIC_DRAW;
- default: return GL_STATIC_READ;
- }
-}
-
-static GLenum _calcTarget(Resource::Usage usage)
-{
- typedef Resource::Usage Usage;
- switch (usage)
- {
- case Usage::ConstantBuffer: return GL_UNIFORM_BUFFER;
- default: return GL_SHADER_STORAGE_BUFFER;
- }
-}
-
-Result GLRenderer::createBufferResource(Resource::Usage initialUsage, const BufferResource::Desc& descIn, const void* initData, BufferResource** outResource)
-{
- BufferResource::Desc desc(descIn);
- desc.setDefaults(initialUsage);
-
- const GLenum target = _calcTarget(initialUsage);
- // TODO: should derive from desc...
- const GLenum usage = _calcUsage(initialUsage);
-
- GLuint bufferID = 0;
- glGenBuffers(1, &bufferID);
- glBindBuffer(target, bufferID);
-
- glBufferData(target, descIn.sizeInBytes, initData, usage);
-
- RefPtr<BufferResourceImpl> resourceImpl = new BufferResourceImpl(initialUsage, desc, m_weakRenderer, bufferID, target);
- *outResource = resourceImpl.detach();
- return SLANG_OK;
-}
-
-Result GLRenderer::createSamplerState(SamplerState::Desc const& desc, SamplerState** outSampler)
-{
- GLuint samplerID;
- glCreateSamplers(1, &samplerID);
-
- RefPtr<SamplerStateImpl> samplerImpl = new SamplerStateImpl();
- samplerImpl->m_samplerID = samplerID;
- *outSampler = samplerImpl.detach();
- return SLANG_OK;
-}
-
-Result GLRenderer::createTextureView(TextureResource* texture, ResourceView::Desc const& desc, ResourceView** outView)
-{
- auto resourceImpl = (TextureResourceImpl*) texture;
-
- // TODO: actually do something?
-
- RefPtr<TextureViewImpl> viewImpl = new TextureViewImpl();
- viewImpl->m_resource = resourceImpl;
- viewImpl->m_textureID = resourceImpl->m_handle;
- *outView = viewImpl;
- return SLANG_OK;
-}
-
-Result GLRenderer::createBufferView(BufferResource* buffer, ResourceView::Desc const& desc, ResourceView** outView)
-{
- auto resourceImpl = (BufferResourceImpl*) buffer;
-
- // TODO: actually do something?
-
- RefPtr<BufferViewImpl> viewImpl = new BufferViewImpl();
- viewImpl->m_resource = resourceImpl;
- viewImpl->m_bufferID = resourceImpl->m_handle;
- *outView = viewImpl.detach();
- return SLANG_OK;
-}
-
-Result GLRenderer::createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount, InputLayout** outLayout)
-{
- RefPtr<InputLayoutImpl> inputLayout = new InputLayoutImpl;
-
- inputLayout->m_attributeCount = inputElementCount;
- for (UInt ii = 0; ii < inputElementCount; ++ii)
- {
- auto& inputAttr = inputElements[ii];
- auto& glAttr = inputLayout->m_attributes[ii];
-
- glAttr.streamIndex = 0;
- glAttr.format = getVertexAttributeFormat(inputAttr.format);
- glAttr.offset = (GLsizei)inputAttr.offset;
- }
-
- *outLayout = inputLayout.detach();
- return SLANG_OK;
-}
-
-void* GLRenderer::map(BufferResource* bufferIn, MapFlavor flavor)
-{
- BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(bufferIn);
-
- //GLenum target = GL_UNIFORM_BUFFER;
-
- GLuint access = 0;
- switch (flavor)
- {
- case MapFlavor::WriteDiscard:
- case MapFlavor::HostWrite:
- access = GL_WRITE_ONLY;
- break;
- case MapFlavor::HostRead:
- access = GL_READ_ONLY;
- break;
- }
-
- glBindBuffer(buffer->m_target, buffer->m_handle);
-
- return glMapBuffer(buffer->m_target, access);
-}
-
-void GLRenderer::unmap(BufferResource* bufferIn)
-{
- BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(bufferIn);
- glUnmapBuffer(buffer->m_target);
-}
-
-void GLRenderer::setPrimitiveTopology(PrimitiveTopology topology)
-{
- GLenum glTopology = 0;
- switch (topology)
- {
-#define CASE(NAME, VALUE) case PrimitiveTopology::NAME: glTopology = VALUE; break
-
- CASE(TriangleList, GL_TRIANGLES);
-
-#undef CASE
- }
- m_boundPrimitiveTopology = glTopology;
-}
-
-void GLRenderer::setVertexBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* strides, const UInt* offsets)
-{
- for (UInt ii = 0; ii < slotCount; ++ii)
- {
- UInt slot = startSlot + ii;
-
- BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(buffers[ii]);
- GLuint bufferID = buffer ? buffer->m_handle : 0;
-
- m_boundVertexStreamBuffers[slot] = bufferID;
- m_boundVertexStreamStrides[slot] = strides[ii];
- m_boundVertexStreamOffsets[slot] = offsets[ii];
- }
-}
-
-void GLRenderer::setIndexBuffer(BufferResource* buffer, Format indexFormat, UInt offset)
-{
-}
-
-void GLRenderer::setDepthStencilTarget(ResourceView* depthStencilView)
-{
-}
-
-void GLRenderer::setViewports(UInt count, Viewport const* viewports)
-{
- assert(count == 1);
- auto viewport = viewports[0];
- glViewport(
- (GLint) viewport.originX,
- (GLint) viewport.originY,
- (GLsizei) viewport.extentX,
- (GLsizei) viewport.extentY);
- glDepthRange(viewport.minZ, viewport.maxZ);
-}
-
-void GLRenderer::setScissorRects(UInt count, ScissorRect const* rects)
-{
- assert(count <= 1);
- if( count )
- {
- // TODO: this isn't goign to be quite right because of the
- // flipped coordinate system in GL.
- //
- // The best way around this is probably to *always* render
- // things internally into textures with "flipped" conventions,
- // and then only deal with the flipping as part of a final
- // "present" step that copies to the primary back-buffer.
- //
- auto rect = rects[0];
- glScissor(
- GLint(rect.minX),
- GLint(rect.minY),
- GLsizei(rect.maxX - rect.minX),
- GLsizei(rect.maxY - rect.minY));
-
- glEnable(GL_SCISSOR_TEST);
- }
- else
- {
- glDisable(GL_SCISSOR_TEST);
- }
-}
-
-void GLRenderer::setPipelineState(PipelineType pipelineType, PipelineState* state)
-{
- auto pipelineStateImpl = (PipelineStateImpl*) state;
-
- m_currentPipelineState = pipelineStateImpl;
-
- auto program = pipelineStateImpl->m_program;
- GLuint programID = program ? program->m_id : 0;
- glUseProgram(programID);
-}
-
-void GLRenderer::draw(UInt vertexCount, UInt startVertex = 0)
-{
- flushStateForDraw();
-
- glDrawArrays(m_boundPrimitiveTopology, (GLint)startVertex, (GLsizei)vertexCount);
-}
-
-void GLRenderer::drawIndexed(UInt indexCount, UInt startIndex, UInt baseVertex)
-{
- assert(!"unimplemented");
-}
-
-void GLRenderer::dispatchCompute(int x, int y, int z)
-{
- glDispatchCompute(x, y, z);
-}
-
-#if 0
-BindingState* GLRenderer::createBindingState(const BindingState::Desc& bindingStateDesc)
-{
- RefPtr<BindingStateImpl> bindingState(new BindingStateImpl(bindingStateDesc, this));
-
- const auto& srcBindings = bindingStateDesc.m_bindings;
- const int numBindings = int(srcBindings.Count());
-
- auto& dstDetails = bindingState->m_bindingDetails;
- dstDetails.SetSize(numBindings);
-
- for (int i = 0; i < numBindings; ++i)
- {
- auto& dstDetail = dstDetails[i];
- const auto& srcBinding = srcBindings[i];
-
-
- switch (srcBinding.bindingType)
- {
- case BindingType::Texture:
- case BindingType::Buffer:
- {
- break;
- }
- case BindingType::CombinedTextureSampler:
- {
- assert(srcBinding.resource && srcBinding.resource->isTexture());
- TextureResourceImpl* texture = static_cast<TextureResourceImpl*>(srcBinding.resource.Ptr());
- const BindingState::SamplerDesc& samplerDesc = bindingStateDesc.m_samplerDescs[srcBinding.descIndex];
-
- if (samplerDesc.isCompareSampler)
- {
- auto target = texture->m_target;
-
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
- glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
- }
- break;
- }
- case BindingType::Sampler:
- {
- const BindingState::SamplerDesc& samplerDesc = bindingStateDesc.m_samplerDescs[srcBinding.descIndex];
-
- GLuint handle;
-
- glCreateSamplers(1, &handle);
- glSamplerParameteri(handle, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glSamplerParameteri(handle, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glSamplerParameteri(handle, GL_TEXTURE_WRAP_R, GL_REPEAT);
-
- if (samplerDesc.isCompareSampler)
- {
- glSamplerParameteri(handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glSamplerParameteri(handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glSamplerParameteri(handle, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
- glSamplerParameteri(handle, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
- }
- else
- {
- glSamplerParameteri(handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glSamplerParameteri(handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glSamplerParameteri(handle, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);
- }
-
- dstDetail.m_samplerHandle = handle;
- break;
- }
- }
- }
-
- return bindingState.detach();
-}
-
-void GLRenderer::setBindingState(BindingState* stateIn)
-{
- BindingStateImpl* state = static_cast<BindingStateImpl*>(stateIn);
-
- const auto& bindingDesc = state->getDesc();
-
- const auto& details = state->m_bindingDetails;
- const auto& bindings = bindingDesc.m_bindings;
- const int numBindings = int(bindings.Count());
-
- for (int i = 0; i < numBindings; ++i)
- {
- const auto& binding = bindings[i];
- const auto& detail = details[i];
-
- switch (binding.bindingType)
- {
- case BindingType::Buffer:
- {
- const int bindingIndex = binding.registerRange.getSingleIndex();
-
- BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(binding.resource.Ptr());
- glBindBufferBase(buffer->m_target, bindingIndex, buffer->m_handle);
- break;
- }
- case BindingType::Sampler:
- {
- for (int index = binding.registerRange.index; index < binding.registerRange.index + binding.registerRange.size; ++index)
- {
- glBindSampler(index, detail.m_samplerHandle);
- }
- break;
- }
- case BindingType::Texture:
- case BindingType::CombinedTextureSampler:
- {
- BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(binding.resource.Ptr());
-
- const int bindingIndex = binding.registerRange.getSingleIndex();
-
- glActiveTexture(GL_TEXTURE0 + bindingIndex);
- glBindTexture(buffer->m_target, buffer->m_handle);
- break;
- }
- }
- }
-}
-#endif
-
-void GLRenderer::DescriptorSetImpl::setConstantBuffer(UInt range, UInt index, BufferResource* buffer)
-{
- auto resourceImpl = (BufferResourceImpl*) buffer;
-
- auto layout = m_layout;
- auto rangeInfo = layout->m_ranges[range];
- auto arrayIndex = rangeInfo.arrayIndex + index;
-
- m_constantBuffers[arrayIndex] = resourceImpl;
-}
-
-void GLRenderer::DescriptorSetImpl::setResource(UInt range, UInt index, ResourceView* view)
-{
- auto viewImpl = (ResourceViewImpl*) view;
-
- auto layout = m_layout;
- auto rangeInfo = layout->m_ranges[range];
- auto arrayIndex = rangeInfo.arrayIndex + index;
-
- assert(!"unimplemented");
-}
-
-void GLRenderer::DescriptorSetImpl::setSampler(UInt range, UInt index, SamplerState* sampler)
-{
- assert(!"unsupported");
-}
-
-void GLRenderer::DescriptorSetImpl::setCombinedTextureSampler(
- UInt range,
- UInt index,
- ResourceView* textureView,
- SamplerState* sampler)
-{
- auto viewImpl = (TextureViewImpl*) textureView;
- auto samplerImpl = (SamplerStateImpl*) sampler;
-
- auto layout = m_layout;
- auto rangeInfo = layout->m_ranges[range];
- auto arrayIndex = rangeInfo.arrayIndex + index;
-
- m_textures[arrayIndex] = viewImpl;
- m_samplers[arrayIndex] = samplerImpl;
-}
-
-void GLRenderer::setDescriptorSet(PipelineType pipelineType, PipelineLayout* layout, UInt index, DescriptorSet* descriptorSet)
-{
- auto descriptorSetImpl = (DescriptorSetImpl*)descriptorSet;
-
- // TODO: can we just bind things immediately here, rather than shadowing the state?
-
- m_boundDescriptorSets[index] = descriptorSetImpl;
-}
-
-Result GLRenderer::createDescriptorSetLayout(const DescriptorSetLayout::Desc& desc, DescriptorSetLayout** outLayout)
-{
- RefPtr<DescriptorSetLayoutImpl> layoutImpl = new DescriptorSetLayoutImpl();
-
- Int counts[int(GLDescriptorSlotType::CountOf)] = { 0, };
-
- Int rangeCount = desc.slotRangeCount;
- for(Int rr = 0; rr < rangeCount; ++rr)
- {
- auto rangeDesc = desc.slotRanges[rr];
- DescriptorSetLayoutImpl::RangeInfo rangeInfo;
-
- GLDescriptorSlotType glSlotType;
- switch( rangeDesc.type )
- {
- default:
- assert(!"unsupported");
- break;
-
- // TODO: There are many other slot types we could support here,
- // in particular including storage buffers.
-
- case DescriptorSlotType::CombinedImageSampler:
- glSlotType = GLDescriptorSlotType::CombinedTextureSampler;
- break;
-
- case DescriptorSlotType::UniformBuffer:
- case DescriptorSlotType::DynamicUniformBuffer:
- glSlotType = GLDescriptorSlotType::ConstantBuffer;
- break;
- }
-
- rangeInfo.type = glSlotType;
- rangeInfo.arrayIndex = counts[int(glSlotType)];
- counts[int(glSlotType)] += rangeDesc.count;
-
- layoutImpl->m_ranges.add(rangeInfo);
- }
-
- for( Int ii = 0; ii < int(GLDescriptorSlotType::CountOf); ++ii )
- {
- layoutImpl->m_counts[ii] = counts[ii];
- }
-
- *outLayout = layoutImpl.detach();
- return SLANG_OK;
-}
-
-Result GLRenderer::createPipelineLayout(const PipelineLayout::Desc& desc, PipelineLayout** outLayout)
-{
- RefPtr<PipelineLayoutImpl> layoutImpl = new PipelineLayoutImpl();
-
- static const int kSlotTypeCount = int(GLDescriptorSlotType::CountOf);
- Int counts[kSlotTypeCount] = { 0, };
-
- Int setCount = desc.descriptorSetCount;
- for( Int ii = 0; ii < setCount; ++ii )
- {
- auto setLayout = (DescriptorSetLayoutImpl*) desc.descriptorSets[ii].layout;
-
- PipelineLayoutImpl::DescriptorSetInfo setInfo;
- setInfo.layout = setLayout;
-
- for( Int ii = 0; ii < int(GLDescriptorSlotType::CountOf); ++ii )
- {
- setInfo.baseArrayIndex[ii] = counts[ii];
- counts[ii] += setLayout->m_counts[ii];
- }
-
- layoutImpl->m_sets.add(setInfo);
- }
-
- *outLayout = layoutImpl.detach();
- return SLANG_OK;
-}
-
-Result GLRenderer::createDescriptorSet(DescriptorSetLayout* layout, DescriptorSet** outDescriptorSet)
-{
- auto layoutImpl = (DescriptorSetLayoutImpl*) layout;
-
- RefPtr<DescriptorSetImpl> descriptorSetImpl = new DescriptorSetImpl();
-
- descriptorSetImpl->m_layout = layoutImpl;
-
- // TODO: storage for the arrays of bound objects could be tail allocated
- // as part of the descriptor set, with offsets pre-computed in the
- // descriptor set layout.
-
- {
- auto slotTypeIndex = int(GLDescriptorSlotType::ConstantBuffer);
- auto slotCount = layoutImpl->m_counts[slotTypeIndex];
- descriptorSetImpl->m_constantBuffers.setCount(slotCount);
- }
-
- {
- auto slotTypeIndex = int(GLDescriptorSlotType::CombinedTextureSampler);
- auto slotCount = layoutImpl->m_counts[slotTypeIndex];
-
- descriptorSetImpl->m_textures.setCount(slotCount);
- descriptorSetImpl->m_samplers.setCount(slotCount);
- }
-
- *outDescriptorSet = descriptorSetImpl.detach();
- return SLANG_OK;
-}
-
-Result GLRenderer::createProgram(const ShaderProgram::Desc& desc, ShaderProgram** outProgram)
-{
- auto programID = glCreateProgram();
- if(desc.pipelineType == PipelineType::Compute )
- {
- auto computeKernel = desc.findKernel(StageType::Compute);
- auto computeShaderID = loadShader(GL_COMPUTE_SHADER, (char const*) computeKernel->codeBegin);
- glAttachShader(programID, computeShaderID);
- glLinkProgram(programID);
- glDeleteShader(computeShaderID);
- }
- else
- {
- auto vertexKernel = desc.findKernel(StageType::Vertex);
- auto fragmentKernel = desc.findKernel(StageType::Fragment);
-
- auto vertexShaderID = loadShader(GL_VERTEX_SHADER, (char const*) vertexKernel->codeBegin);
- auto fragmentShaderID = loadShader(GL_FRAGMENT_SHADER, (char const*) fragmentKernel->codeBegin);
-
- glAttachShader(programID, vertexShaderID);
- glAttachShader(programID, fragmentShaderID);
-
-
- glLinkProgram(programID);
-
- glDeleteShader(vertexShaderID);
- glDeleteShader(fragmentShaderID);
- }
- GLint success = GL_FALSE;
- glGetProgramiv(programID, GL_LINK_STATUS, &success);
- if (!success)
- {
- int maxSize = 0;
- glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &maxSize);
-
- auto infoBuffer = (char*)::malloc(maxSize);
-
- int infoSize = 0;
- glGetProgramInfoLog(programID, maxSize, &infoSize, infoBuffer);
- if (infoSize > 0)
- {
- fprintf(stderr, "%s", infoBuffer);
- OutputDebugStringA(infoBuffer);
- }
-
- ::free(infoBuffer);
-
- glDeleteProgram(programID);
- return SLANG_FAIL;
- }
-
- *outProgram = new ShaderProgramImpl(m_weakRenderer, programID);
- return SLANG_OK;
-}
-
-Result GLRenderer::createGraphicsPipelineState(const GraphicsPipelineStateDesc& desc, PipelineState** outState)
-{
- auto programImpl = (ShaderProgramImpl*) desc.program;
- auto pipelineLayoutImpl = (PipelineLayoutImpl*) desc.pipelineLayout;
- auto inputLayoutImpl = (InputLayoutImpl*) desc.inputLayout;
-
- RefPtr<PipelineStateImpl> pipelineStateImpl = new PipelineStateImpl();
- pipelineStateImpl->m_program = programImpl;
- pipelineStateImpl->m_pipelineLayout = pipelineLayoutImpl;
- pipelineStateImpl->m_inputLayout = inputLayoutImpl;
- *outState = pipelineStateImpl.detach();
- return SLANG_OK;
-}
-
-Result GLRenderer::createComputePipelineState(const ComputePipelineStateDesc& desc, PipelineState** outState)
-{
- auto programImpl = (ShaderProgramImpl*) desc.program;
- auto pipelineLayoutImpl = (PipelineLayoutImpl*) desc.pipelineLayout;
-
- RefPtr<PipelineStateImpl> pipelineStateImpl = new PipelineStateImpl();
- pipelineStateImpl->m_program = programImpl;
- pipelineStateImpl->m_pipelineLayout = pipelineLayoutImpl;
- *outState = pipelineStateImpl.detach();
- return SLANG_OK;
-}
-
-
-} // renderer_test