mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-03 11:46:09 +00:00
Only mark objects as cached right before inserting into the cache
This fixes bugs where we try to uncache objects that fail creation. Bug: dawn:249 Change-Id: Ic60b3ce702dfdda18baa6d263911885a43d3cda7 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/12820 Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
fe221ac089
commit
84bcf44fae
2
BUILD.gn
2
BUILD.gn
@ -156,6 +156,8 @@ source_set("libdawn_native_sources") {
|
|||||||
"src/dawn_native/BuddyMemoryAllocator.h",
|
"src/dawn_native/BuddyMemoryAllocator.h",
|
||||||
"src/dawn_native/Buffer.cpp",
|
"src/dawn_native/Buffer.cpp",
|
||||||
"src/dawn_native/Buffer.h",
|
"src/dawn_native/Buffer.h",
|
||||||
|
"src/dawn_native/CachedObject.cpp",
|
||||||
|
"src/dawn_native/CachedObject.h",
|
||||||
"src/dawn_native/CommandAllocator.cpp",
|
"src/dawn_native/CommandAllocator.cpp",
|
||||||
"src/dawn_native/CommandAllocator.h",
|
"src/dawn_native/CommandAllocator.h",
|
||||||
"src/dawn_native/CommandBuffer.cpp",
|
"src/dawn_native/CommandBuffer.cpp",
|
||||||
|
@ -116,11 +116,11 @@ namespace dawn_native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AttachmentState::AttachmentState(DeviceBase* device, const AttachmentStateBlueprint& blueprint)
|
AttachmentState::AttachmentState(DeviceBase* device, const AttachmentStateBlueprint& blueprint)
|
||||||
: AttachmentStateBlueprint(blueprint), RefCounted(), mDevice(device) {
|
: AttachmentStateBlueprint(blueprint), CachedObject(device) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AttachmentState::~AttachmentState() {
|
AttachmentState::~AttachmentState() {
|
||||||
mDevice->UncacheAttachmentState(this);
|
GetDevice()->UncacheAttachmentState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::bitset<kMaxColorAttachments> AttachmentState::GetColorAttachmentsMask() const {
|
std::bitset<kMaxColorAttachments> AttachmentState::GetColorAttachmentsMask() const {
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#define DAWNNATIVE_ATTACHMENTSTATE_H_
|
#define DAWNNATIVE_ATTACHMENTSTATE_H_
|
||||||
|
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
#include "dawn_native/RefCounted.h"
|
#include "dawn_native/CachedObject.h"
|
||||||
|
|
||||||
#include "dawn_native/dawn_platform.h"
|
#include "dawn_native/dawn_platform.h"
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ namespace dawn_native {
|
|||||||
uint32_t mSampleCount = 0;
|
uint32_t mSampleCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AttachmentState : public AttachmentStateBlueprint, public RefCounted {
|
class AttachmentState : public AttachmentStateBlueprint, public CachedObject {
|
||||||
public:
|
public:
|
||||||
AttachmentState(DeviceBase* device, const AttachmentStateBlueprint& blueprint);
|
AttachmentState(DeviceBase* device, const AttachmentStateBlueprint& blueprint);
|
||||||
~AttachmentState() override;
|
~AttachmentState() override;
|
||||||
@ -66,9 +66,6 @@ namespace dawn_native {
|
|||||||
bool HasDepthStencilAttachment() const;
|
bool HasDepthStencilAttachment() const;
|
||||||
wgpu::TextureFormat GetDepthStencilFormat() const;
|
wgpu::TextureFormat GetDepthStencilFormat() const;
|
||||||
uint32_t GetSampleCount() const;
|
uint32_t GetSampleCount() const;
|
||||||
|
|
||||||
private:
|
|
||||||
DeviceBase* mDevice;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
@ -129,9 +129,8 @@ namespace dawn_native {
|
|||||||
// BindGroupLayoutBase
|
// BindGroupLayoutBase
|
||||||
|
|
||||||
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device,
|
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device,
|
||||||
const BindGroupLayoutDescriptor* descriptor,
|
const BindGroupLayoutDescriptor* descriptor)
|
||||||
bool blueprint)
|
: CachedObject(device) {
|
||||||
: ObjectBase(device), mIsBlueprint(blueprint) {
|
|
||||||
for (uint32_t i = 0; i < descriptor->bindingCount; ++i) {
|
for (uint32_t i = 0; i < descriptor->bindingCount; ++i) {
|
||||||
auto& binding = descriptor->bindings[i];
|
auto& binding = descriptor->bindings[i];
|
||||||
|
|
||||||
@ -171,12 +170,12 @@ namespace dawn_native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||||
: ObjectBase(device, tag), mIsBlueprint(true) {
|
: CachedObject(device, tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BindGroupLayoutBase::~BindGroupLayoutBase() {
|
BindGroupLayoutBase::~BindGroupLayoutBase() {
|
||||||
// Do not uncache the actual cached object if we are a blueprint
|
// Do not uncache the actual cached object if we are a blueprint
|
||||||
if (!mIsBlueprint && !IsError()) {
|
if (IsCachedReference()) {
|
||||||
GetDevice()->UncacheBindGroupLayout(this);
|
GetDevice()->UncacheBindGroupLayout(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
#define DAWNNATIVE_BINDGROUPLAYOUT_H_
|
#define DAWNNATIVE_BINDGROUPLAYOUT_H_
|
||||||
|
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
|
#include "dawn_native/CachedObject.h"
|
||||||
#include "dawn_native/Error.h"
|
#include "dawn_native/Error.h"
|
||||||
#include "dawn_native/Forward.h"
|
#include "dawn_native/Forward.h"
|
||||||
#include "dawn_native/ObjectBase.h"
|
|
||||||
|
|
||||||
#include "dawn_native/dawn_platform.h"
|
#include "dawn_native/dawn_platform.h"
|
||||||
|
|
||||||
@ -30,11 +30,9 @@ namespace dawn_native {
|
|||||||
MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase*,
|
MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase*,
|
||||||
const BindGroupLayoutDescriptor* descriptor);
|
const BindGroupLayoutDescriptor* descriptor);
|
||||||
|
|
||||||
class BindGroupLayoutBase : public ObjectBase {
|
class BindGroupLayoutBase : public CachedObject {
|
||||||
public:
|
public:
|
||||||
BindGroupLayoutBase(DeviceBase* device,
|
BindGroupLayoutBase(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor);
|
||||||
const BindGroupLayoutDescriptor* descriptor,
|
|
||||||
bool blueprint = false);
|
|
||||||
~BindGroupLayoutBase() override;
|
~BindGroupLayoutBase() override;
|
||||||
|
|
||||||
static BindGroupLayoutBase* MakeError(DeviceBase* device);
|
static BindGroupLayoutBase* MakeError(DeviceBase* device);
|
||||||
@ -66,7 +64,6 @@ namespace dawn_native {
|
|||||||
BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
||||||
|
|
||||||
LayoutBindingInfo mBindingInfo;
|
LayoutBindingInfo mBindingInfo;
|
||||||
bool mIsBlueprint = false;
|
|
||||||
uint32_t mDynamicUniformBufferCount = 0;
|
uint32_t mDynamicUniformBufferCount = 0;
|
||||||
uint32_t mDynamicStorageBufferCount = 0;
|
uint32_t mDynamicStorageBufferCount = 0;
|
||||||
};
|
};
|
||||||
|
27
src/dawn_native/CachedObject.cpp
Normal file
27
src/dawn_native/CachedObject.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2019 The Dawn Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "dawn_native/CachedObject.h"
|
||||||
|
|
||||||
|
namespace dawn_native {
|
||||||
|
|
||||||
|
bool CachedObject::IsCachedReference() const {
|
||||||
|
return mIsCachedReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CachedObject::SetIsCachedReference() {
|
||||||
|
mIsCachedReference = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dawn_native
|
41
src/dawn_native/CachedObject.h
Normal file
41
src/dawn_native/CachedObject.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2019 The Dawn Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef DAWNNATIVE_CACHED_OBJECT_H_
|
||||||
|
#define DAWNNATIVE_CACHED_OBJECT_H_
|
||||||
|
|
||||||
|
#include "dawn_native/ObjectBase.h"
|
||||||
|
|
||||||
|
namespace dawn_native {
|
||||||
|
|
||||||
|
// Some objects are cached so that instead of creating new duplicate objects,
|
||||||
|
// we increase the refcount of an existing object.
|
||||||
|
// When an object is successfully created, the device should call
|
||||||
|
// SetIsCachedReference() and insert the object into the cache.
|
||||||
|
class CachedObject : public ObjectBase {
|
||||||
|
public:
|
||||||
|
using ObjectBase::ObjectBase;
|
||||||
|
|
||||||
|
bool IsCachedReference() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class DeviceBase;
|
||||||
|
void SetIsCachedReference();
|
||||||
|
|
||||||
|
bool mIsCachedReference = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dawn_native
|
||||||
|
|
||||||
|
#endif // DAWNNATIVE_CACHED_OBJECT_H_
|
@ -34,12 +34,10 @@ namespace dawn_native {
|
|||||||
// ComputePipelineBase
|
// ComputePipelineBase
|
||||||
|
|
||||||
ComputePipelineBase::ComputePipelineBase(DeviceBase* device,
|
ComputePipelineBase::ComputePipelineBase(DeviceBase* device,
|
||||||
const ComputePipelineDescriptor* descriptor,
|
const ComputePipelineDescriptor* descriptor)
|
||||||
bool blueprint)
|
|
||||||
: PipelineBase(device, descriptor->layout, wgpu::ShaderStage::Compute),
|
: PipelineBase(device, descriptor->layout, wgpu::ShaderStage::Compute),
|
||||||
mModule(descriptor->computeStage.module),
|
mModule(descriptor->computeStage.module),
|
||||||
mEntryPoint(descriptor->computeStage.entryPoint),
|
mEntryPoint(descriptor->computeStage.entryPoint) {
|
||||||
mIsBlueprint(blueprint) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ComputePipelineBase::ComputePipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
ComputePipelineBase::ComputePipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||||
@ -48,7 +46,7 @@ namespace dawn_native {
|
|||||||
|
|
||||||
ComputePipelineBase::~ComputePipelineBase() {
|
ComputePipelineBase::~ComputePipelineBase() {
|
||||||
// Do not uncache the actual cached object if we are a blueprint
|
// Do not uncache the actual cached object if we are a blueprint
|
||||||
if (!mIsBlueprint && !IsError()) {
|
if (IsCachedReference()) {
|
||||||
GetDevice()->UncacheComputePipeline(this);
|
GetDevice()->UncacheComputePipeline(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,7 @@ namespace dawn_native {
|
|||||||
|
|
||||||
class ComputePipelineBase : public PipelineBase {
|
class ComputePipelineBase : public PipelineBase {
|
||||||
public:
|
public:
|
||||||
ComputePipelineBase(DeviceBase* device,
|
ComputePipelineBase(DeviceBase* device, const ComputePipelineDescriptor* descriptor);
|
||||||
const ComputePipelineDescriptor* descriptor,
|
|
||||||
bool blueprint = false);
|
|
||||||
~ComputePipelineBase() override;
|
~ComputePipelineBase() override;
|
||||||
|
|
||||||
static ComputePipelineBase* MakeError(DeviceBase* device);
|
static ComputePipelineBase* MakeError(DeviceBase* device);
|
||||||
@ -47,7 +45,6 @@ namespace dawn_native {
|
|||||||
// TODO(cwallez@chromium.org): Store a crypto hash of the module instead.
|
// TODO(cwallez@chromium.org): Store a crypto hash of the module instead.
|
||||||
Ref<ShaderModuleBase> mModule;
|
Ref<ShaderModuleBase> mModule;
|
||||||
std::string mEntryPoint;
|
std::string mEntryPoint;
|
||||||
bool mIsBlueprint = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
@ -191,7 +191,7 @@ namespace dawn_native {
|
|||||||
|
|
||||||
ResultOrError<BindGroupLayoutBase*> DeviceBase::GetOrCreateBindGroupLayout(
|
ResultOrError<BindGroupLayoutBase*> DeviceBase::GetOrCreateBindGroupLayout(
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
BindGroupLayoutBase blueprint(this, descriptor, true);
|
BindGroupLayoutBase blueprint(this, descriptor);
|
||||||
|
|
||||||
auto iter = mCaches->bindGroupLayouts.find(&blueprint);
|
auto iter = mCaches->bindGroupLayouts.find(&blueprint);
|
||||||
if (iter != mCaches->bindGroupLayouts.end()) {
|
if (iter != mCaches->bindGroupLayouts.end()) {
|
||||||
@ -201,18 +201,20 @@ namespace dawn_native {
|
|||||||
|
|
||||||
BindGroupLayoutBase* backendObj;
|
BindGroupLayoutBase* backendObj;
|
||||||
DAWN_TRY_ASSIGN(backendObj, CreateBindGroupLayoutImpl(descriptor));
|
DAWN_TRY_ASSIGN(backendObj, CreateBindGroupLayoutImpl(descriptor));
|
||||||
|
backendObj->SetIsCachedReference();
|
||||||
mCaches->bindGroupLayouts.insert(backendObj);
|
mCaches->bindGroupLayouts.insert(backendObj);
|
||||||
return backendObj;
|
return backendObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::UncacheBindGroupLayout(BindGroupLayoutBase* obj) {
|
void DeviceBase::UncacheBindGroupLayout(BindGroupLayoutBase* obj) {
|
||||||
|
ASSERT(obj->IsCachedReference());
|
||||||
size_t removedCount = mCaches->bindGroupLayouts.erase(obj);
|
size_t removedCount = mCaches->bindGroupLayouts.erase(obj);
|
||||||
ASSERT(removedCount == 1);
|
ASSERT(removedCount == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<ComputePipelineBase*> DeviceBase::GetOrCreateComputePipeline(
|
ResultOrError<ComputePipelineBase*> DeviceBase::GetOrCreateComputePipeline(
|
||||||
const ComputePipelineDescriptor* descriptor) {
|
const ComputePipelineDescriptor* descriptor) {
|
||||||
ComputePipelineBase blueprint(this, descriptor, true);
|
ComputePipelineBase blueprint(this, descriptor);
|
||||||
|
|
||||||
auto iter = mCaches->computePipelines.find(&blueprint);
|
auto iter = mCaches->computePipelines.find(&blueprint);
|
||||||
if (iter != mCaches->computePipelines.end()) {
|
if (iter != mCaches->computePipelines.end()) {
|
||||||
@ -222,18 +224,20 @@ namespace dawn_native {
|
|||||||
|
|
||||||
ComputePipelineBase* backendObj;
|
ComputePipelineBase* backendObj;
|
||||||
DAWN_TRY_ASSIGN(backendObj, CreateComputePipelineImpl(descriptor));
|
DAWN_TRY_ASSIGN(backendObj, CreateComputePipelineImpl(descriptor));
|
||||||
|
backendObj->SetIsCachedReference();
|
||||||
mCaches->computePipelines.insert(backendObj);
|
mCaches->computePipelines.insert(backendObj);
|
||||||
return backendObj;
|
return backendObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::UncacheComputePipeline(ComputePipelineBase* obj) {
|
void DeviceBase::UncacheComputePipeline(ComputePipelineBase* obj) {
|
||||||
|
ASSERT(obj->IsCachedReference());
|
||||||
size_t removedCount = mCaches->computePipelines.erase(obj);
|
size_t removedCount = mCaches->computePipelines.erase(obj);
|
||||||
ASSERT(removedCount == 1);
|
ASSERT(removedCount == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<PipelineLayoutBase*> DeviceBase::GetOrCreatePipelineLayout(
|
ResultOrError<PipelineLayoutBase*> DeviceBase::GetOrCreatePipelineLayout(
|
||||||
const PipelineLayoutDescriptor* descriptor) {
|
const PipelineLayoutDescriptor* descriptor) {
|
||||||
PipelineLayoutBase blueprint(this, descriptor, true);
|
PipelineLayoutBase blueprint(this, descriptor);
|
||||||
|
|
||||||
auto iter = mCaches->pipelineLayouts.find(&blueprint);
|
auto iter = mCaches->pipelineLayouts.find(&blueprint);
|
||||||
if (iter != mCaches->pipelineLayouts.end()) {
|
if (iter != mCaches->pipelineLayouts.end()) {
|
||||||
@ -243,18 +247,20 @@ namespace dawn_native {
|
|||||||
|
|
||||||
PipelineLayoutBase* backendObj;
|
PipelineLayoutBase* backendObj;
|
||||||
DAWN_TRY_ASSIGN(backendObj, CreatePipelineLayoutImpl(descriptor));
|
DAWN_TRY_ASSIGN(backendObj, CreatePipelineLayoutImpl(descriptor));
|
||||||
|
backendObj->SetIsCachedReference();
|
||||||
mCaches->pipelineLayouts.insert(backendObj);
|
mCaches->pipelineLayouts.insert(backendObj);
|
||||||
return backendObj;
|
return backendObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::UncachePipelineLayout(PipelineLayoutBase* obj) {
|
void DeviceBase::UncachePipelineLayout(PipelineLayoutBase* obj) {
|
||||||
|
ASSERT(obj->IsCachedReference());
|
||||||
size_t removedCount = mCaches->pipelineLayouts.erase(obj);
|
size_t removedCount = mCaches->pipelineLayouts.erase(obj);
|
||||||
ASSERT(removedCount == 1);
|
ASSERT(removedCount == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<RenderPipelineBase*> DeviceBase::GetOrCreateRenderPipeline(
|
ResultOrError<RenderPipelineBase*> DeviceBase::GetOrCreateRenderPipeline(
|
||||||
const RenderPipelineDescriptor* descriptor) {
|
const RenderPipelineDescriptor* descriptor) {
|
||||||
RenderPipelineBase blueprint(this, descriptor, true);
|
RenderPipelineBase blueprint(this, descriptor);
|
||||||
|
|
||||||
auto iter = mCaches->renderPipelines.find(&blueprint);
|
auto iter = mCaches->renderPipelines.find(&blueprint);
|
||||||
if (iter != mCaches->renderPipelines.end()) {
|
if (iter != mCaches->renderPipelines.end()) {
|
||||||
@ -264,18 +270,20 @@ namespace dawn_native {
|
|||||||
|
|
||||||
RenderPipelineBase* backendObj;
|
RenderPipelineBase* backendObj;
|
||||||
DAWN_TRY_ASSIGN(backendObj, CreateRenderPipelineImpl(descriptor));
|
DAWN_TRY_ASSIGN(backendObj, CreateRenderPipelineImpl(descriptor));
|
||||||
|
backendObj->SetIsCachedReference();
|
||||||
mCaches->renderPipelines.insert(backendObj);
|
mCaches->renderPipelines.insert(backendObj);
|
||||||
return backendObj;
|
return backendObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::UncacheRenderPipeline(RenderPipelineBase* obj) {
|
void DeviceBase::UncacheRenderPipeline(RenderPipelineBase* obj) {
|
||||||
|
ASSERT(obj->IsCachedReference());
|
||||||
size_t removedCount = mCaches->renderPipelines.erase(obj);
|
size_t removedCount = mCaches->renderPipelines.erase(obj);
|
||||||
ASSERT(removedCount == 1);
|
ASSERT(removedCount == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<SamplerBase*> DeviceBase::GetOrCreateSampler(
|
ResultOrError<SamplerBase*> DeviceBase::GetOrCreateSampler(
|
||||||
const SamplerDescriptor* descriptor) {
|
const SamplerDescriptor* descriptor) {
|
||||||
SamplerBase blueprint(this, descriptor, true);
|
SamplerBase blueprint(this, descriptor);
|
||||||
|
|
||||||
auto iter = mCaches->samplers.find(&blueprint);
|
auto iter = mCaches->samplers.find(&blueprint);
|
||||||
if (iter != mCaches->samplers.end()) {
|
if (iter != mCaches->samplers.end()) {
|
||||||
@ -285,18 +293,20 @@ namespace dawn_native {
|
|||||||
|
|
||||||
SamplerBase* backendObj;
|
SamplerBase* backendObj;
|
||||||
DAWN_TRY_ASSIGN(backendObj, CreateSamplerImpl(descriptor));
|
DAWN_TRY_ASSIGN(backendObj, CreateSamplerImpl(descriptor));
|
||||||
|
backendObj->SetIsCachedReference();
|
||||||
mCaches->samplers.insert(backendObj);
|
mCaches->samplers.insert(backendObj);
|
||||||
return backendObj;
|
return backendObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::UncacheSampler(SamplerBase* obj) {
|
void DeviceBase::UncacheSampler(SamplerBase* obj) {
|
||||||
|
ASSERT(obj->IsCachedReference());
|
||||||
size_t removedCount = mCaches->samplers.erase(obj);
|
size_t removedCount = mCaches->samplers.erase(obj);
|
||||||
ASSERT(removedCount == 1);
|
ASSERT(removedCount == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<ShaderModuleBase*> DeviceBase::GetOrCreateShaderModule(
|
ResultOrError<ShaderModuleBase*> DeviceBase::GetOrCreateShaderModule(
|
||||||
const ShaderModuleDescriptor* descriptor) {
|
const ShaderModuleDescriptor* descriptor) {
|
||||||
ShaderModuleBase blueprint(this, descriptor, true);
|
ShaderModuleBase blueprint(this, descriptor);
|
||||||
|
|
||||||
auto iter = mCaches->shaderModules.find(&blueprint);
|
auto iter = mCaches->shaderModules.find(&blueprint);
|
||||||
if (iter != mCaches->shaderModules.end()) {
|
if (iter != mCaches->shaderModules.end()) {
|
||||||
@ -306,11 +316,13 @@ namespace dawn_native {
|
|||||||
|
|
||||||
ShaderModuleBase* backendObj;
|
ShaderModuleBase* backendObj;
|
||||||
DAWN_TRY_ASSIGN(backendObj, CreateShaderModuleImpl(descriptor));
|
DAWN_TRY_ASSIGN(backendObj, CreateShaderModuleImpl(descriptor));
|
||||||
|
backendObj->SetIsCachedReference();
|
||||||
mCaches->shaderModules.insert(backendObj);
|
mCaches->shaderModules.insert(backendObj);
|
||||||
return backendObj;
|
return backendObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::UncacheShaderModule(ShaderModuleBase* obj) {
|
void DeviceBase::UncacheShaderModule(ShaderModuleBase* obj) {
|
||||||
|
ASSERT(obj->IsCachedReference());
|
||||||
size_t removedCount = mCaches->shaderModules.erase(obj);
|
size_t removedCount = mCaches->shaderModules.erase(obj);
|
||||||
ASSERT(removedCount == 1);
|
ASSERT(removedCount == 1);
|
||||||
}
|
}
|
||||||
@ -323,6 +335,7 @@ namespace dawn_native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ref<AttachmentState> attachmentState = AcquireRef(new AttachmentState(this, *blueprint));
|
Ref<AttachmentState> attachmentState = AcquireRef(new AttachmentState(this, *blueprint));
|
||||||
|
attachmentState->SetIsCachedReference();
|
||||||
mCaches->attachmentStates.insert(attachmentState.Get());
|
mCaches->attachmentStates.insert(attachmentState.Get());
|
||||||
return attachmentState;
|
return attachmentState;
|
||||||
}
|
}
|
||||||
@ -346,6 +359,7 @@ namespace dawn_native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::UncacheAttachmentState(AttachmentState* obj) {
|
void DeviceBase::UncacheAttachmentState(AttachmentState* obj) {
|
||||||
|
ASSERT(obj->IsCachedReference());
|
||||||
size_t removedCount = mCaches->attachmentStates.erase(obj);
|
size_t removedCount = mCaches->attachmentStates.erase(obj);
|
||||||
ASSERT(removedCount == 1);
|
ASSERT(removedCount == 1);
|
||||||
}
|
}
|
||||||
|
@ -43,11 +43,11 @@ namespace dawn_native {
|
|||||||
PipelineBase::PipelineBase(DeviceBase* device,
|
PipelineBase::PipelineBase(DeviceBase* device,
|
||||||
PipelineLayoutBase* layout,
|
PipelineLayoutBase* layout,
|
||||||
wgpu::ShaderStage stages)
|
wgpu::ShaderStage stages)
|
||||||
: ObjectBase(device), mStageMask(stages), mLayout(layout) {
|
: CachedObject(device), mStageMask(stages), mLayout(layout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PipelineBase::PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
PipelineBase::PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||||
: ObjectBase(device, tag) {
|
: CachedObject(device, tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wgpu::ShaderStage PipelineBase::GetStageMask() const {
|
wgpu::ShaderStage PipelineBase::GetStageMask() const {
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef DAWNNATIVE_PIPELINE_H_
|
#ifndef DAWNNATIVE_PIPELINE_H_
|
||||||
#define DAWNNATIVE_PIPELINE_H_
|
#define DAWNNATIVE_PIPELINE_H_
|
||||||
|
|
||||||
|
#include "dawn_native/CachedObject.h"
|
||||||
#include "dawn_native/Forward.h"
|
#include "dawn_native/Forward.h"
|
||||||
#include "dawn_native/ObjectBase.h"
|
|
||||||
#include "dawn_native/PerStage.h"
|
#include "dawn_native/PerStage.h"
|
||||||
#include "dawn_native/PipelineLayout.h"
|
#include "dawn_native/PipelineLayout.h"
|
||||||
#include "dawn_native/ShaderModule.h"
|
#include "dawn_native/ShaderModule.h"
|
||||||
@ -33,7 +33,7 @@ namespace dawn_native {
|
|||||||
const PipelineLayoutBase* layout,
|
const PipelineLayoutBase* layout,
|
||||||
SingleShaderStage stage);
|
SingleShaderStage stage);
|
||||||
|
|
||||||
class PipelineBase : public ObjectBase {
|
class PipelineBase : public CachedObject {
|
||||||
public:
|
public:
|
||||||
wgpu::ShaderStage GetStageMask() const;
|
wgpu::ShaderStage GetStageMask() const;
|
||||||
PipelineLayoutBase* GetLayout();
|
PipelineLayoutBase* GetLayout();
|
||||||
|
@ -56,9 +56,8 @@ namespace dawn_native {
|
|||||||
// PipelineLayoutBase
|
// PipelineLayoutBase
|
||||||
|
|
||||||
PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device,
|
PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device,
|
||||||
const PipelineLayoutDescriptor* descriptor,
|
const PipelineLayoutDescriptor* descriptor)
|
||||||
bool blueprint)
|
: CachedObject(device) {
|
||||||
: ObjectBase(device), mIsBlueprint(blueprint) {
|
|
||||||
ASSERT(descriptor->bindGroupLayoutCount <= kMaxBindGroups);
|
ASSERT(descriptor->bindGroupLayoutCount <= kMaxBindGroups);
|
||||||
for (uint32_t group = 0; group < descriptor->bindGroupLayoutCount; ++group) {
|
for (uint32_t group = 0; group < descriptor->bindGroupLayoutCount; ++group) {
|
||||||
mBindGroupLayouts[group] = descriptor->bindGroupLayouts[group];
|
mBindGroupLayouts[group] = descriptor->bindGroupLayouts[group];
|
||||||
@ -67,12 +66,12 @@ namespace dawn_native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||||
: ObjectBase(device, tag) {
|
: CachedObject(device, tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PipelineLayoutBase::~PipelineLayoutBase() {
|
PipelineLayoutBase::~PipelineLayoutBase() {
|
||||||
// Do not uncache the actual cached object if we are a blueprint
|
// Do not uncache the actual cached object if we are a blueprint
|
||||||
if (!mIsBlueprint && !IsError()) {
|
if (IsCachedReference()) {
|
||||||
GetDevice()->UncachePipelineLayout(this);
|
GetDevice()->UncachePipelineLayout(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
#define DAWNNATIVE_PIPELINELAYOUT_H_
|
#define DAWNNATIVE_PIPELINELAYOUT_H_
|
||||||
|
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
|
#include "dawn_native/CachedObject.h"
|
||||||
#include "dawn_native/Error.h"
|
#include "dawn_native/Error.h"
|
||||||
#include "dawn_native/Forward.h"
|
#include "dawn_native/Forward.h"
|
||||||
#include "dawn_native/ObjectBase.h"
|
|
||||||
|
|
||||||
#include "dawn_native/dawn_platform.h"
|
#include "dawn_native/dawn_platform.h"
|
||||||
|
|
||||||
@ -32,11 +32,9 @@ namespace dawn_native {
|
|||||||
|
|
||||||
using BindGroupLayoutArray = std::array<Ref<BindGroupLayoutBase>, kMaxBindGroups>;
|
using BindGroupLayoutArray = std::array<Ref<BindGroupLayoutBase>, kMaxBindGroups>;
|
||||||
|
|
||||||
class PipelineLayoutBase : public ObjectBase {
|
class PipelineLayoutBase : public CachedObject {
|
||||||
public:
|
public:
|
||||||
PipelineLayoutBase(DeviceBase* device,
|
PipelineLayoutBase(DeviceBase* device, const PipelineLayoutDescriptor* descriptor);
|
||||||
const PipelineLayoutDescriptor* descriptor,
|
|
||||||
bool blueprint = false);
|
|
||||||
~PipelineLayoutBase() override;
|
~PipelineLayoutBase() override;
|
||||||
|
|
||||||
static PipelineLayoutBase* MakeError(DeviceBase* device);
|
static PipelineLayoutBase* MakeError(DeviceBase* device);
|
||||||
@ -65,7 +63,6 @@ namespace dawn_native {
|
|||||||
|
|
||||||
BindGroupLayoutArray mBindGroupLayouts;
|
BindGroupLayoutArray mBindGroupLayouts;
|
||||||
std::bitset<kMaxBindGroups> mMask;
|
std::bitset<kMaxBindGroups> mMask;
|
||||||
bool mIsBlueprint = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
@ -366,8 +366,7 @@ namespace dawn_native {
|
|||||||
// RenderPipelineBase
|
// RenderPipelineBase
|
||||||
|
|
||||||
RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
|
RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
|
||||||
const RenderPipelineDescriptor* descriptor,
|
const RenderPipelineDescriptor* descriptor)
|
||||||
bool blueprint)
|
|
||||||
: PipelineBase(device,
|
: PipelineBase(device,
|
||||||
descriptor->layout,
|
descriptor->layout,
|
||||||
wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment),
|
wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment),
|
||||||
@ -378,8 +377,7 @@ namespace dawn_native {
|
|||||||
mVertexModule(descriptor->vertexStage.module),
|
mVertexModule(descriptor->vertexStage.module),
|
||||||
mVertexEntryPoint(descriptor->vertexStage.entryPoint),
|
mVertexEntryPoint(descriptor->vertexStage.entryPoint),
|
||||||
mFragmentModule(descriptor->fragmentStage->module),
|
mFragmentModule(descriptor->fragmentStage->module),
|
||||||
mFragmentEntryPoint(descriptor->fragmentStage->entryPoint),
|
mFragmentEntryPoint(descriptor->fragmentStage->entryPoint) {
|
||||||
mIsBlueprint(blueprint) {
|
|
||||||
if (descriptor->vertexInput != nullptr) {
|
if (descriptor->vertexInput != nullptr) {
|
||||||
mVertexInput = *descriptor->vertexInput;
|
mVertexInput = *descriptor->vertexInput;
|
||||||
} else {
|
} else {
|
||||||
@ -451,8 +449,7 @@ namespace dawn_native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RenderPipelineBase::~RenderPipelineBase() {
|
RenderPipelineBase::~RenderPipelineBase() {
|
||||||
// Do not uncache the actual cached object if we are a blueprint
|
if (IsCachedReference()) {
|
||||||
if (!mIsBlueprint && !IsError()) {
|
|
||||||
GetDevice()->UncacheRenderPipeline(this);
|
GetDevice()->UncacheRenderPipeline(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,7 @@ namespace dawn_native {
|
|||||||
|
|
||||||
class RenderPipelineBase : public PipelineBase {
|
class RenderPipelineBase : public PipelineBase {
|
||||||
public:
|
public:
|
||||||
RenderPipelineBase(DeviceBase* device,
|
RenderPipelineBase(DeviceBase* device, const RenderPipelineDescriptor* descriptor);
|
||||||
const RenderPipelineDescriptor* descriptor,
|
|
||||||
bool blueprint = false);
|
|
||||||
~RenderPipelineBase() override;
|
~RenderPipelineBase() override;
|
||||||
|
|
||||||
static RenderPipelineBase* MakeError(DeviceBase* device);
|
static RenderPipelineBase* MakeError(DeviceBase* device);
|
||||||
@ -119,8 +117,6 @@ namespace dawn_native {
|
|||||||
std::string mVertexEntryPoint;
|
std::string mVertexEntryPoint;
|
||||||
Ref<ShaderModuleBase> mFragmentModule;
|
Ref<ShaderModuleBase> mFragmentModule;
|
||||||
std::string mFragmentEntryPoint;
|
std::string mFragmentEntryPoint;
|
||||||
|
|
||||||
bool mIsBlueprint = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
@ -52,10 +52,8 @@ namespace dawn_native {
|
|||||||
|
|
||||||
// SamplerBase
|
// SamplerBase
|
||||||
|
|
||||||
SamplerBase::SamplerBase(DeviceBase* device,
|
SamplerBase::SamplerBase(DeviceBase* device, const SamplerDescriptor* descriptor)
|
||||||
const SamplerDescriptor* descriptor,
|
: CachedObject(device),
|
||||||
bool blueprint)
|
|
||||||
: ObjectBase(device),
|
|
||||||
mAddressModeU(descriptor->addressModeU),
|
mAddressModeU(descriptor->addressModeU),
|
||||||
mAddressModeV(descriptor->addressModeV),
|
mAddressModeV(descriptor->addressModeV),
|
||||||
mAddressModeW(descriptor->addressModeW),
|
mAddressModeW(descriptor->addressModeW),
|
||||||
@ -64,17 +62,15 @@ namespace dawn_native {
|
|||||||
mMipmapFilter(descriptor->mipmapFilter),
|
mMipmapFilter(descriptor->mipmapFilter),
|
||||||
mLodMinClamp(descriptor->lodMinClamp),
|
mLodMinClamp(descriptor->lodMinClamp),
|
||||||
mLodMaxClamp(descriptor->lodMaxClamp),
|
mLodMaxClamp(descriptor->lodMaxClamp),
|
||||||
mCompareFunction(descriptor->compare),
|
mCompareFunction(descriptor->compare) {
|
||||||
mIsBlueprint(blueprint) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SamplerBase::SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
SamplerBase::SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||||
: ObjectBase(device, tag) {
|
: CachedObject(device, tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SamplerBase::~SamplerBase() {
|
SamplerBase::~SamplerBase() {
|
||||||
// Do not uncache the actual cached object if we are a blueprint
|
if (IsCachedReference()) {
|
||||||
if (!mIsBlueprint && !IsError()) {
|
|
||||||
GetDevice()->UncacheSampler(this);
|
GetDevice()->UncacheSampler(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef DAWNNATIVE_SAMPLER_H_
|
#ifndef DAWNNATIVE_SAMPLER_H_
|
||||||
#define DAWNNATIVE_SAMPLER_H_
|
#define DAWNNATIVE_SAMPLER_H_
|
||||||
|
|
||||||
|
#include "dawn_native/CachedObject.h"
|
||||||
#include "dawn_native/Error.h"
|
#include "dawn_native/Error.h"
|
||||||
#include "dawn_native/ObjectBase.h"
|
|
||||||
|
|
||||||
#include "dawn_native/dawn_platform.h"
|
#include "dawn_native/dawn_platform.h"
|
||||||
|
|
||||||
@ -26,11 +26,9 @@ namespace dawn_native {
|
|||||||
|
|
||||||
MaybeError ValidateSamplerDescriptor(DeviceBase* device, const SamplerDescriptor* descriptor);
|
MaybeError ValidateSamplerDescriptor(DeviceBase* device, const SamplerDescriptor* descriptor);
|
||||||
|
|
||||||
class SamplerBase : public ObjectBase {
|
class SamplerBase : public CachedObject {
|
||||||
public:
|
public:
|
||||||
SamplerBase(DeviceBase* device,
|
SamplerBase(DeviceBase* device, const SamplerDescriptor* descriptor);
|
||||||
const SamplerDescriptor* descriptor,
|
|
||||||
bool blueprint = false);
|
|
||||||
~SamplerBase() override;
|
~SamplerBase() override;
|
||||||
|
|
||||||
static SamplerBase* MakeError(DeviceBase* device);
|
static SamplerBase* MakeError(DeviceBase* device);
|
||||||
@ -56,7 +54,6 @@ namespace dawn_native {
|
|||||||
float mLodMinClamp;
|
float mLodMinClamp;
|
||||||
float mLodMaxClamp;
|
float mLodMaxClamp;
|
||||||
wgpu::CompareFunction mCompareFunction;
|
wgpu::CompareFunction mCompareFunction;
|
||||||
bool mIsBlueprint = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
@ -84,22 +84,17 @@ namespace dawn_native {
|
|||||||
|
|
||||||
// ShaderModuleBase
|
// ShaderModuleBase
|
||||||
|
|
||||||
ShaderModuleBase::ShaderModuleBase(DeviceBase* device,
|
ShaderModuleBase::ShaderModuleBase(DeviceBase* device, const ShaderModuleDescriptor* descriptor)
|
||||||
const ShaderModuleDescriptor* descriptor,
|
: CachedObject(device), mCode(descriptor->code, descriptor->code + descriptor->codeSize) {
|
||||||
bool blueprint)
|
|
||||||
: ObjectBase(device),
|
|
||||||
mCode(descriptor->code, descriptor->code + descriptor->codeSize),
|
|
||||||
mIsBlueprint(blueprint) {
|
|
||||||
mFragmentOutputFormatBaseTypes.fill(Format::Other);
|
mFragmentOutputFormatBaseTypes.fill(Format::Other);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderModuleBase::ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
ShaderModuleBase::ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||||
: ObjectBase(device, tag) {
|
: CachedObject(device, tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderModuleBase::~ShaderModuleBase() {
|
ShaderModuleBase::~ShaderModuleBase() {
|
||||||
// Do not uncache the actual cached object if we are a blueprint
|
if (IsCachedReference()) {
|
||||||
if (!mIsBlueprint && !IsError()) {
|
|
||||||
GetDevice()->UncacheShaderModule(this);
|
GetDevice()->UncacheShaderModule(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
#define DAWNNATIVE_SHADERMODULE_H_
|
#define DAWNNATIVE_SHADERMODULE_H_
|
||||||
|
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
|
#include "dawn_native/CachedObject.h"
|
||||||
#include "dawn_native/Error.h"
|
#include "dawn_native/Error.h"
|
||||||
#include "dawn_native/Format.h"
|
#include "dawn_native/Format.h"
|
||||||
#include "dawn_native/Forward.h"
|
#include "dawn_native/Forward.h"
|
||||||
#include "dawn_native/ObjectBase.h"
|
|
||||||
#include "dawn_native/PerStage.h"
|
#include "dawn_native/PerStage.h"
|
||||||
|
|
||||||
#include "dawn_native/dawn_platform.h"
|
#include "dawn_native/dawn_platform.h"
|
||||||
@ -37,11 +37,9 @@ namespace dawn_native {
|
|||||||
MaybeError ValidateShaderModuleDescriptor(DeviceBase* device,
|
MaybeError ValidateShaderModuleDescriptor(DeviceBase* device,
|
||||||
const ShaderModuleDescriptor* descriptor);
|
const ShaderModuleDescriptor* descriptor);
|
||||||
|
|
||||||
class ShaderModuleBase : public ObjectBase {
|
class ShaderModuleBase : public CachedObject {
|
||||||
public:
|
public:
|
||||||
ShaderModuleBase(DeviceBase* device,
|
ShaderModuleBase(DeviceBase* device, const ShaderModuleDescriptor* descriptor);
|
||||||
const ShaderModuleDescriptor* descriptor,
|
|
||||||
bool blueprint = false);
|
|
||||||
~ShaderModuleBase() override;
|
~ShaderModuleBase() override;
|
||||||
|
|
||||||
static ShaderModuleBase* MakeError(DeviceBase* device);
|
static ShaderModuleBase* MakeError(DeviceBase* device);
|
||||||
@ -85,7 +83,6 @@ namespace dawn_native {
|
|||||||
// TODO(cwallez@chromium.org): The code is only stored for deduplication. We could maybe
|
// TODO(cwallez@chromium.org): The code is only stored for deduplication. We could maybe
|
||||||
// store a cryptographic hash of the code instead?
|
// store a cryptographic hash of the code instead?
|
||||||
std::vector<uint32_t> mCode;
|
std::vector<uint32_t> mCode;
|
||||||
bool mIsBlueprint = false;
|
|
||||||
|
|
||||||
ModuleBindingInfo mBindingInfo;
|
ModuleBindingInfo mBindingInfo;
|
||||||
std::bitset<kMaxVertexAttributes> mUsedVertexAttributes;
|
std::bitset<kMaxVertexAttributes> mUsedVertexAttributes;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user