Compare commits
7 Commits
idris/spec
...
zm/test-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07356a2949 | ||
|
|
c73d11858e | ||
|
|
23b67be41a | ||
|
|
7d53baad5c | ||
|
|
1ae33a23fe | ||
|
|
351d9287af | ||
|
|
e7e5004946 |
@@ -57,7 +57,7 @@ SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 0
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: false
|
||||
|
||||
@@ -222,6 +222,56 @@ public:
|
||||
return static_cast<Dp>(p);
|
||||
}
|
||||
|
||||
template<typename Dp, typename B>
|
||||
inline std::enable_if_t<
|
||||
std::is_pointer_v<Dp> && std::is_base_of_v<B, std::remove_pointer_t<Dp>>, int16_t>
|
||||
handle_set_value(Handle<B>& handle, uint8_t v) {
|
||||
assert_invariant(handle);
|
||||
auto [p, tag] = handleToPointer(handle.getId());
|
||||
|
||||
if (isPoolHandle(handle.getId())) {
|
||||
// check for pool handle use-after-free
|
||||
if (UTILS_UNLIKELY(!mUseAfterFreeCheckDisabled)) {
|
||||
auto const pNode = static_cast<typename Allocator::Node*>(p);
|
||||
pNode[-1].test_value = v;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
// check for heap handle use-after-free
|
||||
if (UTILS_UNLIKELY(!mUseAfterFreeCheckDisabled)) {
|
||||
return -1;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Dp, typename B>
|
||||
inline std::enable_if_t<
|
||||
std::is_pointer_v<Dp> && std::is_base_of_v<B, std::remove_pointer_t<Dp>>, int16_t>
|
||||
handle_get_value(Handle<B>& handle) {
|
||||
assert_invariant(handle);
|
||||
auto [p, tag] = handleToPointer(handle.getId());
|
||||
|
||||
if (isPoolHandle(handle.getId())) {
|
||||
// check for pool handle use-after-free
|
||||
if (UTILS_UNLIKELY(!mUseAfterFreeCheckDisabled)) {
|
||||
auto const pNode = static_cast<typename Allocator::Node*>(p);
|
||||
uint8_t age = pNode[-1].age;
|
||||
uint8_t test_value = pNode[-1].test_value;
|
||||
int16_t ret = (int16_t) ((age << 8) | test_value);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
// check for heap handle use-after-free
|
||||
if (UTILS_UNLIKELY(!mUseAfterFreeCheckDisabled)) {
|
||||
return -1;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
utils::CString getHandleTag(HandleBase::HandleId key) const noexcept;
|
||||
|
||||
template<typename B>
|
||||
@@ -276,7 +326,10 @@ private:
|
||||
class Allocator {
|
||||
friend class HandleAllocator;
|
||||
static constexpr size_t MIN_ALIGNMENT = alignof(std::max_align_t);
|
||||
struct Node { uint8_t age; };
|
||||
struct Node {
|
||||
uint8_t age;
|
||||
uint8_t test_value = 0xff;
|
||||
};
|
||||
// Note: using the `extra` parameter of PoolAllocator<>, even with a 1-byte structure,
|
||||
// generally increases all pool allocations by 8-bytes because of alignment restrictions.
|
||||
template<size_t SIZE>
|
||||
|
||||
@@ -162,8 +162,11 @@ void GLDescriptorSet::update(OpenGLContext&,
|
||||
}, descriptors[binding].desc);
|
||||
}
|
||||
|
||||
void GLDescriptorSet::update(OpenGLContext& gl,
|
||||
descriptor_binding_t binding, GLTexture* t, SamplerParams params) noexcept {
|
||||
void GLDescriptorSet::update(OpenGLContext& gl, HandleAllocatorGL& handleAllocator,
|
||||
descriptor_binding_t binding, TextureHandle th, SamplerParams params) noexcept {
|
||||
|
||||
GLTexture* t = th ? handleAllocator.handle_cast<GLTexture*>(th) : nullptr;
|
||||
|
||||
assert_invariant(binding < descriptors.size());
|
||||
std::visit([=, &gl](auto&& arg) mutable {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
@@ -196,20 +199,12 @@ void GLDescriptorSet::update(OpenGLContext& gl,
|
||||
}
|
||||
}
|
||||
|
||||
arg.target = t ? t->gl.target : 0;
|
||||
arg.id = t ? t->gl.id : 0;
|
||||
arg.external = t ? t->gl.external : false;
|
||||
arg.handle = th;
|
||||
if constexpr (std::is_same_v<T, Sampler> ||
|
||||
std::is_same_v<T, SamplerWithAnisotropyWorkaround>) {
|
||||
if constexpr (std::is_same_v<T, SamplerWithAnisotropyWorkaround>) {
|
||||
arg.anisotropy = float(1u << params.anisotropyLog2);
|
||||
}
|
||||
if (t) {
|
||||
arg.ref = t->ref;
|
||||
arg.baseLevel = t->gl.baseLevel;
|
||||
arg.maxLevel = t->gl.maxLevel;
|
||||
arg.swizzle = t->gl.swizzle;
|
||||
}
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
arg.sampler = gl.getSampler(params);
|
||||
#else
|
||||
@@ -225,39 +220,39 @@ void GLDescriptorSet::update(OpenGLContext& gl,
|
||||
}, descriptors[binding].desc);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void GLDescriptorSet::updateTextureView(OpenGLContext& gl,
|
||||
HandleAllocatorGL& handleAllocator, GLuint unit, T const& desc) noexcept {
|
||||
HandleAllocatorGL& handleAllocator, GLuint unit, GLTexture const* t) noexcept {
|
||||
// The common case is that we don't have a ref handle (we only have one if
|
||||
// the texture ever had a View on it).
|
||||
assert_invariant(desc.ref);
|
||||
GLTextureRef* const ref = handleAllocator.handle_cast<GLTextureRef*>(desc.ref);
|
||||
if (UTILS_UNLIKELY((desc.baseLevel != ref->baseLevel || desc.maxLevel != ref->maxLevel))) {
|
||||
assert_invariant(t);
|
||||
assert_invariant(t->ref);
|
||||
GLTextureRef* const ref = handleAllocator.handle_cast<GLTextureRef*>(t->ref);
|
||||
if (UTILS_UNLIKELY((t->gl.baseLevel != ref->baseLevel || t->gl.maxLevel != ref->maxLevel))) {
|
||||
// If we have views, then it's still uncommon that we'll switch often
|
||||
// handle the case where we reset to the original texture
|
||||
GLint baseLevel = GLint(desc.baseLevel); // NOLINT(*-signed-char-misuse)
|
||||
GLint maxLevel = GLint(desc.maxLevel); // NOLINT(*-signed-char-misuse)
|
||||
GLint baseLevel = GLint(t->gl.baseLevel); // NOLINT(*-signed-char-misuse)
|
||||
GLint maxLevel = GLint(t->gl.maxLevel); // NOLINT(*-signed-char-misuse)
|
||||
if (baseLevel > maxLevel) {
|
||||
baseLevel = 0;
|
||||
maxLevel = 1000; // per OpenGL spec
|
||||
}
|
||||
// that is very unfortunate that we have to call activeTexture here
|
||||
gl.activeTexture(unit);
|
||||
glTexParameteri(desc.target, GL_TEXTURE_BASE_LEVEL, baseLevel);
|
||||
glTexParameteri(desc.target, GL_TEXTURE_MAX_LEVEL, maxLevel);
|
||||
ref->baseLevel = desc.baseLevel;
|
||||
ref->maxLevel = desc.maxLevel;
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_BASE_LEVEL, baseLevel);
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_MAX_LEVEL, maxLevel);
|
||||
ref->baseLevel = t->gl.baseLevel;
|
||||
ref->maxLevel = t->gl.maxLevel;
|
||||
}
|
||||
if (UTILS_UNLIKELY(desc.swizzle != ref->swizzle)) {
|
||||
if (UTILS_UNLIKELY(t->gl.swizzle != ref->swizzle)) {
|
||||
using namespace GLUtils;
|
||||
gl.activeTexture(unit);
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2)
|
||||
glTexParameteri(desc.target, GL_TEXTURE_SWIZZLE_R, (GLint)getSwizzleChannel(desc.swizzle[0]));
|
||||
glTexParameteri(desc.target, GL_TEXTURE_SWIZZLE_G, (GLint)getSwizzleChannel(desc.swizzle[1]));
|
||||
glTexParameteri(desc.target, GL_TEXTURE_SWIZZLE_B, (GLint)getSwizzleChannel(desc.swizzle[2]));
|
||||
glTexParameteri(desc.target, GL_TEXTURE_SWIZZLE_A, (GLint)getSwizzleChannel(desc.swizzle[3]));
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_SWIZZLE_R, (GLint)getSwizzleChannel(t->gl.swizzle[0]));
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_SWIZZLE_G, (GLint)getSwizzleChannel(t->gl.swizzle[1]));
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_SWIZZLE_B, (GLint)getSwizzleChannel(t->gl.swizzle[2]));
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_SWIZZLE_A, (GLint)getSwizzleChannel(t->gl.swizzle[3]));
|
||||
#endif
|
||||
ref->swizzle = desc.swizzle;
|
||||
ref->swizzle = t->gl.swizzle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,27 +305,31 @@ void GLDescriptorSet::bind(
|
||||
}
|
||||
} else if constexpr (std::is_same_v<T, Sampler>) {
|
||||
GLuint const unit = p.getTextureUnit(set, binding);
|
||||
if (arg.target) {
|
||||
gl.bindTexture(unit, arg.target, arg.id, arg.external);
|
||||
|
||||
|
||||
if (arg.handle) {
|
||||
GLTexture const* const t = handleAllocator.handle_cast<GLTexture*>(arg.handle);
|
||||
gl.bindTexture(unit, t->gl.target, t->gl.id, t->gl.external);
|
||||
gl.bindSampler(unit, arg.sampler);
|
||||
if (UTILS_UNLIKELY(arg.ref)) {
|
||||
updateTextureView(gl, handleAllocator, unit, arg);
|
||||
if (UTILS_UNLIKELY(t->ref)) {
|
||||
updateTextureView(gl, handleAllocator, unit, t);
|
||||
}
|
||||
} else {
|
||||
gl.unbindTextureUnit(unit);
|
||||
}
|
||||
} else if constexpr (std::is_same_v<T, SamplerWithAnisotropyWorkaround>) {
|
||||
GLuint const unit = p.getTextureUnit(set, binding);
|
||||
if (arg.target) {
|
||||
gl.bindTexture(unit, arg.target, arg.id, arg.external);
|
||||
if (arg.handle) {
|
||||
GLTexture const* const t = handleAllocator.handle_cast<GLTexture*>(arg.handle);
|
||||
gl.bindTexture(unit, t->gl.target, t->gl.id, t->gl.external);
|
||||
gl.bindSampler(unit, arg.sampler);
|
||||
if (UTILS_UNLIKELY(arg.ref)) {
|
||||
updateTextureView(gl, handleAllocator, unit, arg);
|
||||
if (UTILS_UNLIKELY(t->ref)) {
|
||||
updateTextureView(gl, handleAllocator, unit, t);
|
||||
}
|
||||
#if defined(GL_EXT_texture_filter_anisotropic)
|
||||
// Driver claims to support anisotropic filtering, but it fails when set on
|
||||
// the sampler, we have to set it on the texture instead.
|
||||
glTexParameterf(arg.target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
glTexParameterf(t->gl.target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
std::min(gl.gets.max_anisotropy, float(arg.anisotropy)));
|
||||
#endif
|
||||
} else {
|
||||
@@ -339,19 +338,20 @@ void GLDescriptorSet::bind(
|
||||
} else if constexpr (std::is_same_v<T, SamplerGLES2>) {
|
||||
// in ES2 the sampler parameters need to be set on the texture itself
|
||||
GLuint const unit = p.getTextureUnit(set, binding);
|
||||
if (arg.target) {
|
||||
gl.bindTexture(unit, arg.target, arg.id, arg.external);
|
||||
if (arg.handle) {
|
||||
GLTexture const* const t = handleAllocator.handle_cast<GLTexture*>(arg.handle);
|
||||
gl.bindTexture(unit, t->gl.target, t->gl.id, t->gl.external);
|
||||
SamplerParams const params = arg.params;
|
||||
glTexParameteri(arg.target, GL_TEXTURE_MIN_FILTER,
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_MIN_FILTER,
|
||||
(GLint)GLUtils::getTextureFilter(params.filterMin));
|
||||
glTexParameteri(arg.target, GL_TEXTURE_MAG_FILTER,
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_MAG_FILTER,
|
||||
(GLint)GLUtils::getTextureFilter(params.filterMag));
|
||||
glTexParameteri(arg.target, GL_TEXTURE_WRAP_S,
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_WRAP_S,
|
||||
(GLint)GLUtils::getWrapMode(params.wrapS));
|
||||
glTexParameteri(arg.target, GL_TEXTURE_WRAP_T,
|
||||
glTexParameteri(t->gl.target, GL_TEXTURE_WRAP_T,
|
||||
(GLint)GLUtils::getWrapMode(params.wrapT));
|
||||
#if defined(GL_EXT_texture_filter_anisotropic)
|
||||
glTexParameterf(arg.target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
glTexParameterf(t->gl.target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
std::min(gl.gets.max_anisotropy, arg.anisotropy));
|
||||
#endif
|
||||
} else {
|
||||
|
||||
@@ -59,8 +59,8 @@ struct GLDescriptorSet : public HwDescriptorSet {
|
||||
descriptor_binding_t binding, GLBufferObject* bo, size_t offset, size_t size) noexcept;
|
||||
|
||||
// update a sampler descriptor in the set
|
||||
void update(OpenGLContext& gl,
|
||||
descriptor_binding_t binding, GLTexture* t, SamplerParams params) noexcept;
|
||||
void update(OpenGLContext& gl, HandleAllocatorGL& handleAllocator,
|
||||
descriptor_binding_t binding, TextureHandle th, SamplerParams params) noexcept;
|
||||
|
||||
// conceptually bind the set to the command buffer
|
||||
void bind(
|
||||
@@ -111,46 +111,19 @@ private:
|
||||
|
||||
// A sampler descriptor
|
||||
struct Sampler {
|
||||
uint16_t target; // 2 (GLenum)
|
||||
bool external = false; // 1
|
||||
bool reserved = false; // 1
|
||||
GLuint id = 0; // 4
|
||||
TextureHandle handle; // 4
|
||||
GLuint sampler = 0; // 4
|
||||
Handle<GLTextureRef> ref; // 4
|
||||
int8_t baseLevel = 0x7f; // 1
|
||||
int8_t maxLevel = -1; // 1
|
||||
std::array<TextureSwizzle, 4> swizzle{ // 4
|
||||
TextureSwizzle::CHANNEL_0,
|
||||
TextureSwizzle::CHANNEL_1,
|
||||
TextureSwizzle::CHANNEL_2,
|
||||
TextureSwizzle::CHANNEL_3
|
||||
};
|
||||
};
|
||||
|
||||
struct SamplerWithAnisotropyWorkaround {
|
||||
uint16_t target; // 2 (GLenum)
|
||||
bool external = false; // 1
|
||||
bool reserved = false; // 1
|
||||
GLuint id = 0; // 4
|
||||
TextureHandle handle; // 4
|
||||
GLuint sampler = 0; // 4
|
||||
Handle<GLTextureRef> ref; // 4
|
||||
math::half anisotropy = 1.0f; // 2
|
||||
int8_t baseLevel = 0x7f; // 1
|
||||
int8_t maxLevel = -1; // 1
|
||||
std::array<TextureSwizzle, 4> swizzle{ // 4
|
||||
TextureSwizzle::CHANNEL_0,
|
||||
TextureSwizzle::CHANNEL_1,
|
||||
TextureSwizzle::CHANNEL_2,
|
||||
TextureSwizzle::CHANNEL_3
|
||||
};
|
||||
};
|
||||
|
||||
// A sampler descriptor for ES2
|
||||
struct SamplerGLES2 {
|
||||
uint16_t target; // 2 (GLenum)
|
||||
bool external = false; // 1
|
||||
bool reserved = false; // 1
|
||||
GLuint id = 0; // 4
|
||||
TextureHandle handle; // 4
|
||||
SamplerParams params{}; // 4
|
||||
float anisotropy = 1.0f; // 4
|
||||
};
|
||||
@@ -165,9 +138,8 @@ private:
|
||||
};
|
||||
static_assert(sizeof(Descriptor) <= 32);
|
||||
|
||||
template<typename T>
|
||||
static void updateTextureView(OpenGLContext& gl,
|
||||
HandleAllocatorGL& handleAllocator, GLuint unit, T const& desc) noexcept;
|
||||
HandleAllocatorGL& handleAllocator, GLuint unit, GLTexture const* t) noexcept;
|
||||
|
||||
utils::FixedCapacityVector<Descriptor> descriptors; // 16
|
||||
utils::bitset64 dynamicBuffers; // 8
|
||||
|
||||
@@ -643,6 +643,25 @@ void OpenGLDriver::createVertexBufferInfoR(
|
||||
AttributeArray attributes) {
|
||||
DEBUG_MARKER()
|
||||
construct<GLVertexBufferInfo>(vbih, bufferCount, attributeCount, attributes);
|
||||
|
||||
// test ----
|
||||
int16_t returned_value = handle_set_value<GLVertexBufferInfo*>(vbih, 90);
|
||||
uint8_t age = (uint8_t) (returned_value >> 8);
|
||||
uint8_t test_value = (returned_value & 0xff);
|
||||
switch (test_value) {
|
||||
case -2:
|
||||
case -1:
|
||||
case 0:
|
||||
utils::slog.w << "@@@ createVertexBufferInfoR: unexpected result, age:" << (int) age
|
||||
<< ", test_value:" << (int) test_value << utils::io::endl;
|
||||
break;
|
||||
default:
|
||||
FILAMENT_CHECK_POSTCONDITION(test_value == 1)
|
||||
<< "@@@ createVertexBufferInfoR: shouldn't happen, age:" << (int) age
|
||||
<< ", test_value:" << (int) test_value << utils::io::endl;
|
||||
break;
|
||||
}
|
||||
//----------
|
||||
}
|
||||
|
||||
void OpenGLDriver::createVertexBufferR(
|
||||
@@ -761,6 +780,25 @@ void OpenGLDriver::createProgramR(Handle<HwProgram> ph, Program&& program) {
|
||||
|
||||
construct<OpenGLProgram>(ph, *this, std::move(program));
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// test ----
|
||||
int16_t returned_value = handle_set_value<OpenGLProgram*>(ph, 100);
|
||||
uint8_t age = (uint8_t) (returned_value >> 8);
|
||||
uint8_t test_value = (returned_value & 0xff);
|
||||
switch (test_value) {
|
||||
case -2:
|
||||
case -1:
|
||||
case 0:
|
||||
utils::slog.w << "@@@ createProgramR: unexpected result, age:" << (int)age << ", test_value:" << (int)test_value
|
||||
<< utils::io::endl;
|
||||
break;
|
||||
default:
|
||||
FILAMENT_CHECK_POSTCONDITION(test_value == 1)
|
||||
<< "@@@ createProgramR: shouldn't happen, age:" << (int)age
|
||||
<< ", test_value:" << (int)test_value << utils::io::endl;
|
||||
break;
|
||||
}
|
||||
//----------
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
@@ -1918,6 +1956,25 @@ void OpenGLDriver::destroyRenderPrimitive(Handle<HwRenderPrimitive> rph) {
|
||||
void OpenGLDriver::destroyProgram(Handle<HwProgram> ph) {
|
||||
DEBUG_MARKER()
|
||||
if (ph) {
|
||||
// test ----
|
||||
int16_t returned_value = handle_set_value<OpenGLProgram*>(ph, 101);
|
||||
uint8_t age = (uint8_t) (returned_value >> 8);
|
||||
uint8_t test_value = (returned_value & 0xff);
|
||||
switch (test_value) {
|
||||
case -2:
|
||||
case -1:
|
||||
case 0:
|
||||
utils::slog.w << "@@@ destroyProgram: unexpected result, age:" << (int) age
|
||||
<< ", test_value:" << (int) test_value << utils::io::endl;
|
||||
break;
|
||||
default:
|
||||
FILAMENT_CHECK_POSTCONDITION(test_value == 1)
|
||||
<< "@@@ destroyProgram: shouldn't happen, age:" << (int) age
|
||||
<< ", test_value:" << (int) test_value << utils::io::endl;
|
||||
break;
|
||||
}
|
||||
//----------
|
||||
|
||||
OpenGLProgram* p = handle_cast<OpenGLProgram*>(ph);
|
||||
destruct(ph, p);
|
||||
}
|
||||
@@ -2531,10 +2588,28 @@ void OpenGLDriver::makeCurrent(Handle<HwSwapChain> schDraw, Handle<HwSwapChain>
|
||||
|
||||
mPlatform.makeCurrent(scDraw->swapChain, scRead->swapChain,
|
||||
[this]() {
|
||||
for (auto t: mTexturesWithStreamsAttached) {
|
||||
if (t->hwStream->streamType == StreamType::NATIVE) {
|
||||
mPlatform.detach(t->hwStream->stream);
|
||||
}
|
||||
}
|
||||
// OpenGL context is about to change, unbind everything
|
||||
mContext.unbindEverything();
|
||||
},
|
||||
[this](size_t index) {
|
||||
for (auto t: mTexturesWithStreamsAttached) {
|
||||
if (t->hwStream->streamType == StreamType::NATIVE) {
|
||||
glGenTextures(1, &t->gl.id);
|
||||
mPlatform.attach(t->hwStream->stream, t->gl.id);
|
||||
mContext.updateTexImage(GL_TEXTURE_EXTERNAL_OES, t->gl.id);
|
||||
}
|
||||
}
|
||||
|
||||
// force invalidation of all bound descriptor sets
|
||||
decltype(mInvalidDescriptorSetBindings) changed;
|
||||
changed.setValue((1 << MAX_DESCRIPTOR_SET_COUNT) - 1);
|
||||
mInvalidDescriptorSetBindings |= changed;
|
||||
|
||||
// OpenGL context has changed, resynchronize the state with the cache
|
||||
mContext.synchronizeStateAndCache(index);
|
||||
slog.d << "*** OpenGL context change : " << (index ? "protected" : "default") << io::endl;
|
||||
@@ -3725,8 +3800,7 @@ void OpenGLDriver::updateDescriptorSetTexture(
|
||||
TextureHandle th,
|
||||
SamplerParams params) {
|
||||
GLDescriptorSet* ds = handle_cast<GLDescriptorSet*>(dsh);
|
||||
GLTexture* t = th ? handle_cast<GLTexture*>(th) : nullptr;
|
||||
ds->update(mContext, binding, t, params);
|
||||
ds->update(mContext, mHandleAllocator, binding, th, params);
|
||||
}
|
||||
|
||||
void OpenGLDriver::flush(int) {
|
||||
@@ -4049,6 +4123,24 @@ void OpenGLDriver::bindPipeline(PipelineState const& state) {
|
||||
setRasterState(state.rasterState);
|
||||
setStencilState(state.stencilState);
|
||||
gl.polygonOffset(state.polygonOffset.slope, state.polygonOffset.constant);
|
||||
// test ----
|
||||
Handle<HwProgram> pro = state.program;
|
||||
int16_t returned_value = handle_get_value<OpenGLProgram*>(pro);
|
||||
uint8_t age = (uint8_t)(returned_value >> 8);
|
||||
uint8_t test_value = (returned_value & 0xff);
|
||||
switch (test_value) {
|
||||
case -2:
|
||||
case -1:
|
||||
case 0:
|
||||
utils::slog.w << "@@@ bindPipeline: unexpected result, age:" << (int)age << ", test_value:" << (int)test_value << utils::io::endl;
|
||||
break;
|
||||
default:
|
||||
if (test_value != 100) {
|
||||
utils::slog.w << "@@@ bindPipeline: program is not valid OpenGLProgram, age:" << (int)age << ", test_value:" << (int)test_value << utils::io::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
//----------
|
||||
OpenGLProgram* const p = handle_cast<OpenGLProgram*>(state.program);
|
||||
mValidProgram = useProgram(p);
|
||||
(*mCurrentPushConstants) = p->getPushConstants();
|
||||
|
||||
@@ -282,6 +282,20 @@ private:
|
||||
return mHandleAllocator.handle_cast<Dp, B>(handle);
|
||||
}
|
||||
|
||||
template<typename Dp, typename B>
|
||||
std::enable_if_t<std::is_pointer_v<Dp> && std::is_base_of_v<B, std::remove_pointer_t<Dp>>,
|
||||
int16_t>
|
||||
handle_set_value(Handle<B>& handle, uint8_t v) {
|
||||
return mHandleAllocator.handle_set_value<Dp, B>(handle, v);
|
||||
}
|
||||
|
||||
template<typename Dp, typename B>
|
||||
std::enable_if_t<std::is_pointer_v<Dp> && std::is_base_of_v<B, std::remove_pointer_t<Dp>>,
|
||||
int16_t>
|
||||
handle_get_value(Handle<B>& handle) {
|
||||
return mHandleAllocator.handle_get_value<Dp, B>(handle);
|
||||
}
|
||||
|
||||
friend class OpenGLProgram;
|
||||
friend class ShaderCompilerService;
|
||||
|
||||
|
||||
@@ -733,6 +733,7 @@ void WebGPUDriver::beginRenderPass(Handle<HwRenderTarget> rth, RenderPassParams
|
||||
// TODO: Consider colorInfos[i].level and colorInfos[i].layer for view creation
|
||||
// if WGPUTexture::getTextureView() isn't sufficient or needs parameters.
|
||||
customColorViews[customColorViewCount++] = hwTexture->getTextureView();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1076,51 +1077,51 @@ wgpu::Sampler WebGPUDriver::makeSampler(SamplerParams const& params) {
|
||||
desc.addressModeU = fWrapModeToWAddressMode(params.wrapS);
|
||||
desc.addressModeV = fWrapModeToWAddressMode(params.wrapR);
|
||||
desc.addressModeW = fWrapModeToWAddressMode(params.wrapT);
|
||||
|
||||
switch (params.filterMag) {
|
||||
case SamplerMagFilter::NEAREST: {
|
||||
desc.magFilter = wgpu::FilterMode::Nearest;
|
||||
break;
|
||||
}
|
||||
case SamplerMagFilter::LINEAR: {
|
||||
desc.magFilter = wgpu::FilterMode::Linear;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (params.filterMin) {
|
||||
case SamplerMinFilter::NEAREST: {
|
||||
desc.minFilter = wgpu::FilterMode::Nearest;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Undefined;
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::LINEAR: {
|
||||
desc.minFilter = wgpu::FilterMode::Linear;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Undefined;
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::NEAREST_MIPMAP_NEAREST: {
|
||||
desc.minFilter = wgpu::FilterMode::Nearest;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Nearest;
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::LINEAR_MIPMAP_NEAREST: {
|
||||
desc.minFilter = wgpu::FilterMode::Linear;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Nearest;
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::NEAREST_MIPMAP_LINEAR: {
|
||||
desc.minFilter = wgpu::FilterMode::Nearest;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Linear;
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::LINEAR_MIPMAP_LINEAR: {
|
||||
desc.minFilter = wgpu::FilterMode::Linear;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Linear;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (params.compareMode == SamplerCompareMode::COMPARE_TO_TEXTURE) {
|
||||
switch (params.filterMag) {
|
||||
case SamplerMagFilter::NEAREST: {
|
||||
desc.magFilter = wgpu::FilterMode::Nearest;
|
||||
break;
|
||||
}
|
||||
case SamplerMagFilter::LINEAR: {
|
||||
desc.magFilter = wgpu::FilterMode::Linear;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (params.filterMin) {
|
||||
case SamplerMinFilter::NEAREST: {
|
||||
desc.minFilter = wgpu::FilterMode::Nearest;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Undefined;
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::LINEAR: {
|
||||
desc.minFilter = wgpu::FilterMode::Linear;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Undefined;
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::NEAREST_MIPMAP_NEAREST: {
|
||||
desc.minFilter = wgpu::FilterMode::Nearest;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Nearest;
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::LINEAR_MIPMAP_NEAREST: {
|
||||
desc.minFilter = wgpu::FilterMode::Linear;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Nearest;
|
||||
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::NEAREST_MIPMAP_LINEAR: {
|
||||
desc.minFilter = wgpu::FilterMode::Nearest;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Linear;
|
||||
|
||||
break;
|
||||
}
|
||||
case SamplerMinFilter::LINEAR_MIPMAP_LINEAR: {
|
||||
desc.minFilter = wgpu::FilterMode::Linear;
|
||||
desc.mipmapFilter = wgpu::MipmapFilterMode::Linear;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (params.compareFunc) {
|
||||
case SamplerCompareFunc::LE: {
|
||||
desc.compare = wgpu::CompareFunction::LessEqual;
|
||||
|
||||
@@ -387,9 +387,10 @@ WebGPUDescriptorSetLayout::WebGPUDescriptorSetLayout(DescriptorSetLayout const&
|
||||
// TODO: Set once we have the filtering values
|
||||
if (isDepthDescriptor(fEntry.type)) {
|
||||
samplerEntry.sampler.type = wgpu::SamplerBindingType::Comparison;
|
||||
} else if (isIntDescriptor(fEntry.type)) {
|
||||
samplerEntry.sampler.type = wgpu::SamplerBindingType::NonFiltering;
|
||||
} else {
|
||||
samplerEntry.sampler.type =
|
||||
wgpu::SamplerBindingType::NonFiltering;
|
||||
samplerEntry.sampler.type = wgpu::SamplerBindingType::Filtering;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -421,7 +422,7 @@ WebGPUDescriptorSetLayout::WebGPUDescriptorSetLayout(DescriptorSetLayout const&
|
||||
else if (isFloatDescriptor(fEntry.type))
|
||||
{
|
||||
// TODO: Set once we have the filtering values
|
||||
wEntry.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;
|
||||
wEntry.texture.sampleType = wgpu::TextureSampleType::Float;
|
||||
}
|
||||
else if (isIntDescriptor(fEntry.type))
|
||||
{
|
||||
|
||||
@@ -53,8 +53,10 @@ namespace filament::backend {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr std::array REQUIRED_FEATURES = {
|
||||
wgpu::FeatureName::TransientAttachments };
|
||||
constexpr std::array REQUIRED_FEATURES = { wgpu::FeatureName::TransientAttachments,
|
||||
/*To make filtering assumptions like we want while waiting for Filament to provide that info,
|
||||
float 32 needs to be filterable*/
|
||||
wgpu::FeatureName::Float32Filterable };
|
||||
|
||||
constexpr std::array OPTIONAL_FEATURES = {
|
||||
wgpu::FeatureName::DepthClipControl,
|
||||
|
||||
@@ -147,8 +147,7 @@ FMaterialInstance::FMaterialInstance(FEngine& engine,
|
||||
FEngine::DriverApi& driver = engine.getDriverApi();
|
||||
FMaterial const* const material = other->getMaterial();
|
||||
|
||||
size_t const uboSize = std::max(size_t(16), material->getUniformInterfaceBlock().getSize());
|
||||
mUniforms = UniformBuffer(uboSize);
|
||||
mUniforms.setUniforms(other->getUniformBuffer());
|
||||
mUbHandle = driver.createBufferObject(mUniforms.getSize(),
|
||||
BufferObjectBinding::UNIFORM, BufferUsage::DYNAMIC);
|
||||
driver.setDebugTag(mUbHandle.getId(), material->getName());
|
||||
|
||||
@@ -116,7 +116,7 @@ void groundTruthAmbientOcclusion(out float obscurance, out vec3 bentNormal,
|
||||
|
||||
highp vec3 sampleDelta0 = (samplePos0 - origin);
|
||||
highp vec3 sampleDelta1 = (samplePos1 - origin);
|
||||
vec2 sqSampleDist = vec2(dot(sampleDelta0, sampleDelta0), dot(sampleDelta1, sampleDelta1));
|
||||
highp vec2 sqSampleDist = vec2(dot(sampleDelta0, sampleDelta0), dot(sampleDelta1, sampleDelta1));
|
||||
vec2 invSampleDist = rsqrt(sqSampleDist);
|
||||
|
||||
// Use the view space radius to calculate the fallOff
|
||||
|
||||
Reference in New Issue
Block a user