summaryrefslogtreecommitdiffstats
path: root/tools/render-test/render-gl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/render-test/render-gl.cpp')
-rw-r--r--tools/render-test/render-gl.cpp554
1 files changed, 358 insertions, 196 deletions
diff --git a/tools/render-test/render-gl.cpp b/tools/render-test/render-gl.cpp
index f888e72a2..27c3cdab4 100644
--- a/tools/render-test/render-gl.cpp
+++ b/tools/render-test/render-gl.cpp
@@ -11,6 +11,8 @@
#include "core/secure-crt.h"
#include "external/stb/stb_image_write.h"
+#include "slang-support.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...
@@ -82,20 +84,21 @@ public:
virtual void setClearColor(const float color[4]) override;
virtual void clearFrame() override;
virtual void presentFrame() override;
+ virtual TextureResource* createTextureResource(Resource::Type type, Resource::Usage initialUsage, const TextureResource::Desc& desc, const TextureResource::Data* initData) override;
+ virtual BufferResource* createBufferResource(Resource::Usage initialUsage, const BufferResource::Desc& descIn, const void* initData) override;
virtual SlangResult captureScreenShot(char const* outputPath) override;
virtual void serializeOutput(BindingState* state, const char* fileName) override;
- virtual Buffer* createBuffer(const BufferDesc& desc) override;
virtual InputLayout* createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount) override;
virtual BindingState * createBindingState(const ShaderInputLayout& layout) override;
virtual ShaderCompiler* getShaderCompiler() override;
- virtual void* map(Buffer* buffer, MapFlavor flavor) override;
- virtual void unmap(Buffer* buffer) override;
+ virtual void* map(BufferResource* buffer, MapFlavor flavor) override;
+ virtual void unmap(BufferResource* buffer) override;
virtual void setInputLayout(InputLayout* inputLayout) override;
virtual void setPrimitiveTopology(PrimitiveTopology topology) override;
virtual void setBindingState(BindingState* state);
- virtual void setVertexBuffers(UInt startSlot, UInt slotCount, Buffer*const* buffers, const UInt* strides, const UInt* offsets) override;
+ virtual void setVertexBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* strides, const UInt* offsets) override;
virtual void setShaderProgram(ShaderProgram* inProgram) override;
- virtual void setConstantBuffers(UInt startSlot, UInt slotCount, Buffer*const* buffers, const UInt* offsets) override;
+ virtual void setConstantBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* offsets) override;
virtual void draw(UInt vertexCount, UInt startVertex) override;
virtual void dispatchCompute(int x, int y, int z) override;
virtual void submitGpuWork() override {}
@@ -131,34 +134,69 @@ public:
UInt m_attributeCount = 0;
};
- class BufferImpl: public Buffer
+ class BufferResourceImpl: public BufferResource
{
public:
- BufferImpl(GLRenderer* renderer, GLuint id):
+ typedef BufferResource Parent;
+
+ BufferResourceImpl(Usage initialUsage, const Desc& desc, GLRenderer* renderer, GLuint id, GLenum target):
+ Parent(desc),
m_renderer(renderer),
- m_id(id)
+ m_handle(id),
+ m_initialUsage(initialUsage),
+ m_target(target)
{}
- ~BufferImpl()
+ ~BufferResourceImpl()
{
if (m_renderer)
{
- m_renderer->glDeleteBuffers(1, &m_id);
+ m_renderer->glDeleteBuffers(1, &m_handle);
}
}
+ Usage m_initialUsage;
GLRenderer* m_renderer;
- GLuint m_id;
+ GLuint m_handle;
+ GLenum m_target;
};
+ class TextureResourceImpl: public TextureResource
+ {
+ public:
+ typedef TextureResource Parent;
+
+ TextureResourceImpl(Type type, Usage initialUsage, const Desc& desc, GLRenderer* renderer):
+ Parent(type, desc),
+ m_initialUsage(initialUsage),
+ m_renderer(renderer)
+ {
+ m_target = 0;
+ m_handle = 0;
+ }
+
+ ~TextureResourceImpl()
+ {
+ if (m_handle)
+ {
+ glDeleteTextures(1, &m_handle);
+ }
+ }
+
+ Usage m_initialUsage;
+ GLRenderer* m_renderer;
+ GLenum m_target;
+ GLuint m_handle;
+ };
+
struct BindingEntry
{
ShaderInputType type;
- GLuint handle;
+ RefPtr<Resource> resource;
+ GLuint samplerHandle = 0;
List<int> binding;
- int bindTarget;
- int bufferSize;
bool isOutput = false;
};
+
class BindingStateImpl: public BindingState
{
public:
@@ -199,17 +237,31 @@ public:
GLRenderer* m_renderer;
};
- void destroyBindingEntry(const BindingEntry& entry);
+ 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 BindingEntry* entries, int numEntries);
- void bindBufferImpl(int target, UInt startSlot, UInt slotCount, Buffer*const* buffers, const UInt* offsets);
+ void bindBufferImpl(int target, UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* offsets);
void flushStateForDraw();
GLuint loadShader(GLenum stage, char const* source);
- void createInputBuffer(BindingEntry& rs, InputBufferDesc bufDesc, List<unsigned int>& bufferData);
void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message);
- void createInputTexture(BindingEntry& rs, InputTextureDesc texDesc, InputSamplerDesc samplerDesc);
void createInputSampler(BindingEntry& rs, InputSamplerDesc samplerDesc);
+ /// 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);
@@ -230,6 +282,24 @@ public:
#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[int(GlPixelFormat::CountOf)];
+};
+
+/* 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[int(GlPixelFormat::CountOf)] =
+{
+ // internalType, format, formatType
+ { 0, 0, 0}, // GlPixelFormat::Unknown
+ { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE }, // GlPixelFormat::RGBA_Unorm_UInt8
};
Renderer* createGLRenderer()
@@ -268,18 +338,19 @@ void GLRenderer::debugCallback(GLenum source, GLenum type, GLuint id, GLenum sev
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, Buffer*const* buffers, const UInt* offsets)
+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;
- BufferImpl* buffer = static_cast<BufferImpl*>(buffers[ii]);
- GLuint bufferID = buffer ? buffer->m_id : 0;
+ BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(buffers[ii]);
+ GLuint bufferID = buffer ? buffer->m_handle : 0;
assert(!offsets || !offsets[ii]);
@@ -426,158 +497,44 @@ GLuint GLRenderer::loadShader(GLenum stage, const char* source)
return shaderID;
}
-void GLRenderer::destroyBindingEntry(const BindingEntry& entry)
-{
- switch (entry.type)
- {
- case ShaderInputType::Buffer:
- {
- glDeleteBuffers(1, &entry.handle);
- break;
- }
- case ShaderInputType::Texture:
- case ShaderInputType::CombinedTextureSampler:
- {
- glDeleteTextures(1, &entry.handle);
- break;
- }
- case ShaderInputType::Sampler:
- {
- glDeleteSamplers(1, &entry.handle);
- break;
- }
- default: break;
- }
-}
-
void GLRenderer::destroyBindingEntries(const BindingEntry* entries, int numEntries)
{
for (int i = 0; i < numEntries; ++i)
{
- destroyBindingEntry(entries[i]);
+ const BindingEntry& entry = entries[i];
+ if (entry.type == ShaderInputType::Sampler && entry.samplerHandle != 0)
+ {
+ glDeleteSamplers(1, &entry.samplerHandle);
+ }
}
}
-void GLRenderer::createInputBuffer(BindingEntry& rs, InputBufferDesc bufDesc, List<unsigned int>& bufferData)
+void GLRenderer::createInputSampler(BindingEntry& entry, InputSamplerDesc samplerDesc)
{
- rs.bindTarget = (bufDesc.type == InputBufferType::StorageBuffer ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER);
- glGenBuffers(1, &rs.handle);
- glBindBuffer(rs.bindTarget, rs.handle);
- glBufferData(rs.bindTarget, bufferData.Count() * sizeof(unsigned int), bufferData.Buffer(), GL_STATIC_READ);
- glBindBuffer(rs.bindTarget, 0);
-}
+ GLuint handle;
-void GLRenderer::createInputTexture(BindingEntry& rs, InputTextureDesc texDesc, InputSamplerDesc samplerDesc)
-{
- TextureData texData;
- generateTextureData(texData, texDesc);
- glGenTextures(1, &rs.handle);
- switch (texDesc.dimension)
- {
- case 1:
- if (texDesc.arrayLength > 0)
- {
- rs.bindTarget = GL_TEXTURE_1D_ARRAY;
- glBindTexture(rs.bindTarget, rs.handle);
- int slice = 0;
- for (int i = 0; i < texData.arraySize; i++)
- {
- for (int j = 0; j < texData.mipLevels; j++)
- {
- glTexImage2D(rs.bindTarget, j, GL_RGBA8, texData.textureSize, i, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData.dataBuffer[slice].Buffer());
- slice++;
- }
- }
- }
- else
- {
- rs.bindTarget = GL_TEXTURE_1D;
- glBindTexture(rs.bindTarget, rs.handle);
- for (int i = 0; i < texData.mipLevels; i++)
- glTexImage1D(rs.bindTarget, i, GL_RGBA8, texData.textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData.dataBuffer[i].Buffer());
- }
- break;
- case 2:
- if (texDesc.arrayLength > 0)
- {
- if (texDesc.isCube)
- rs.bindTarget = GL_TEXTURE_CUBE_MAP_ARRAY;
- else
- rs.bindTarget = GL_TEXTURE_2D_ARRAY;
- glBindTexture(rs.bindTarget, rs.handle);
- for (auto i = 0u; i < texData.dataBuffer.Count(); i++)
- glTexImage3D(rs.bindTarget, i % texData.mipLevels, GL_RGBA8, texData.textureSize, texData.textureSize, i, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData.dataBuffer[i].Buffer());
- }
- else
- {
- if (texDesc.isCube)
- {
- rs.bindTarget = GL_TEXTURE_CUBE_MAP;
- glBindTexture(rs.bindTarget, rs.handle);
- for (int j = 0; j < 6; j++)
- {
- for (int i = 0; i < texData.mipLevels; i++)
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i, GL_RGBA8, texData.textureSize, texData.textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData.dataBuffer[i + j*texData.mipLevels].Buffer());
- }
- }
- else
- {
- rs.bindTarget = GL_TEXTURE_2D;
- glBindTexture(rs.bindTarget, rs.handle);
- for (int i = 0; i < texData.mipLevels; i++)
- glTexImage2D(rs.bindTarget, i, GL_RGBA8, texData.textureSize, texData.textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData.dataBuffer[i].Buffer());
- }
- }
- break;
- case 3:
- rs.bindTarget = GL_TEXTURE_3D;
- glBindTexture(rs.bindTarget, rs.handle);
- for (int i = 0; i < texData.mipLevels; i++)
- glTexImage3D(rs.bindTarget, i, GL_RGBA8, texData.textureSize, texData.textureSize, texData.textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData.dataBuffer[i].Buffer());
- break;
- }
- glTexParameteri(rs.bindTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(rs.bindTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(rs.bindTarget, GL_TEXTURE_WRAP_R, GL_REPEAT);
+ 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)
{
- glTexParameteri(rs.bindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(rs.bindTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(rs.bindTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8.0f);
+ 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
{
- glTexParameteri(rs.bindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(rs.bindTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(rs.bindTarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
- glTexParameteri(rs.bindTarget, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
+ 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);
}
-}
-void GLRenderer::createInputSampler(BindingEntry& rs, InputSamplerDesc samplerDesc)
-{
- glCreateSamplers(1, &rs.handle);
- glSamplerParameteri(rs.handle, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glSamplerParameteri(rs.handle, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glSamplerParameteri(rs.handle, GL_TEXTURE_WRAP_R, GL_REPEAT);
-
- if (samplerDesc.isCompareSampler)
- {
- glSamplerParameteri(rs.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glSamplerParameteri(rs.handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glSamplerParameteri(rs.handle, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);
- }
- else
- {
- glSamplerParameteri(rs.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glSamplerParameteri(rs.handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glSamplerParameteri(rs.handle, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
- glSamplerParameteri(rs.handle, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
- }
+ entry.samplerHandle = handle;
}
-
// !!!!!!!!!!!!!!!!!!!!!!!!!!!! Renderer interface !!!!!!!!!!!!!!!!!!!!!!!!!!
SlangResult GLRenderer::initialize(void* inWindowHandle)
@@ -691,21 +648,187 @@ ShaderCompiler* GLRenderer::getShaderCompiler()
return this;
}
-Buffer* GLRenderer::createBuffer(const BufferDesc& desc)
+TextureResource* GLRenderer::createTextureResource(Resource::Type type, Resource::Usage initialUsage, const TextureResource::Desc& descIn, const TextureResource::Data* initData)
{
- // TODO: should derive target from desc...
- GLenum target = GL_UNIFORM_BUFFER;
+ TextureResource::Desc srcDesc(descIn);
+ srcDesc.setDefaults(type, initialUsage);
- // TODO: should derive from desc...
- GLenum usage = GL_DYNAMIC_DRAW;
+ GlPixelFormat pixelFormat = _getGlPixelFormat(srcDesc.format);
+ if (pixelFormat == GlPixelFormat::Unknown)
+ {
+ return nullptr;
+ }
+
+ 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(type, initialUsage, srcDesc, this));
+
+ GLenum target = 0;
+ GLuint handle = 0;
+ glGenTextures(1, &handle);
+
+ const int effectiveArraySize = srcDesc.calcEffectiveArraySize(type);
+
+ 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 (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 (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 (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 nullptr;
+ }
+
+ 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;
+
+ return texture.detach();
+}
+
+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;
+ }
+}
+
+BufferResource* GLRenderer::createBufferResource(Resource::Usage initialUsage, const BufferResource::Desc& descIn, const void* initData)
+{
+ BufferResource::Desc desc(descIn);
+
+ if (desc.bindFlags == 0)
+ {
+ desc.bindFlags = Resource::s_requiredBinding[int(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, desc.size, desc.initData, usage);
+ glBufferData(target, descIn.sizeInBytes, initData, usage);
- return new BufferImpl(this, bufferID);
+ return new BufferResourceImpl(initialUsage, desc, this, bufferID, target);
}
InputLayout* GLRenderer::createInputLayout(const InputElementDesc* inputElements, UInt inputElementCount)
@@ -726,11 +849,11 @@ InputLayout* GLRenderer::createInputLayout(const InputElementDesc* inputElements
return (InputLayout*)inputLayout;
}
-void* GLRenderer::map(Buffer* bufferIn, MapFlavor flavor)
+void* GLRenderer::map(BufferResource* bufferIn, MapFlavor flavor)
{
- BufferImpl* buffer = static_cast<BufferImpl*>(bufferIn);
+ BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(bufferIn);
- GLenum target = GL_UNIFORM_BUFFER;
+ //GLenum target = GL_UNIFORM_BUFFER;
GLuint access = 0;
switch (flavor)
@@ -744,18 +867,15 @@ void* GLRenderer::map(Buffer* bufferIn, MapFlavor flavor)
break;
}
- auto bufferID = buffer ? buffer->m_id : 0;
- glBindBuffer(target, bufferID);
+ glBindBuffer(buffer->m_target, buffer->m_handle);
- return glMapBuffer(target, access);
+ return glMapBuffer(buffer->m_target, access);
}
-void GLRenderer::unmap(Buffer* bufferIn)
+void GLRenderer::unmap(BufferResource* bufferIn)
{
- BufferImpl* buffer = static_cast<BufferImpl*>(bufferIn);
- GLenum target = GL_UNIFORM_BUFFER;
- auto bufferID = buffer ? buffer->m_id : 0;
- glUnmapBuffer(target);
+ BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(bufferIn);
+ glUnmapBuffer(buffer->m_target);
}
void GLRenderer::setInputLayout(InputLayout* inputLayout)
@@ -777,14 +897,14 @@ void GLRenderer::setPrimitiveTopology(PrimitiveTopology topology)
m_boundPrimitiveTopology = glTopology;
}
-void GLRenderer::setVertexBuffers(UInt startSlot, UInt slotCount, Buffer*const* buffers, const UInt* strides, const UInt* offsets)
+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;
- BufferImpl* buffer = static_cast<BufferImpl*>(buffers[ii]);
- GLuint bufferID = buffer ? buffer->m_id : 0;
+ BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(buffers[ii]);
+ GLuint bufferID = buffer ? buffer->m_handle : 0;
m_boundVertexStreamBuffers[slot] = bufferID;
m_boundVertexStreamStrides[slot] = strides[ii];
@@ -800,7 +920,7 @@ void GLRenderer::setShaderProgram(ShaderProgram* programIn)
glUseProgram(programID);
}
-void GLRenderer::setConstantBuffers(UInt startSlot, UInt slotCount, Buffer*const* buffers, const UInt* offsets)
+void GLRenderer::setConstantBuffers(UInt startSlot, UInt slotCount, BufferResource*const* buffers, const UInt* offsets)
{
bindBufferImpl(GL_UNIFORM_BUFFER, startSlot, slotCount, buffers, offsets);
}
@@ -820,28 +940,51 @@ void GLRenderer::dispatchCompute(int x, int y, int z)
BindingState* GLRenderer::createBindingState(const ShaderInputLayout& layout)
{
BindingStateImpl* state = new BindingStateImpl(this);
- for (auto & entry : layout.entries)
+ for (auto & srcEntry : layout.entries)
{
- BindingEntry rsEntry;
- rsEntry.isOutput = entry.isOutput;
- rsEntry.binding = entry.glslBinding;
- rsEntry.type = entry.type;
- switch (entry.type)
+ BindingEntry dstEntry;
+ dstEntry.isOutput = srcEntry.isOutput;
+ dstEntry.binding = srcEntry.glslBinding;
+ dstEntry.type = srcEntry.type;
+
+ switch (srcEntry.type)
{
case ShaderInputType::Buffer:
- createInputBuffer(rsEntry, entry.bufferDesc, entry.bufferData);
+ {
+ RefPtr<BufferResource> bufferResource;
+ SLANG_RETURN_NULL_ON_FAIL(createInputBufferResource(srcEntry.bufferDesc, srcEntry.isOutput, srcEntry.bufferData.Count() * sizeof(uint32_t), srcEntry.bufferData.Buffer(), this, bufferResource));
+ dstEntry.resource = bufferResource;
break;
+ }
case ShaderInputType::Texture:
- createInputTexture(rsEntry, entry.textureDesc, InputSamplerDesc());
- break;
case ShaderInputType::CombinedTextureSampler:
- createInputTexture(rsEntry, entry.textureDesc, entry.samplerDesc);
+ {
+ RefPtr<TextureResource> textureResource;
+
+ int bindFlags = 0;
+ SLANG_RETURN_NULL_ON_FAIL(generateTextureResource(srcEntry.textureDesc, bindFlags, this, textureResource));
+
+ // Handle if combined
+ if (srcEntry.type == ShaderInputType::CombinedTextureSampler && srcEntry.samplerDesc.isCompareSampler)
+ {
+ TextureResourceImpl* texture = static_cast<TextureResourceImpl*>(textureResource.Ptr());
+ 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 ShaderInputType::Sampler:
- createInputSampler(rsEntry, entry.samplerDesc);
+ {
+ createInputSampler(dstEntry, srcEntry.samplerDesc);
break;
+ }
}
- state->m_entries.Add(rsEntry);
+ state->m_entries.Add(dstEntry);
}
return state;
}
@@ -854,17 +997,28 @@ void GLRenderer::setBindingState(BindingState* stateIn)
switch (entry.type)
{
case ShaderInputType::Buffer:
- glBindBufferBase(entry.bindTarget, entry.binding[0], entry.handle);
+ {
+ BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(entry.resource.Ptr());
+ glBindBufferBase(buffer->m_target, entry.binding[0], buffer->m_handle);
break;
+ }
case ShaderInputType::Sampler:
+ {
for (auto b : entry.binding)
- glBindSampler(b, entry.handle);
+ {
+ glBindSampler(b, entry.samplerHandle);
+ }
break;
+ }
case ShaderInputType::Texture:
case ShaderInputType::CombinedTextureSampler:
+ {
+ BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(entry.resource.Ptr());
+
glActiveTexture(GL_TEXTURE0 + entry.binding[0]);
- glBindTexture(entry.bindTarget, entry.handle);
+ glBindTexture(buffer->m_target, buffer->m_handle);
break;
+ }
}
}
}
@@ -878,11 +1032,19 @@ void GLRenderer::serializeOutput(BindingState* stateIn, const char* fileName)
{
if (entry.isOutput)
{
- glBindBuffer(entry.bindTarget, entry.handle);
- auto ptr = (unsigned int *)glMapBuffer(entry.bindTarget, GL_READ_ONLY);
- for (auto i = 0u; i < entry.bufferSize / sizeof(unsigned int); i++)
- fprintf(f, "%X\n", ptr[i]);
- glUnmapBuffer(entry.bindTarget);
+ if (entry.resource && entry.resource->isBuffer())
+ {
+ BufferResource* bufferResource = static_cast<BufferResource*>(entry.resource.Ptr());
+ size_t bufferSize = bufferResource->getDesc().sizeInBytes;
+
+ unsigned int* ptr = (unsigned int*)map(bufferResource, MapFlavor::HostRead);
+
+ for (auto i = 0u; i < bufferSize / sizeof(unsigned int); i++)
+ {
+ fprintf(f, "%X\n", ptr[i]);
+ }
+ unmap(bufferResource);
+ }
}
}
fclose(f);