diff options
| author | YONGH\yongh <yonghe@outlook.com> | 2017-10-25 16:33:18 -0400 |
|---|---|---|
| committer | YONGH\yongh <yonghe@outlook.com> | 2017-10-25 16:33:18 -0400 |
| commit | 5894c3b1a96e9db41f50b2b178f81568ff421776 (patch) | |
| tree | 035aedbf9c6d64ded7dd91338997856d814bf813 /tools/render-test | |
| parent | 434d3428932ccaa0f6834d03c37adcab37d17a01 (diff) | |
finish up opengl renderer implementation for input resource binding.
Diffstat (limited to 'tools/render-test')
| -rw-r--r-- | tools/render-test/render-d3d11.cpp | 132 | ||||
| -rw-r--r-- | tools/render-test/render-gl.cpp | 200 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.cpp | 76 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.h | 10 |
4 files changed, 319 insertions, 99 deletions
diff --git a/tools/render-test/render-d3d11.cpp b/tools/render-test/render-d3d11.cpp index 8f73b4dd4..f90d3fbbe 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/render-test/render-d3d11.cpp @@ -852,81 +852,20 @@ public: void createInputTexture(const InputTextureDesc & inputDesc, ID3D11ShaderResourceView * &viewOut) { - int arrLen = inputDesc.arrayLength; - if (arrLen == 0) - arrLen = 1; + TextureData texData; + generateTextureData(texData, inputDesc); List<D3D11_SUBRESOURCE_DATA> subRes; - List<List<unsigned int>> dataBuffer; - int arraySize = arrLen; - if (inputDesc.isCube) - arraySize *= 6; - int textureSize = inputDesc.size; - int textureMipLevels = Math::Log2Floor(textureSize) + 1; - subRes.SetSize(textureMipLevels * arraySize); - dataBuffer.SetSize(subRes.Count()); - - auto iteratePixels = [&](int dimension, int size, unsigned int * buffer, auto f) + for (int i = 0; i < texData.arraySize; i++) { - if (dimension == 1) - for (int i = 0; i < size; i++) - buffer[i] = f(i, 0, 0); - else if (dimension == 2) - for (int i = 0; i < size; i++) - for (int j = 0; j < size; j++) - buffer[i*size + j] = f(j, i, 0); - else if (dimension == 3) - for (int i = 0; i < size; i++) - for (int j = 0; j < size; j++) - for (int k = 0; k < size; k++) - buffer[i*size*size + j*size + k] = f(k, j, i); - }; - - int slice = 0; - for (int i = 0; i < arraySize; i++) - { - for (int j = 0; j < textureMipLevels; j++) + int slice = 0; + for (int j = 0; j < texData.mipLevels; j++) { - int size = textureSize >> j; - int bufferLen = size; - if (inputDesc.dimension == 2) - bufferLen *= size; - else if (inputDesc.dimension == 3) - bufferLen *= size*size; - dataBuffer[slice].SetSize(bufferLen); - subRes[slice].pSysMem = dataBuffer[slice].Buffer(); - subRes[slice].SysMemPitch = sizeof(unsigned int) * size; - subRes[slice].SysMemSlicePitch = sizeof(unsigned int) * size * size; - - iteratePixels(inputDesc.dimension, size, dataBuffer[slice].Buffer(), [&](int x, int y, int z) -> unsigned int - { - if (inputDesc.content == InputTextureContent::Zero) - { - return 0x0; - } - else if (inputDesc.content == InputTextureContent::One) - { - return 0xFFFFFFFF; - } - else if (inputDesc.content == InputTextureContent::Gradient) - { - unsigned char r = (unsigned char)(x / (float)(size - 1) * 255.0f); - unsigned char g = (unsigned char)(y / (float)(size - 1) * 255.0f); - unsigned char b = (unsigned char)(z / (float)(size - 1) * 255.0f); - return 0xFF000000 + r + (g << 8) + (b << 16); - } - else if (inputDesc.content == InputTextureContent::ChessBoard) - { - unsigned int xSig = x < (size >> 1) ? 1 : 0; - unsigned int ySig = y < (size >> 1) ? 1 : 0; - unsigned int zSig = z < (size >> 1) ? 1 : 0; - auto sig = xSig ^ ySig ^ zSig; - if (sig) - return 0xFFFFFFFF; - else - return 0xFF808080; - } - return 0x0; - }); + int size = texData.textureSize >> j; + D3D11_SUBRESOURCE_DATA res; + res.pSysMem = texData.dataBuffer[slice].Buffer(); + res.SysMemPitch = sizeof(unsigned int) * size; + res.SysMemSlicePitch = sizeof(unsigned int) * size * size; + subRes.Add(res); slice++; } } @@ -937,9 +876,9 @@ public: desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; - desc.MipLevels = textureMipLevels; - desc.ArraySize = arraySize; - desc.Width = textureSize; + desc.MipLevels = texData.mipLevels; + desc.ArraySize = texData.arraySize; + desc.Width = texData.textureSize; desc.Usage = D3D11_USAGE_DEFAULT; ID3D11Texture1D * texture; @@ -949,11 +888,11 @@ public: viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; if (inputDesc.arrayLength != 0) viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; - viewDesc.Texture1D.MipLevels = textureMipLevels; + viewDesc.Texture1D.MipLevels = texData.mipLevels; viewDesc.Texture1D.MostDetailedMip = 0; - viewDesc.Texture1DArray.ArraySize = arraySize; + viewDesc.Texture1DArray.ArraySize = texData.arraySize; viewDesc.Texture1DArray.FirstArraySlice = 0; - viewDesc.Texture1DArray.MipLevels = textureMipLevels; + viewDesc.Texture1DArray.MipLevels = texData.mipLevels; viewDesc.Texture1DArray.MostDetailedMip = 0; dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); } @@ -965,15 +904,15 @@ public: desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; - desc.MipLevels = textureMipLevels; - desc.ArraySize = arraySize; + desc.MipLevels = texData.mipLevels; + desc.ArraySize = texData.arraySize; if (inputDesc.isCube) { desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - viewDesc.TextureCube.MipLevels = textureMipLevels; + viewDesc.TextureCube.MipLevels = texData.mipLevels; viewDesc.TextureCube.MostDetailedMip = 0; - viewDesc.TextureCubeArray.MipLevels = textureMipLevels; + viewDesc.TextureCubeArray.MipLevels = texData.mipLevels; viewDesc.TextureCubeArray.MostDetailedMip = 0; viewDesc.TextureCubeArray.First2DArrayFace = 0; viewDesc.TextureCubeArray.NumCubes = inputDesc.arrayLength; @@ -981,17 +920,17 @@ public: else { viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - viewDesc.Texture2D.MipLevels = textureMipLevels; + viewDesc.Texture2D.MipLevels = texData.mipLevels; viewDesc.Texture2D.MostDetailedMip = 0; - viewDesc.Texture2DArray.ArraySize = arraySize; + viewDesc.Texture2DArray.ArraySize = texData.arraySize; viewDesc.Texture2DArray.FirstArraySlice = 0; - viewDesc.Texture2DArray.MipLevels = textureMipLevels; + viewDesc.Texture2DArray.MipLevels = texData.mipLevels; viewDesc.Texture2DArray.MostDetailedMip = 0; } if (inputDesc.arrayLength != 0) viewDesc.ViewDimension = (D3D11_SRV_DIMENSION)(int)(viewDesc.ViewDimension + 1); - desc.Width = textureSize; - desc.Height = textureSize; + desc.Width = texData.textureSize; + desc.Height = texData.textureSize; desc.Usage = D3D11_USAGE_DEFAULT; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; @@ -1007,17 +946,17 @@ public: desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS; - desc.MipLevels = textureMipLevels; + desc.MipLevels = texData.mipLevels; viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - desc.Width = textureSize; - desc.Height = textureSize; - desc.Depth = textureSize; + desc.Width = texData.textureSize; + desc.Height = texData.textureSize; + desc.Depth = texData.textureSize; desc.Usage = D3D11_USAGE_DEFAULT; ID3D11Texture3D * texture; dxDevice->CreateTexture3D(&desc, subRes.Buffer(), &texture); if (inputDesc.arrayLength != 0) viewDesc.ViewDimension = (D3D11_SRV_DIMENSION)(int)(viewDesc.ViewDimension + 1); - viewDesc.Texture3D.MipLevels = textureMipLevels; + viewDesc.Texture3D.MipLevels = texData.mipLevels; viewDesc.Texture3D.MostDetailedMip = 0; dxDevice->CreateShaderResourceView(texture, &viewDesc, &viewOut); } @@ -1032,12 +971,15 @@ public: { desc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL; desc.Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; + desc.MinLOD = desc.MaxLOD = 0.0f; } else + { desc.Filter = D3D11_FILTER_ANISOTROPIC; - desc.MaxAnisotropy = 16; - desc.MinLOD = 0.0f; - desc.MaxLOD = 100.0f; + desc.MaxAnisotropy = 8; + desc.MinLOD = 0.0f; + desc.MaxLOD = 100.0f; + } dxDevice->CreateSamplerState(&desc, &stateOut); } virtual BindingState * createBindingState(const ShaderInputLayout & layout) diff --git a/tools/render-test/render-gl.cpp b/tools/render-test/render-gl.cpp index ff9d54eb6..e983dad70 100644 --- a/tools/render-test/render-gl.cpp +++ b/tools/render-test/render-gl.cpp @@ -7,7 +7,7 @@ #include <assert.h> #include <stdio.h> #include <stdlib.h> - +#include "core/basic.h" #include "external/stb/stb_image_write.h" // TODO(tfoley): eventually we should be able to run these @@ -59,8 +59,15 @@ F(glDisableVertexAttribArray, PFNGLDISABLEVERTEXATTRIBARRAYPROC) \ F(glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) \ F(glDispatchCompute, PFNGLDISPATCHCOMPUTEPROC) \ + F(glActiveTexture, PFNGLACTIVETEXTUREPROC) \ + F(glCreateSamplers, PFNGLCREATESAMPLERSPROC) \ + F(glBindSampler, PFNGLBINDSAMPLERPROC) \ + F(glTexImage3D, PFNGLTEXIMAGE3DPROC) \ + F(glSamplerParameteri, PFNGLSAMPLERPARAMETERIPROC) \ /* end */ +using namespace Slang; + namespace renderer_test { class GLRenderer : public Renderer, public ShaderCompiler @@ -614,19 +621,204 @@ public: glDispatchCompute(x, y, z); } + struct GLBindingEntry + { + ShaderInputType type; + GLuint handle; + int binding; + int bindTarget; + int bufferSize; + bool isOutput = false; + }; + struct GLBindingState + { + List<GLBindingEntry> entries; + }; + + void createInputBuffer(GLBindingEntry & rs, InputBufferDesc bufDesc, List<unsigned int> & bufferData) + { + 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); + } + + void createInputTexture(GLBindingEntry & 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); + + 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); + } + 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); + } + } + + void createInputSampler(GLBindingEntry & 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.0f); + } + 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); + } + } + virtual BindingState * createBindingState(const ShaderInputLayout & layout) { - return nullptr; + GLBindingState * rs = new GLBindingState(); + for (auto & entry : layout.entries) + { + GLBindingEntry rsEntry; + rsEntry.isOutput = entry.isOutput; + rsEntry.binding = entry.glslBinding; + rsEntry.type = entry.type; + switch (entry.type) + { + case ShaderInputType::Buffer: + createInputBuffer(rsEntry, entry.bufferDesc, entry.bufferData); + break; + case ShaderInputType::Texture: + createInputTexture(rsEntry, entry.textureDesc, InputSamplerDesc()); + break; + case ShaderInputType::CombinedTextureSampler: + createInputTexture(rsEntry, entry.textureDesc, entry.samplerDesc); + break; + case ShaderInputType::Sampler: + createInputSampler(rsEntry, entry.samplerDesc); + break; + } + rs->entries.Add(rsEntry); + } + return (BindingState*)rs; } virtual void setBindingState(BindingState * state) { - + GLBindingState * glState = (GLBindingState*)state; + for (auto & entry : glState->entries) + { + switch (entry.type) + { + case ShaderInputType::Buffer: + glBindBufferBase(entry.bindTarget, entry.binding, entry.handle); + break; + case ShaderInputType::Sampler: + glBindSampler(entry.binding, entry.handle); + break; + case ShaderInputType::Texture: + case ShaderInputType::CombinedTextureSampler: + glActiveTexture(GL_TEXTURE0 + entry.binding); + glBindTexture(entry.bindTarget, entry.handle); + break; + } + } } virtual void serializeOutput(BindingState* state, const char * fileName) { - + GLBindingState * glState = (GLBindingState*)state; + FILE * f = fopen(fileName, "wt"); + for (auto & entry : glState->entries) + { + 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); + } + } + fclose(f); } }; diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp index b606a1a13..47ba767ae 100644 --- a/tools/render-test/shader-input-layout.cpp +++ b/tools/render-test/shader-input-layout.cpp @@ -218,4 +218,80 @@ namespace renderer_test } + void generateTextureData(TextureData & output, const InputTextureDesc & inputDesc) + { + int arrLen = inputDesc.arrayLength; + if (arrLen == 0) + arrLen = 1; + List<List<unsigned int>> dataBuffer; + int arraySize = arrLen; + if (inputDesc.isCube) + arraySize *= 6; + output.arraySize = arraySize; + output.textureSize = inputDesc.size; + output.mipLevels = Math::Log2Floor(output.textureSize) + 1; + output.dataBuffer.SetSize(output.mipLevels * output.arraySize); + auto iteratePixels = [&](int dimension, int size, unsigned int * buffer, auto f) + { + if (dimension == 1) + for (int i = 0; i < size; i++) + buffer[i] = f(i, 0, 0); + else if (dimension == 2) + for (int i = 0; i < size; i++) + for (int j = 0; j < size; j++) + buffer[i*size + j] = f(j, i, 0); + else if (dimension == 3) + for (int i = 0; i < size; i++) + for (int j = 0; j < size; j++) + for (int k = 0; k < size; k++) + buffer[i*size*size + j*size + k] = f(k, j, i); + }; + + int slice = 0; + for (int i = 0; i < arraySize; i++) + { + for (int j = 0; j < output.mipLevels; j++) + { + int size = output.textureSize >> j; + int bufferLen = size; + if (inputDesc.dimension == 2) + bufferLen *= size; + else if (inputDesc.dimension == 3) + bufferLen *= size*size; + dataBuffer[slice].SetSize(bufferLen); + + iteratePixels(inputDesc.dimension, size, dataBuffer[slice].Buffer(), [&](int x, int y, int z) -> unsigned int + { + if (inputDesc.content == InputTextureContent::Zero) + { + return 0x0; + } + else if (inputDesc.content == InputTextureContent::One) + { + return 0xFFFFFFFF; + } + else if (inputDesc.content == InputTextureContent::Gradient) + { + unsigned char r = (unsigned char)(x / (float)(size - 1) * 255.0f); + unsigned char g = (unsigned char)(y / (float)(size - 1) * 255.0f); + unsigned char b = (unsigned char)(z / (float)(size - 1) * 255.0f); + return 0xFF000000 + r + (g << 8) + (b << 16); + } + else if (inputDesc.content == InputTextureContent::ChessBoard) + { + unsigned int xSig = x < (size >> 1) ? 1 : 0; + unsigned int ySig = y < (size >> 1) ? 1 : 0; + unsigned int zSig = z < (size >> 1) ? 1 : 0; + auto sig = xSig ^ ySig ^ zSig; + if (sig) + return 0xFFFFFFFF; + else + return 0xFF808080; + } + return 0x0; + }); + slice++; + } + } + } }
\ No newline at end of file diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h index f2258b7b9..9dae75270 100644 --- a/tools/render-test/shader-input-layout.h +++ b/tools/render-test/shader-input-layout.h @@ -49,6 +49,16 @@ namespace renderer_test int glslBinding = -1; int glslLocation = -1; }; + + struct TextureData + { + Slang::List<Slang::List<unsigned int>> dataBuffer; + int textureSize; + int mipLevels; + int arraySize; + }; + void generateTextureData(TextureData & output, const InputTextureDesc & desc); + class ShaderInputLayout { public: |
