mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-13 16:45:56 +00:00
Format: src/backend
This commit is contained in:
parent
9d01c6c26d
commit
c1400f0d14
@ -26,7 +26,9 @@ namespace backend {
|
|||||||
// BindGroup
|
// BindGroup
|
||||||
|
|
||||||
BindGroupBase::BindGroupBase(BindGroupBuilder* builder)
|
BindGroupBase::BindGroupBase(BindGroupBuilder* builder)
|
||||||
: mLayout(std::move(builder->mLayout)), mUsage(builder->mUsage), mBindings(std::move(builder->mBindings)) {
|
: mLayout(std::move(builder->mLayout)),
|
||||||
|
mUsage(builder->mUsage),
|
||||||
|
mBindings(std::move(builder->mBindings)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const BindGroupLayoutBase* BindGroupBase::GetLayout() const {
|
const BindGroupLayoutBase* BindGroupBase::GetLayout() const {
|
||||||
@ -104,7 +106,9 @@ namespace backend {
|
|||||||
mPropertiesSet |= BINDGROUP_PROPERTY_USAGE;
|
mPropertiesSet |= BINDGROUP_PROPERTY_USAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindGroupBuilder::SetBufferViews(uint32_t start, uint32_t count, BufferViewBase* const * bufferViews) {
|
void BindGroupBuilder::SetBufferViews(uint32_t start,
|
||||||
|
uint32_t count,
|
||||||
|
BufferViewBase* const* bufferViews) {
|
||||||
if (!SetBindingsValidationBase(start, count)) {
|
if (!SetBindingsValidationBase(start, count)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -138,10 +142,12 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetBindingsBase(start, count, reinterpret_cast<RefCounted* const *>(bufferViews));
|
SetBindingsBase(start, count, reinterpret_cast<RefCounted* const*>(bufferViews));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindGroupBuilder::SetSamplers(uint32_t start, uint32_t count, SamplerBase* const * samplers) {
|
void BindGroupBuilder::SetSamplers(uint32_t start,
|
||||||
|
uint32_t count,
|
||||||
|
SamplerBase* const* samplers) {
|
||||||
if (!SetBindingsValidationBase(start, count)) {
|
if (!SetBindingsValidationBase(start, count)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -154,10 +160,12 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetBindingsBase(start, count, reinterpret_cast<RefCounted* const *>(samplers));
|
SetBindingsBase(start, count, reinterpret_cast<RefCounted* const*>(samplers));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindGroupBuilder::SetTextureViews(uint32_t start, uint32_t count, TextureViewBase* const * textureViews) {
|
void BindGroupBuilder::SetTextureViews(uint32_t start,
|
||||||
|
uint32_t count,
|
||||||
|
TextureViewBase* const* textureViews) {
|
||||||
if (!SetBindingsValidationBase(start, count)) {
|
if (!SetBindingsValidationBase(start, count)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -169,16 +177,19 @@ namespace backend {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(textureViews[j]->GetTexture()->GetAllowedUsage() & nxt::TextureUsageBit::Sampled)) {
|
if (!(textureViews[j]->GetTexture()->GetAllowedUsage() &
|
||||||
|
nxt::TextureUsageBit::Sampled)) {
|
||||||
HandleError("Texture needs to allow the sampled usage bit");
|
HandleError("Texture needs to allow the sampled usage bit");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetBindingsBase(start, count, reinterpret_cast<RefCounted* const *>(textureViews));
|
SetBindingsBase(start, count, reinterpret_cast<RefCounted* const*>(textureViews));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindGroupBuilder::SetBindingsBase(uint32_t start, uint32_t count, RefCounted* const * objects) {
|
void BindGroupBuilder::SetBindingsBase(uint32_t start,
|
||||||
|
uint32_t count,
|
||||||
|
RefCounted* const* objects) {
|
||||||
for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
|
for (size_t i = start, j = 0; i < start + count; ++i, ++j) {
|
||||||
mSetMask.set(i);
|
mSetMask.set(i);
|
||||||
mBindings[i] = objects[j];
|
mBindings[i] = objects[j];
|
||||||
@ -211,4 +222,4 @@ namespace backend {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -52,32 +52,32 @@ namespace backend {
|
|||||||
void SetLayout(BindGroupLayoutBase* layout);
|
void SetLayout(BindGroupLayoutBase* layout);
|
||||||
void SetUsage(nxt::BindGroupUsage usage);
|
void SetUsage(nxt::BindGroupUsage usage);
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void SetBufferViews(uint32_t start, uint32_t count, T* const* bufferViews) {
|
void SetBufferViews(uint32_t start, uint32_t count, T* const* bufferViews) {
|
||||||
static_assert(std::is_base_of<BufferViewBase, T>::value, "");
|
static_assert(std::is_base_of<BufferViewBase, T>::value, "");
|
||||||
SetBufferViews(start, count, reinterpret_cast<BufferViewBase* const*>(bufferViews));
|
SetBufferViews(start, count, reinterpret_cast<BufferViewBase* const*>(bufferViews));
|
||||||
}
|
}
|
||||||
void SetBufferViews(uint32_t start, uint32_t count, BufferViewBase* const * bufferViews);
|
void SetBufferViews(uint32_t start, uint32_t count, BufferViewBase* const* bufferViews);
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void SetSamplers(uint32_t start, uint32_t count, T* const* samplers) {
|
void SetSamplers(uint32_t start, uint32_t count, T* const* samplers) {
|
||||||
static_assert(std::is_base_of<SamplerBase, T>::value, "");
|
static_assert(std::is_base_of<SamplerBase, T>::value, "");
|
||||||
SetSamplers(start, count, reinterpret_cast<SamplerBase* const*>(samplers));
|
SetSamplers(start, count, reinterpret_cast<SamplerBase* const*>(samplers));
|
||||||
}
|
}
|
||||||
void SetSamplers(uint32_t start, uint32_t count, SamplerBase* const * samplers);
|
void SetSamplers(uint32_t start, uint32_t count, SamplerBase* const* samplers);
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void SetTextureViews(uint32_t start, uint32_t count, T* const* textureViews) {
|
void SetTextureViews(uint32_t start, uint32_t count, T* const* textureViews) {
|
||||||
static_assert(std::is_base_of<TextureViewBase, T>::value, "");
|
static_assert(std::is_base_of<TextureViewBase, T>::value, "");
|
||||||
SetTextureViews(start, count, reinterpret_cast<TextureViewBase* const*>(textureViews));
|
SetTextureViews(start, count, reinterpret_cast<TextureViewBase* const*>(textureViews));
|
||||||
}
|
}
|
||||||
void SetTextureViews(uint32_t start, uint32_t count, TextureViewBase* const * textureViews);
|
void SetTextureViews(uint32_t start, uint32_t count, TextureViewBase* const* textureViews);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BindGroupBase;
|
friend class BindGroupBase;
|
||||||
|
|
||||||
BindGroupBase* GetResultImpl() override;
|
BindGroupBase* GetResultImpl() override;
|
||||||
void SetBindingsBase(uint32_t start, uint32_t count, RefCounted* const * objects);
|
void SetBindingsBase(uint32_t start, uint32_t count, RefCounted* const* objects);
|
||||||
bool SetBindingsValidationBase(uint32_t start, uint32_t count);
|
bool SetBindingsValidationBase(uint32_t start, uint32_t count);
|
||||||
|
|
||||||
std::bitset<kMaxBindingsPerGroup> mSetMask;
|
std::bitset<kMaxBindingsPerGroup> mSetMask;
|
||||||
@ -88,6 +88,6 @@ namespace backend {
|
|||||||
std::array<Ref<RefCounted>, kMaxBindingsPerGroup> mBindings;
|
std::array<Ref<RefCounted>, kMaxBindingsPerGroup> mBindings;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_BINDGROUP_H_
|
#endif // BACKEND_BINDGROUP_H_
|
||||||
|
@ -23,13 +23,13 @@ namespace backend {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Workaround for Chrome's stdlib having a broken std::hash for enums and bitsets
|
// Workaround for Chrome's stdlib having a broken std::hash for enums and bitsets
|
||||||
template<typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_enum<T>::value, size_t>::type Hash(T value) {
|
typename std::enable_if<std::is_enum<T>::value, size_t>::type Hash(T value) {
|
||||||
using Integral = typename nxt::UnderlyingType<T>::type;
|
using Integral = typename nxt::UnderlyingType<T>::type;
|
||||||
return std::hash<Integral>()(static_cast<Integral>(value));
|
return std::hash<Integral>()(static_cast<Integral>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t N>
|
template <size_t N>
|
||||||
size_t Hash(const std::bitset<N>& value) {
|
size_t Hash(const std::bitset<N>& value) {
|
||||||
static_assert(N <= sizeof(unsigned long long) * 8, "");
|
static_assert(N <= sizeof(unsigned long long) * 8, "");
|
||||||
return std::hash<unsigned long long>()(value.to_ullong());
|
return std::hash<unsigned long long>()(value.to_ullong());
|
||||||
@ -54,7 +54,8 @@ namespace backend {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator== (const BindGroupLayoutBase::LayoutBindingInfo& a, const BindGroupLayoutBase::LayoutBindingInfo& b) {
|
bool operator==(const BindGroupLayoutBase::LayoutBindingInfo& a,
|
||||||
|
const BindGroupLayoutBase::LayoutBindingInfo& b) {
|
||||||
if (a.mask != b.mask) {
|
if (a.mask != b.mask) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -72,7 +73,7 @@ namespace backend {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
// BindGroupLayoutBase
|
// BindGroupLayoutBase
|
||||||
|
|
||||||
@ -108,7 +109,10 @@ namespace backend {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindGroupLayoutBuilder::SetBindingsType(nxt::ShaderStageBit visibility, nxt::BindingType bindingType, uint32_t start, uint32_t count) {
|
void BindGroupLayoutBuilder::SetBindingsType(nxt::ShaderStageBit visibility,
|
||||||
|
nxt::BindingType bindingType,
|
||||||
|
uint32_t start,
|
||||||
|
uint32_t count) {
|
||||||
if (start + count > kMaxBindingsPerGroup) {
|
if (start + count > kMaxBindingsPerGroup) {
|
||||||
HandleError("Setting bindings type over maximum number of bindings");
|
HandleError("Setting bindings type over maximum number of bindings");
|
||||||
return;
|
return;
|
||||||
@ -129,12 +133,13 @@ namespace backend {
|
|||||||
|
|
||||||
// BindGroupLayoutCacheFuncs
|
// BindGroupLayoutCacheFuncs
|
||||||
|
|
||||||
size_t BindGroupLayoutCacheFuncs::operator() (const BindGroupLayoutBase* bgl) const {
|
size_t BindGroupLayoutCacheFuncs::operator()(const BindGroupLayoutBase* bgl) const {
|
||||||
return HashBindingInfo(bgl->GetBindingInfo());
|
return HashBindingInfo(bgl->GetBindingInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BindGroupLayoutCacheFuncs::operator() (const BindGroupLayoutBase* a, const BindGroupLayoutBase* b) const {
|
bool BindGroupLayoutCacheFuncs::operator()(const BindGroupLayoutBase* a,
|
||||||
|
const BindGroupLayoutBase* b) const {
|
||||||
return a->GetBindingInfo() == b->GetBindingInfo();
|
return a->GetBindingInfo() == b->GetBindingInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_BINDGROUPLAYOUT_H_
|
#ifndef BACKEND_BINDGROUPLAYOUT_H_
|
||||||
#define BACKEND_BINDGROUPLAYOUT_H_
|
#define BACKEND_BINDGROUPLAYOUT_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
|
|
||||||
@ -52,7 +52,10 @@ namespace backend {
|
|||||||
const BindGroupLayoutBase::LayoutBindingInfo& GetBindingInfo() const;
|
const BindGroupLayoutBase::LayoutBindingInfo& GetBindingInfo() const;
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
void SetBindingsType(nxt::ShaderStageBit visibility, nxt::BindingType bindingType, uint32_t start, uint32_t count);
|
void SetBindingsType(nxt::ShaderStageBit visibility,
|
||||||
|
nxt::BindingType bindingType,
|
||||||
|
uint32_t start,
|
||||||
|
uint32_t count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BindGroupLayoutBase;
|
friend class BindGroupLayoutBase;
|
||||||
@ -65,12 +68,12 @@ namespace backend {
|
|||||||
// Implements the functors necessary for the unordered_set<BGL*>-based cache.
|
// Implements the functors necessary for the unordered_set<BGL*>-based cache.
|
||||||
struct BindGroupLayoutCacheFuncs {
|
struct BindGroupLayoutCacheFuncs {
|
||||||
// The hash function
|
// The hash function
|
||||||
size_t operator() (const BindGroupLayoutBase* bgl) const;
|
size_t operator()(const BindGroupLayoutBase* bgl) const;
|
||||||
|
|
||||||
// The equality predicate
|
// The equality predicate
|
||||||
bool operator() (const BindGroupLayoutBase* a, const BindGroupLayoutBase* b) const;
|
bool operator()(const BindGroupLayoutBase* a, const BindGroupLayoutBase* b) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_BINDGROUPLAYOUT_H_
|
#endif // BACKEND_BINDGROUPLAYOUT_H_
|
||||||
|
@ -54,7 +54,9 @@ namespace backend {
|
|||||||
mBlendInfo.blendEnabled = blendEnabled;
|
mBlendInfo.blendEnabled = blendEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlendStateBuilder::SetAlphaBlend(nxt::BlendOperation blendOperation, nxt::BlendFactor srcFactor, nxt::BlendFactor dstFactor) {
|
void BlendStateBuilder::SetAlphaBlend(nxt::BlendOperation blendOperation,
|
||||||
|
nxt::BlendFactor srcFactor,
|
||||||
|
nxt::BlendFactor dstFactor) {
|
||||||
if ((mPropertiesSet & BLEND_STATE_PROPERTY_ALPHA_BLEND) != 0) {
|
if ((mPropertiesSet & BLEND_STATE_PROPERTY_ALPHA_BLEND) != 0) {
|
||||||
HandleError("Alpha blend property set multiple times");
|
HandleError("Alpha blend property set multiple times");
|
||||||
return;
|
return;
|
||||||
@ -62,10 +64,12 @@ namespace backend {
|
|||||||
|
|
||||||
mPropertiesSet |= BLEND_STATE_PROPERTY_ALPHA_BLEND;
|
mPropertiesSet |= BLEND_STATE_PROPERTY_ALPHA_BLEND;
|
||||||
|
|
||||||
mBlendInfo.alphaBlend = { blendOperation, srcFactor, dstFactor };
|
mBlendInfo.alphaBlend = {blendOperation, srcFactor, dstFactor};
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlendStateBuilder::SetColorBlend(nxt::BlendOperation blendOperation, nxt::BlendFactor srcFactor, nxt::BlendFactor dstFactor) {
|
void BlendStateBuilder::SetColorBlend(nxt::BlendOperation blendOperation,
|
||||||
|
nxt::BlendFactor srcFactor,
|
||||||
|
nxt::BlendFactor dstFactor) {
|
||||||
if ((mPropertiesSet & BLEND_STATE_PROPERTY_COLOR_BLEND) != 0) {
|
if ((mPropertiesSet & BLEND_STATE_PROPERTY_COLOR_BLEND) != 0) {
|
||||||
HandleError("Color blend property set multiple times");
|
HandleError("Color blend property set multiple times");
|
||||||
return;
|
return;
|
||||||
@ -73,7 +77,7 @@ namespace backend {
|
|||||||
|
|
||||||
mPropertiesSet |= BLEND_STATE_PROPERTY_COLOR_BLEND;
|
mPropertiesSet |= BLEND_STATE_PROPERTY_COLOR_BLEND;
|
||||||
|
|
||||||
mBlendInfo.colorBlend = { blendOperation, srcFactor, dstFactor };
|
mBlendInfo.colorBlend = {blendOperation, srcFactor, dstFactor};
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlendStateBuilder::SetColorWriteMask(nxt::ColorWriteMask colorWriteMask) {
|
void BlendStateBuilder::SetColorWriteMask(nxt::ColorWriteMask colorWriteMask) {
|
||||||
@ -86,4 +90,4 @@ namespace backend {
|
|||||||
|
|
||||||
mBlendInfo.colorWriteMask = colorWriteMask;
|
mBlendInfo.colorWriteMask = colorWriteMask;
|
||||||
}
|
}
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_BLENDSTATE_H_
|
#ifndef BACKEND_BLENDSTATE_H_
|
||||||
#define BACKEND_BLENDSTATE_H_
|
#define BACKEND_BLENDSTATE_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
@ -44,7 +44,6 @@ namespace backend {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BlendInfo mBlendInfo;
|
BlendInfo mBlendInfo;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlendStateBuilder : public Builder<BlendStateBase> {
|
class BlendStateBuilder : public Builder<BlendStateBase> {
|
||||||
@ -53,8 +52,12 @@ namespace backend {
|
|||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
void SetBlendEnabled(bool blendEnabled);
|
void SetBlendEnabled(bool blendEnabled);
|
||||||
void SetAlphaBlend(nxt::BlendOperation blendOperation, nxt::BlendFactor srcFactor, nxt::BlendFactor dstFactor);
|
void SetAlphaBlend(nxt::BlendOperation blendOperation,
|
||||||
void SetColorBlend(nxt::BlendOperation blendOperation, nxt::BlendFactor srcFactor, nxt::BlendFactor dstFactor);
|
nxt::BlendFactor srcFactor,
|
||||||
|
nxt::BlendFactor dstFactor);
|
||||||
|
void SetColorBlend(nxt::BlendOperation blendOperation,
|
||||||
|
nxt::BlendFactor srcFactor,
|
||||||
|
nxt::BlendFactor dstFactor);
|
||||||
void SetColorWriteMask(nxt::ColorWriteMask colorWriteMask);
|
void SetColorWriteMask(nxt::ColorWriteMask colorWriteMask);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -67,6 +70,6 @@ namespace backend {
|
|||||||
BlendStateBase::BlendInfo mBlendInfo;
|
BlendStateBase::BlendInfo mBlendInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_BLENDSTATE_H_
|
#endif // BACKEND_BLENDSTATE_H_
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
@ -57,7 +57,9 @@ namespace backend {
|
|||||||
return mCurrentUsage;
|
return mCurrentUsage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferBase::CallMapReadCallback(uint32_t serial, nxtBufferMapReadStatus status, const void* pointer) {
|
void BufferBase::CallMapReadCallback(uint32_t serial,
|
||||||
|
nxtBufferMapReadStatus status,
|
||||||
|
const void* pointer) {
|
||||||
if (mMapReadCallback && serial == mMapReadSerial) {
|
if (mMapReadCallback && serial == mMapReadSerial) {
|
||||||
mMapReadCallback(status, pointer, mMapReadUserdata);
|
mMapReadCallback(status, pointer, mMapReadUserdata);
|
||||||
mMapReadCallback = nullptr;
|
mMapReadCallback = nullptr;
|
||||||
@ -78,7 +80,10 @@ namespace backend {
|
|||||||
SetSubDataImpl(start, count, data);
|
SetSubDataImpl(start, count, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferBase::MapReadAsync(uint32_t start, uint32_t size, nxtBufferMapReadCallback callback, nxtCallbackUserdata userdata) {
|
void BufferBase::MapReadAsync(uint32_t start,
|
||||||
|
uint32_t size,
|
||||||
|
nxtBufferMapReadCallback callback,
|
||||||
|
nxtCallbackUserdata userdata) {
|
||||||
if (start + size > GetSize()) {
|
if (start + size > GetSize()) {
|
||||||
mDevice->HandleError("Buffer map read out of range");
|
mDevice->HandleError("Buffer map read out of range");
|
||||||
callback(NXT_BUFFER_MAP_READ_STATUS_ERROR, nullptr, userdata);
|
callback(NXT_BUFFER_MAP_READ_STATUS_ERROR, nullptr, userdata);
|
||||||
@ -98,7 +103,7 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(cwallez@chromium.org): what to do on wraparound? Could cause crashes.
|
// TODO(cwallez@chromium.org): what to do on wraparound? Could cause crashes.
|
||||||
mMapReadSerial ++;
|
mMapReadSerial++;
|
||||||
mMapReadCallback = callback;
|
mMapReadCallback = callback;
|
||||||
mMapReadUserdata = userdata;
|
mMapReadUserdata = userdata;
|
||||||
MapReadAsyncImpl(mMapReadSerial, start, size);
|
MapReadAsyncImpl(mMapReadSerial, start, size);
|
||||||
@ -128,11 +133,8 @@ namespace backend {
|
|||||||
|
|
||||||
bool BufferBase::IsUsagePossible(nxt::BufferUsageBit allowedUsage, nxt::BufferUsageBit usage) {
|
bool BufferBase::IsUsagePossible(nxt::BufferUsageBit allowedUsage, nxt::BufferUsageBit usage) {
|
||||||
const nxt::BufferUsageBit allReadBits =
|
const nxt::BufferUsageBit allReadBits =
|
||||||
nxt::BufferUsageBit::MapRead |
|
nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::TransferSrc |
|
||||||
nxt::BufferUsageBit::TransferSrc |
|
nxt::BufferUsageBit::Index | nxt::BufferUsageBit::Vertex | nxt::BufferUsageBit::Uniform;
|
||||||
nxt::BufferUsageBit::Index |
|
|
||||||
nxt::BufferUsageBit::Vertex |
|
|
||||||
nxt::BufferUsageBit::Uniform;
|
|
||||||
bool allowed = (usage & allowedUsage) == usage;
|
bool allowed = (usage & allowedUsage) == usage;
|
||||||
bool readOnly = (usage & allReadBits) == usage;
|
bool readOnly = (usage & allReadBits) == usage;
|
||||||
bool singleUse = nxt::HasZeroOrOneBits(usage);
|
bool singleUse = nxt::HasZeroOrOneBits(usage);
|
||||||
@ -189,14 +191,16 @@ namespace backend {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nxt::BufferUsageBit kMapWriteAllowedUsages = nxt::BufferUsageBit::MapWrite | nxt::BufferUsageBit::TransferSrc;
|
const nxt::BufferUsageBit kMapWriteAllowedUsages =
|
||||||
|
nxt::BufferUsageBit::MapWrite | nxt::BufferUsageBit::TransferSrc;
|
||||||
if (mAllowedUsage & nxt::BufferUsageBit::MapWrite &&
|
if (mAllowedUsage & nxt::BufferUsageBit::MapWrite &&
|
||||||
(mAllowedUsage & kMapWriteAllowedUsages) != mAllowedUsage) {
|
(mAllowedUsage & kMapWriteAllowedUsages) != mAllowedUsage) {
|
||||||
HandleError("Only TransferSrc is allowed with MapWrite");
|
HandleError("Only TransferSrc is allowed with MapWrite");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nxt::BufferUsageBit kMapReadAllowedUsages = nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::TransferDst;
|
const nxt::BufferUsageBit kMapReadAllowedUsages =
|
||||||
|
nxt::BufferUsageBit::MapRead | nxt::BufferUsageBit::TransferDst;
|
||||||
if (mAllowedUsage & nxt::BufferUsageBit::MapRead &&
|
if (mAllowedUsage & nxt::BufferUsageBit::MapRead &&
|
||||||
(mAllowedUsage & kMapReadAllowedUsages) != mAllowedUsage) {
|
(mAllowedUsage & kMapReadAllowedUsages) != mAllowedUsage) {
|
||||||
HandleError("Only TransferDst is allowed with MapRead");
|
HandleError("Only TransferDst is allowed with MapRead");
|
||||||
@ -296,4 +300,4 @@ namespace backend {
|
|||||||
mPropertiesSet |= BUFFER_VIEW_PROPERTY_EXTENT;
|
mPropertiesSet |= BUFFER_VIEW_PROPERTY_EXTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_BUFFER_H_
|
#ifndef BACKEND_BUFFER_H_
|
||||||
#define BACKEND_BUFFER_H_
|
#define BACKEND_BUFFER_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
@ -42,19 +42,25 @@ namespace backend {
|
|||||||
// NXT API
|
// NXT API
|
||||||
BufferViewBuilder* CreateBufferViewBuilder();
|
BufferViewBuilder* CreateBufferViewBuilder();
|
||||||
void SetSubData(uint32_t start, uint32_t count, const uint32_t* data);
|
void SetSubData(uint32_t start, uint32_t count, const uint32_t* data);
|
||||||
void MapReadAsync(uint32_t start, uint32_t size, nxtBufferMapReadCallback callback, nxtCallbackUserdata userdata);
|
void MapReadAsync(uint32_t start,
|
||||||
|
uint32_t size,
|
||||||
|
nxtBufferMapReadCallback callback,
|
||||||
|
nxtCallbackUserdata userdata);
|
||||||
void Unmap();
|
void Unmap();
|
||||||
void TransitionUsage(nxt::BufferUsageBit usage);
|
void TransitionUsage(nxt::BufferUsageBit usage);
|
||||||
void FreezeUsage(nxt::BufferUsageBit usage);
|
void FreezeUsage(nxt::BufferUsageBit usage);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CallMapReadCallback(uint32_t serial, nxtBufferMapReadStatus status, const void* pointer);
|
void CallMapReadCallback(uint32_t serial,
|
||||||
|
nxtBufferMapReadStatus status,
|
||||||
|
const void* pointer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) = 0;
|
virtual void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) = 0;
|
||||||
virtual void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t size) = 0;
|
virtual void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t size) = 0;
|
||||||
virtual void UnmapImpl() = 0;
|
virtual void UnmapImpl() = 0;
|
||||||
virtual void TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) = 0;
|
virtual void TransitionUsageImpl(nxt::BufferUsageBit currentUsage,
|
||||||
|
nxt::BufferUsageBit targetUsage) = 0;
|
||||||
|
|
||||||
DeviceBase* mDevice;
|
DeviceBase* mDevice;
|
||||||
uint32_t mSize;
|
uint32_t mSize;
|
||||||
@ -121,6 +127,6 @@ namespace backend {
|
|||||||
int mPropertiesSet = 0;
|
int mPropertiesSet = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_BUFFER_H_
|
#endif // BACKEND_BUFFER_H_
|
||||||
|
@ -44,7 +44,8 @@ namespace backend {
|
|||||||
|
|
||||||
BuilderBase::~BuilderBase() {
|
BuilderBase::~BuilderBase() {
|
||||||
if (!mIsConsumed && mCallback != nullptr) {
|
if (!mIsConsumed && mCallback != nullptr) {
|
||||||
mCallback(NXT_BUILDER_ERROR_STATUS_UNKNOWN, "Builder destroyed before GetResult", mUserdata1, mUserdata2);
|
mCallback(NXT_BUILDER_ERROR_STATUS_UNKNOWN, "Builder destroyed before GetResult",
|
||||||
|
mUserdata1, mUserdata2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,17 +79,19 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unhandled builder errors are promoted to device errors
|
// Unhandled builder errors are promoted to device errors
|
||||||
if (!mCallback) mDevice->HandleError(("Unhandled builder error: " + mStoredMessage).c_str());
|
if (!mCallback)
|
||||||
|
mDevice->HandleError(("Unhandled builder error: " + mStoredMessage).c_str());
|
||||||
} else {
|
} else {
|
||||||
ASSERT(mStoredStatus == nxt::BuilderErrorStatus::Success);
|
ASSERT(mStoredStatus == nxt::BuilderErrorStatus::Success);
|
||||||
ASSERT(mStoredMessage.empty());
|
ASSERT(mStoredMessage.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCallback != nullptr) {
|
if (mCallback != nullptr) {
|
||||||
mCallback(static_cast<nxtBuilderErrorStatus>(mStoredStatus), mStoredMessage.c_str(), mUserdata1, mUserdata2);
|
mCallback(static_cast<nxtBuilderErrorStatus>(mStoredStatus), mStoredMessage.c_str(),
|
||||||
|
mUserdata1, mUserdata2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result != nullptr;
|
return result != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -25,17 +25,15 @@
|
|||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
// This class implements behavior shared by all builders:
|
// This class implements behavior shared by all builders:
|
||||||
// - Tracking whether GetResult has been called already, needed by the
|
// - Tracking whether GetResult has been called already, needed by the autogenerated code to
|
||||||
// autogenerated code to prevent operations on "consumed" builders.
|
// prevent operations on "consumed" builders.
|
||||||
// - The error status callback of the API. The callback is guaranteed to be
|
// - The error status callback of the API. The callback is guaranteed to be called exactly once
|
||||||
// called exactly once with an error, a success, or "unknown" if the
|
// with an error, a success, or "unknown" if the builder is destroyed; also the builder
|
||||||
// builder is destroyed; also the builder callback cannot be called before
|
// callback cannot be called before either the object is destroyed or GetResult is called.
|
||||||
// either the object is destroyed or GetResult is called.
|
|
||||||
//
|
//
|
||||||
// It is possible for error to be generated before the error callback is
|
// It is possible for error to be generated before the error callback is registered when a
|
||||||
// registered when a builder "set" function performance validation inline.
|
// builder "set" function performance validation inline. Because of this we have to store the
|
||||||
// Because of this we have to store the status in the builder and defer
|
// status in the builder and defer calling the callback to GetResult.
|
||||||
// calling the callback to GetResult.
|
|
||||||
|
|
||||||
class BuilderBase : public RefCounted {
|
class BuilderBase : public RefCounted {
|
||||||
public:
|
public:
|
||||||
@ -48,7 +46,7 @@ namespace backend {
|
|||||||
void HandleError(const char* message);
|
void HandleError(const char* message);
|
||||||
|
|
||||||
// Internal API, to be used by builder and BackendProcTable only.
|
// Internal API, to be used by builder and BackendProcTable only.
|
||||||
// rReturns true for success cases, and calls the callback with appropriate status.
|
// Returns true for success cases, and calls the callback with appropriate status.
|
||||||
bool HandleResult(RefCounted* result);
|
bool HandleResult(RefCounted* result);
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
@ -76,11 +74,10 @@ namespace backend {
|
|||||||
bool mIsConsumed = false;
|
bool mIsConsumed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This builder base class is used to capture the calls to GetResult and make sure
|
// This builder base class is used to capture the calls to GetResult and make sure that either:
|
||||||
// that either:
|
|
||||||
// - There was an error, callback is called with an error and nullptr is returned.
|
// - There was an error, callback is called with an error and nullptr is returned.
|
||||||
// - There was no error, callback is called with success and a non-null T* is returned.
|
// - There was no error, callback is called with success and a non-null T* is returned.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
class Builder : public BuilderBase {
|
class Builder : public BuilderBase {
|
||||||
public:
|
public:
|
||||||
// NXT API
|
// NXT API
|
||||||
@ -93,11 +90,11 @@ namespace backend {
|
|||||||
virtual T* GetResultImpl() = 0;
|
virtual T* GetResultImpl() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T* Builder<T>::GetResult() {
|
T* Builder<T>::GetResult() {
|
||||||
T* result = GetResultImpl();
|
T* result = GetResultImpl();
|
||||||
// An object can have been returned but failed its initialization, so if an error
|
// An object can have been returned but failed its initialization, so if an error happened,
|
||||||
// happened, return nullptr instead of result.
|
// return nullptr instead of result.
|
||||||
if (HandleResult(result)) {
|
if (HandleResult(result)) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
@ -105,6 +102,6 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_BUILDER_H_
|
#endif // BACKEND_BUILDER_H_
|
||||||
|
@ -23,13 +23,12 @@
|
|||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
constexpr uint32_t EndOfBlock = UINT_MAX;//std::numeric_limits<uint32_t>::max();
|
constexpr uint32_t EndOfBlock = UINT_MAX; // std::numeric_limits<uint32_t>::max();
|
||||||
constexpr uint32_t AdditionalData = UINT_MAX - 1;//std::numeric_limits<uint32_t>::max();
|
constexpr uint32_t AdditionalData = UINT_MAX - 1; // std::numeric_limits<uint32_t>::max() - 1;
|
||||||
|
|
||||||
// TODO(cwallez@chromium.org): figure out a way to have more type safety for the iterator
|
// TODO(cwallez@chromium.org): figure out a way to have more type safety for the iterator
|
||||||
|
|
||||||
CommandIterator::CommandIterator()
|
CommandIterator::CommandIterator() : mEndOfBlock(EndOfBlock) {
|
||||||
: mEndOfBlock(EndOfBlock) {
|
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,8 +42,7 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandIterator::CommandIterator(CommandIterator&& other)
|
CommandIterator::CommandIterator(CommandIterator&& other) : mEndOfBlock(EndOfBlock) {
|
||||||
: mEndOfBlock(EndOfBlock) {
|
|
||||||
if (!other.IsEmpty()) {
|
if (!other.IsEmpty()) {
|
||||||
mBlocks = std::move(other.mBlocks);
|
mBlocks = std::move(other.mBlocks);
|
||||||
other.Reset();
|
other.Reset();
|
||||||
@ -80,9 +78,8 @@ namespace backend {
|
|||||||
mCurrentBlock = 0;
|
mCurrentBlock = 0;
|
||||||
|
|
||||||
if (mBlocks.empty()) {
|
if (mBlocks.empty()) {
|
||||||
// This will case the first NextCommandId call to try to move to the next
|
// This will case the first NextCommandId call to try to move to the next block and stop
|
||||||
// block and stop the iteration immediately, without special casing the
|
// the iteration immediately, without special casing the initialization.
|
||||||
// initialization.
|
|
||||||
mCurrentPtr = reinterpret_cast<uint8_t*>(&mEndOfBlock);
|
mCurrentPtr = reinterpret_cast<uint8_t*>(&mEndOfBlock);
|
||||||
mBlocks.emplace_back();
|
mBlocks.emplace_back();
|
||||||
mBlocks[0].size = sizeof(mEndOfBlock);
|
mBlocks[0].size = sizeof(mEndOfBlock);
|
||||||
@ -102,7 +99,8 @@ namespace backend {
|
|||||||
|
|
||||||
bool CommandIterator::NextCommandId(uint32_t* commandId) {
|
bool CommandIterator::NextCommandId(uint32_t* commandId) {
|
||||||
uint8_t* idPtr = AlignPtr(mCurrentPtr, alignof(uint32_t));
|
uint8_t* idPtr = AlignPtr(mCurrentPtr, alignof(uint32_t));
|
||||||
ASSERT(idPtr + sizeof(uint32_t) <= mBlocks[mCurrentBlock].block + mBlocks[mCurrentBlock].size);
|
ASSERT(idPtr + sizeof(uint32_t) <=
|
||||||
|
mBlocks[mCurrentBlock].block + mBlocks[mCurrentBlock].size);
|
||||||
|
|
||||||
uint32_t id = *reinterpret_cast<uint32_t*>(idPtr);
|
uint32_t id = *reinterpret_cast<uint32_t*>(idPtr);
|
||||||
|
|
||||||
@ -124,7 +122,8 @@ namespace backend {
|
|||||||
|
|
||||||
void* CommandIterator::NextCommand(size_t commandSize, size_t commandAlignment) {
|
void* CommandIterator::NextCommand(size_t commandSize, size_t commandAlignment) {
|
||||||
uint8_t* commandPtr = AlignPtr(mCurrentPtr, commandAlignment);
|
uint8_t* commandPtr = AlignPtr(mCurrentPtr, commandAlignment);
|
||||||
ASSERT(commandPtr + sizeof(commandSize) <= mBlocks[mCurrentBlock].block + mBlocks[mCurrentBlock].size);
|
ASSERT(commandPtr + sizeof(commandSize) <=
|
||||||
|
mBlocks[mCurrentBlock].block + mBlocks[mCurrentBlock].size);
|
||||||
|
|
||||||
mCurrentPtr = commandPtr + commandSize;
|
mCurrentPtr = commandPtr + commandSize;
|
||||||
return commandPtr;
|
return commandPtr;
|
||||||
@ -140,13 +139,18 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Potential TODO(cwallez@chromium.org):
|
// Potential TODO(cwallez@chromium.org):
|
||||||
// - Host the size and pointer to next block in the block itself to avoid having an allocation in the vector
|
// - Host the size and pointer to next block in the block itself to avoid having an allocation
|
||||||
// - Assume T's alignof is, say 64bits, static assert it, and make commandAlignment a constant in Allocate
|
// in the vector
|
||||||
// - Be able to optimize allocation to one block, for command buffers expected to live long to avoid cache misses
|
// - Assume T's alignof is, say 64bits, static assert it, and make commandAlignment a constant
|
||||||
// - Better block allocation, maybe have NXT API to say command buffer is going to have size close to another
|
// in Allocate
|
||||||
|
// - Be able to optimize allocation to one block, for command buffers expected to live long to
|
||||||
|
// avoid cache misses
|
||||||
|
// - Better block allocation, maybe have NXT API to say command buffer is going to have size
|
||||||
|
// close to another
|
||||||
|
|
||||||
CommandAllocator::CommandAllocator()
|
CommandAllocator::CommandAllocator()
|
||||||
: mCurrentPtr(reinterpret_cast<uint8_t*>(&mDummyEnum[0])), mEndPtr(reinterpret_cast<uint8_t*>(&mDummyEnum[1])) {
|
: mCurrentPtr(reinterpret_cast<uint8_t*>(&mDummyEnum[0])),
|
||||||
|
mEndPtr(reinterpret_cast<uint8_t*>(&mDummyEnum[1])) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandAllocator::~CommandAllocator() {
|
CommandAllocator::~CommandAllocator() {
|
||||||
@ -164,7 +168,9 @@ namespace backend {
|
|||||||
return std::move(mBlocks);
|
return std::move(mBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* CommandAllocator::Allocate(uint32_t commandId, size_t commandSize, size_t commandAlignment) {
|
uint8_t* CommandAllocator::Allocate(uint32_t commandId,
|
||||||
|
size_t commandSize,
|
||||||
|
size_t commandAlignment) {
|
||||||
ASSERT(mCurrentPtr != nullptr);
|
ASSERT(mCurrentPtr != nullptr);
|
||||||
ASSERT(mEndPtr != nullptr);
|
ASSERT(mEndPtr != nullptr);
|
||||||
ASSERT(commandId != EndOfBlock);
|
ASSERT(commandId != EndOfBlock);
|
||||||
@ -180,15 +186,15 @@ namespace backend {
|
|||||||
// When there is not enough space, we signal the EndOfBlock, so that the iterator nows to
|
// When there is not enough space, we signal the EndOfBlock, so that the iterator nows to
|
||||||
// move to the next one. EndOfBlock on the last block means the end of the commands.
|
// move to the next one. EndOfBlock on the last block means the end of the commands.
|
||||||
if (nextPtr + sizeof(uint32_t) > mEndPtr) {
|
if (nextPtr + sizeof(uint32_t) > mEndPtr) {
|
||||||
|
// Even if we are not able to get another block, the list of commands will be
|
||||||
// Even if we are not able to get another block, the list of commands will be well-formed
|
// well-formed and iterable as this block will be that last one.
|
||||||
// and iterable as this block will be that last one.
|
|
||||||
*idAlloc = EndOfBlock;
|
*idAlloc = EndOfBlock;
|
||||||
|
|
||||||
// Make sure we have space for current allocation, plus end of block and alignment padding
|
// Make sure we have space for current allocation, plus end of block and alignment
|
||||||
// for the first id.
|
// padding for the first id.
|
||||||
ASSERT(nextPtr > mCurrentPtr);
|
ASSERT(nextPtr > mCurrentPtr);
|
||||||
if (!GetNewBlock(static_cast<size_t>(nextPtr - mCurrentPtr) + sizeof(uint32_t) + alignof(uint32_t))) {
|
if (!GetNewBlock(static_cast<size_t>(nextPtr - mCurrentPtr) + sizeof(uint32_t) +
|
||||||
|
alignof(uint32_t))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return Allocate(commandId, commandSize, commandAlignment);
|
return Allocate(commandId, commandSize, commandAlignment);
|
||||||
@ -205,7 +211,8 @@ namespace backend {
|
|||||||
|
|
||||||
bool CommandAllocator::GetNewBlock(size_t minimumSize) {
|
bool CommandAllocator::GetNewBlock(size_t minimumSize) {
|
||||||
// Allocate blocks doubling sizes each time, to a maximum of 16k (or at least minimumSize).
|
// Allocate blocks doubling sizes each time, to a maximum of 16k (or at least minimumSize).
|
||||||
mLastAllocationSize = std::max(minimumSize, std::min(mLastAllocationSize * 2, size_t(16384)));
|
mLastAllocationSize =
|
||||||
|
std::max(minimumSize, std::min(mLastAllocationSize * 2, size_t(16384)));
|
||||||
|
|
||||||
uint8_t* block = reinterpret_cast<uint8_t*>(malloc(mLastAllocationSize));
|
uint8_t* block = reinterpret_cast<uint8_t*>(malloc(mLastAllocationSize));
|
||||||
if (block == nullptr) {
|
if (block == nullptr) {
|
||||||
@ -218,4 +225,4 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_COMMAND_ALLOCATOR_H_
|
#ifndef BACKEND_COMMAND_ALLOCATOR_H_
|
||||||
#define BACKEND_COMMAND_ALLOCATOR_H_
|
#define BACKEND_COMMAND_ALLOCATOR_H_
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
@ -71,15 +71,15 @@ namespace backend {
|
|||||||
CommandIterator(CommandAllocator&& allocator);
|
CommandIterator(CommandAllocator&& allocator);
|
||||||
CommandIterator& operator=(CommandAllocator&& allocator);
|
CommandIterator& operator=(CommandAllocator&& allocator);
|
||||||
|
|
||||||
template<typename E>
|
template <typename E>
|
||||||
bool NextCommandId(E* commandId) {
|
bool NextCommandId(E* commandId) {
|
||||||
return NextCommandId(reinterpret_cast<uint32_t*>(commandId));
|
return NextCommandId(reinterpret_cast<uint32_t*>(commandId));
|
||||||
}
|
}
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T* NextCommand() {
|
T* NextCommand() {
|
||||||
return reinterpret_cast<T*>(NextCommand(sizeof(T), alignof(T)));
|
return reinterpret_cast<T*>(NextCommand(sizeof(T), alignof(T)));
|
||||||
}
|
}
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T* NextData(size_t count) {
|
T* NextData(size_t count) {
|
||||||
return reinterpret_cast<T*>(NextData(sizeof(T) * count, alignof(T)));
|
return reinterpret_cast<T*>(NextData(sizeof(T) * count, alignof(T)));
|
||||||
}
|
}
|
||||||
@ -109,14 +109,15 @@ namespace backend {
|
|||||||
CommandAllocator();
|
CommandAllocator();
|
||||||
~CommandAllocator();
|
~CommandAllocator();
|
||||||
|
|
||||||
template<typename T, typename E>
|
template <typename T, typename E>
|
||||||
T* Allocate(E commandId) {
|
T* Allocate(E commandId) {
|
||||||
static_assert(sizeof(E) == sizeof(uint32_t), "");
|
static_assert(sizeof(E) == sizeof(uint32_t), "");
|
||||||
static_assert(alignof(E) == alignof(uint32_t), "");
|
static_assert(alignof(E) == alignof(uint32_t), "");
|
||||||
return reinterpret_cast<T*>(Allocate(static_cast<uint32_t>(commandId), sizeof(T), alignof(T)));
|
return reinterpret_cast<T*>(
|
||||||
|
Allocate(static_cast<uint32_t>(commandId), sizeof(T), alignof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T* AllocateData(size_t count) {
|
T* AllocateData(size_t count) {
|
||||||
return reinterpret_cast<T*>(AllocateData(sizeof(T) * count, alignof(T)));
|
return reinterpret_cast<T*>(AllocateData(sizeof(T) * count, alignof(T)));
|
||||||
}
|
}
|
||||||
@ -132,19 +133,18 @@ namespace backend {
|
|||||||
CommandBlocks mBlocks;
|
CommandBlocks mBlocks;
|
||||||
size_t mLastAllocationSize = 2048;
|
size_t mLastAllocationSize = 2048;
|
||||||
|
|
||||||
// Pointers to the current range of allocation in the block. Guaranteed to allow
|
// Pointers to the current range of allocation in the block. Guaranteed to allow for at
|
||||||
// for at least one uint32_t is not nullptr, so that the special EndOfBlock command id
|
// least one uint32_t is not nullptr, so that the special EndOfBlock command id can always
|
||||||
// can always be written.
|
// be written. Nullptr iff the blocks were moved out.
|
||||||
// Nullptr iff the blocks were moved out.
|
|
||||||
uint8_t* mCurrentPtr = nullptr;
|
uint8_t* mCurrentPtr = nullptr;
|
||||||
uint8_t* mEndPtr = nullptr;
|
uint8_t* mEndPtr = nullptr;
|
||||||
|
|
||||||
// Data used for the block range at initialization so that the first call to Allocate
|
// Data used for the block range at initialization so that the first call to Allocate sees
|
||||||
// sees there is not enough space and calls GetNewBlock. This avoids having to special
|
// there is not enough space and calls GetNewBlock. This avoids having to special case the
|
||||||
// case the initialization in Allocate.
|
// initialization in Allocate.
|
||||||
uint32_t mDummyEnum[1] = {0};
|
uint32_t mDummyEnum[1] = {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_COMMAND_ALLOCATOR_H_
|
#endif // BACKEND_COMMAND_ALLOCATOR_H_
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
#include "backend/BindGroup.h"
|
#include "backend/BindGroup.h"
|
||||||
#include "backend/Buffer.h"
|
#include "backend/Buffer.h"
|
||||||
#include "backend/Commands.h"
|
|
||||||
#include "backend/CommandBufferStateTracker.h"
|
#include "backend/CommandBufferStateTracker.h"
|
||||||
|
#include "backend/Commands.h"
|
||||||
#include "backend/ComputePipeline.h"
|
#include "backend/ComputePipeline.h"
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
#include "backend/InputState.h"
|
#include "backend/InputState.h"
|
||||||
@ -32,22 +32,27 @@ namespace backend {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool ValidateCopyLocationFitsInTexture(CommandBufferBuilder* builder, const TextureCopyLocation& location) {
|
bool ValidateCopyLocationFitsInTexture(CommandBufferBuilder* builder,
|
||||||
|
const TextureCopyLocation& location) {
|
||||||
const TextureBase* texture = location.texture.Get();
|
const TextureBase* texture = location.texture.Get();
|
||||||
if (location.level >= texture->GetNumMipLevels()) {
|
if (location.level >= texture->GetNumMipLevels()) {
|
||||||
builder->HandleError("Copy mip-level out of range");
|
builder->HandleError("Copy mip-level out of range");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All texture dimensions are in uint32_t so by doing checks in uint64_t we avoid overflows.
|
// All texture dimensions are in uint32_t so by doing checks in uint64_t we avoid
|
||||||
|
// overflows.
|
||||||
uint64_t level = location.level;
|
uint64_t level = location.level;
|
||||||
if (uint64_t(location.x) + uint64_t(location.width) > (static_cast<uint64_t>(texture->GetWidth()) >> level) ||
|
if (uint64_t(location.x) + uint64_t(location.width) >
|
||||||
uint64_t(location.y) + uint64_t(location.height) > (static_cast<uint64_t>(texture->GetHeight()) >> level)) {
|
(static_cast<uint64_t>(texture->GetWidth()) >> level) ||
|
||||||
|
uint64_t(location.y) + uint64_t(location.height) >
|
||||||
|
(static_cast<uint64_t>(texture->GetHeight()) >> level)) {
|
||||||
builder->HandleError("Copy would touch outside of the texture");
|
builder->HandleError("Copy would touch outside of the texture");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(cwallez@chromium.org): Check the depth bound differently for 2D arrays and 3D textures
|
// TODO(cwallez@chromium.org): Check the depth bound differently for 2D arrays and 3D
|
||||||
|
// textures
|
||||||
if (location.z != 0 || location.depth != 1) {
|
if (location.z != 0 || location.depth != 1) {
|
||||||
builder->HandleError("No support for z != 0 and depth != 1 for now");
|
builder->HandleError("No support for z != 0 and depth != 1 for now");
|
||||||
return false;
|
return false;
|
||||||
@ -61,7 +66,9 @@ namespace backend {
|
|||||||
return offset <= bufferSize && (size <= (bufferSize - offset));
|
return offset <= bufferSize && (size <= (bufferSize - offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValidateCopySizeFitsInBuffer(CommandBufferBuilder* builder, const BufferCopyLocation& location, uint32_t dataSize) {
|
bool ValidateCopySizeFitsInBuffer(CommandBufferBuilder* builder,
|
||||||
|
const BufferCopyLocation& location,
|
||||||
|
uint32_t dataSize) {
|
||||||
if (!FitsInBuffer(location.buffer.Get(), location.offset, dataSize)) {
|
if (!FitsInBuffer(location.buffer.Get(), location.offset, dataSize)) {
|
||||||
builder->HandleError("Copy would overflow the buffer");
|
builder->HandleError("Copy would overflow the buffer");
|
||||||
return false;
|
return false;
|
||||||
@ -70,8 +77,11 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValidateTexelBufferOffset(CommandBufferBuilder* builder, TextureBase* texture, const BufferCopyLocation& location) {
|
bool ValidateTexelBufferOffset(CommandBufferBuilder* builder,
|
||||||
uint32_t texelSize = static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat()));
|
TextureBase* texture,
|
||||||
|
const BufferCopyLocation& location) {
|
||||||
|
uint32_t texelSize =
|
||||||
|
static_cast<uint32_t>(TextureFormatPixelSize(texture->GetFormat()));
|
||||||
if (location.offset % texelSize != 0) {
|
if (location.offset % texelSize != 0) {
|
||||||
builder->HandleError("Buffer offset must be a multiple of the texel size");
|
builder->HandleError("Buffer offset must be a multiple of the texel size");
|
||||||
return false;
|
return false;
|
||||||
@ -80,7 +90,10 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComputeTextureCopyBufferSize(CommandBufferBuilder*, const TextureCopyLocation& location, uint32_t rowPitch, uint32_t* bufferSize) {
|
bool ComputeTextureCopyBufferSize(CommandBufferBuilder*,
|
||||||
|
const TextureCopyLocation& location,
|
||||||
|
uint32_t rowPitch,
|
||||||
|
uint32_t* bufferSize) {
|
||||||
// TODO(cwallez@chromium.org): check for overflows
|
// TODO(cwallez@chromium.org): check for overflows
|
||||||
*bufferSize = (rowPitch * (location.height - 1) + location.width) * location.depth;
|
*bufferSize = (rowPitch * (location.height - 1) + location.width) * location.depth;
|
||||||
|
|
||||||
@ -92,7 +105,9 @@ namespace backend {
|
|||||||
return texelSize * width;
|
return texelSize * width;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValidateRowPitch(CommandBufferBuilder* builder, const TextureCopyLocation& location, uint32_t rowPitch) {
|
bool ValidateRowPitch(CommandBufferBuilder* builder,
|
||||||
|
const TextureCopyLocation& location,
|
||||||
|
uint32_t rowPitch) {
|
||||||
if (rowPitch % kTextureRowPitchAlignment != 0) {
|
if (rowPitch % kTextureRowPitchAlignment != 0) {
|
||||||
builder->HandleError("Row pitch must be a multiple of 256");
|
builder->HandleError("Row pitch must be a multiple of 256");
|
||||||
return false;
|
return false;
|
||||||
@ -107,7 +122,7 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
CommandBufferBase::CommandBufferBase(CommandBufferBuilder* builder)
|
CommandBufferBase::CommandBufferBase(CommandBufferBuilder* builder)
|
||||||
: mDevice(builder->mDevice),
|
: mDevice(builder->mDevice),
|
||||||
@ -137,125 +152,86 @@ namespace backend {
|
|||||||
|
|
||||||
void FreeCommands(CommandIterator* commands) {
|
void FreeCommands(CommandIterator* commands) {
|
||||||
Command type;
|
Command type;
|
||||||
while(commands->NextCommandId(&type)) {
|
while (commands->NextCommandId(&type)) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Command::BeginComputePass:
|
case Command::BeginComputePass: {
|
||||||
{
|
|
||||||
BeginComputePassCmd* begin = commands->NextCommand<BeginComputePassCmd>();
|
BeginComputePassCmd* begin = commands->NextCommand<BeginComputePassCmd>();
|
||||||
begin->~BeginComputePassCmd();
|
begin->~BeginComputePassCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::BeginRenderPass: {
|
||||||
case Command::BeginRenderPass:
|
|
||||||
{
|
|
||||||
BeginRenderPassCmd* begin = commands->NextCommand<BeginRenderPassCmd>();
|
BeginRenderPassCmd* begin = commands->NextCommand<BeginRenderPassCmd>();
|
||||||
begin->~BeginRenderPassCmd();
|
begin->~BeginRenderPassCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::BeginRenderSubpass: {
|
||||||
case Command::BeginRenderSubpass:
|
|
||||||
{
|
|
||||||
BeginRenderSubpassCmd* begin = commands->NextCommand<BeginRenderSubpassCmd>();
|
BeginRenderSubpassCmd* begin = commands->NextCommand<BeginRenderSubpassCmd>();
|
||||||
begin->~BeginRenderSubpassCmd();
|
begin->~BeginRenderSubpassCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::CopyBufferToBuffer: {
|
||||||
case Command::CopyBufferToBuffer:
|
|
||||||
{
|
|
||||||
CopyBufferToBufferCmd* copy = commands->NextCommand<CopyBufferToBufferCmd>();
|
CopyBufferToBufferCmd* copy = commands->NextCommand<CopyBufferToBufferCmd>();
|
||||||
copy->~CopyBufferToBufferCmd();
|
copy->~CopyBufferToBufferCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::CopyBufferToTexture: {
|
||||||
case Command::CopyBufferToTexture:
|
|
||||||
{
|
|
||||||
CopyBufferToTextureCmd* copy = commands->NextCommand<CopyBufferToTextureCmd>();
|
CopyBufferToTextureCmd* copy = commands->NextCommand<CopyBufferToTextureCmd>();
|
||||||
copy->~CopyBufferToTextureCmd();
|
copy->~CopyBufferToTextureCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::CopyTextureToBuffer: {
|
||||||
case Command::CopyTextureToBuffer:
|
|
||||||
{
|
|
||||||
CopyTextureToBufferCmd* copy = commands->NextCommand<CopyTextureToBufferCmd>();
|
CopyTextureToBufferCmd* copy = commands->NextCommand<CopyTextureToBufferCmd>();
|
||||||
copy->~CopyTextureToBufferCmd();
|
copy->~CopyTextureToBufferCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::Dispatch: {
|
||||||
case Command::Dispatch:
|
|
||||||
{
|
|
||||||
DispatchCmd* dispatch = commands->NextCommand<DispatchCmd>();
|
DispatchCmd* dispatch = commands->NextCommand<DispatchCmd>();
|
||||||
dispatch->~DispatchCmd();
|
dispatch->~DispatchCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::DrawArrays: {
|
||||||
case Command::DrawArrays:
|
|
||||||
{
|
|
||||||
DrawArraysCmd* draw = commands->NextCommand<DrawArraysCmd>();
|
DrawArraysCmd* draw = commands->NextCommand<DrawArraysCmd>();
|
||||||
draw->~DrawArraysCmd();
|
draw->~DrawArraysCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::DrawElements: {
|
||||||
case Command::DrawElements:
|
|
||||||
{
|
|
||||||
DrawElementsCmd* draw = commands->NextCommand<DrawElementsCmd>();
|
DrawElementsCmd* draw = commands->NextCommand<DrawElementsCmd>();
|
||||||
draw->~DrawElementsCmd();
|
draw->~DrawElementsCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::EndComputePass: {
|
||||||
case Command::EndComputePass:
|
|
||||||
{
|
|
||||||
EndComputePassCmd* cmd = commands->NextCommand<EndComputePassCmd>();
|
EndComputePassCmd* cmd = commands->NextCommand<EndComputePassCmd>();
|
||||||
cmd->~EndComputePassCmd();
|
cmd->~EndComputePassCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::EndRenderPass: {
|
||||||
case Command::EndRenderPass:
|
|
||||||
{
|
|
||||||
EndRenderPassCmd* cmd = commands->NextCommand<EndRenderPassCmd>();
|
EndRenderPassCmd* cmd = commands->NextCommand<EndRenderPassCmd>();
|
||||||
cmd->~EndRenderPassCmd();
|
cmd->~EndRenderPassCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::EndRenderSubpass: {
|
||||||
case Command::EndRenderSubpass:
|
|
||||||
{
|
|
||||||
EndRenderSubpassCmd* cmd = commands->NextCommand<EndRenderSubpassCmd>();
|
EndRenderSubpassCmd* cmd = commands->NextCommand<EndRenderSubpassCmd>();
|
||||||
cmd->~EndRenderSubpassCmd();
|
cmd->~EndRenderSubpassCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::SetComputePipeline: {
|
||||||
case Command::SetComputePipeline:
|
|
||||||
{
|
|
||||||
SetComputePipelineCmd* cmd = commands->NextCommand<SetComputePipelineCmd>();
|
SetComputePipelineCmd* cmd = commands->NextCommand<SetComputePipelineCmd>();
|
||||||
cmd->~SetComputePipelineCmd();
|
cmd->~SetComputePipelineCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::SetRenderPipeline: {
|
||||||
case Command::SetRenderPipeline:
|
|
||||||
{
|
|
||||||
SetRenderPipelineCmd* cmd = commands->NextCommand<SetRenderPipelineCmd>();
|
SetRenderPipelineCmd* cmd = commands->NextCommand<SetRenderPipelineCmd>();
|
||||||
cmd->~SetRenderPipelineCmd();
|
cmd->~SetRenderPipelineCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::SetPushConstants: {
|
||||||
case Command::SetPushConstants:
|
|
||||||
{
|
|
||||||
SetPushConstantsCmd* cmd = commands->NextCommand<SetPushConstantsCmd>();
|
SetPushConstantsCmd* cmd = commands->NextCommand<SetPushConstantsCmd>();
|
||||||
commands->NextData<uint32_t>(cmd->count);
|
commands->NextData<uint32_t>(cmd->count);
|
||||||
cmd->~SetPushConstantsCmd();
|
cmd->~SetPushConstantsCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::SetStencilReference: {
|
||||||
case Command::SetStencilReference:
|
|
||||||
{
|
|
||||||
SetStencilReferenceCmd* cmd = commands->NextCommand<SetStencilReferenceCmd>();
|
SetStencilReferenceCmd* cmd = commands->NextCommand<SetStencilReferenceCmd>();
|
||||||
cmd->~SetStencilReferenceCmd();
|
cmd->~SetStencilReferenceCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::SetBlendColor: {
|
||||||
case Command::SetBlendColor:
|
|
||||||
{
|
|
||||||
SetBlendColorCmd* cmd = commands->NextCommand<SetBlendColorCmd>();
|
SetBlendColorCmd* cmd = commands->NextCommand<SetBlendColorCmd>();
|
||||||
cmd->~SetBlendColorCmd();
|
cmd->~SetBlendColorCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::SetBindGroup: {
|
||||||
case Command::SetBindGroup:
|
|
||||||
{
|
|
||||||
SetBindGroupCmd* cmd = commands->NextCommand<SetBindGroupCmd>();
|
SetBindGroupCmd* cmd = commands->NextCommand<SetBindGroupCmd>();
|
||||||
cmd->~SetBindGroupCmd();
|
cmd->~SetBindGroupCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::SetIndexBuffer: {
|
||||||
case Command::SetIndexBuffer:
|
|
||||||
{
|
|
||||||
SetIndexBufferCmd* cmd = commands->NextCommand<SetIndexBufferCmd>();
|
SetIndexBufferCmd* cmd = commands->NextCommand<SetIndexBufferCmd>();
|
||||||
cmd->~SetIndexBufferCmd();
|
cmd->~SetIndexBufferCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::SetVertexBuffers: {
|
||||||
case Command::SetVertexBuffers:
|
|
||||||
{
|
|
||||||
SetVertexBuffersCmd* cmd = commands->NextCommand<SetVertexBuffersCmd>();
|
SetVertexBuffersCmd* cmd = commands->NextCommand<SetVertexBuffersCmd>();
|
||||||
auto buffers = commands->NextData<Ref<BufferBase>>(cmd->count);
|
auto buffers = commands->NextData<Ref<BufferBase>>(cmd->count);
|
||||||
for (size_t i = 0; i < cmd->count; ++i) {
|
for (size_t i = 0; i < cmd->count; ++i) {
|
||||||
@ -263,20 +239,17 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
commands->NextData<uint32_t>(cmd->count);
|
commands->NextData<uint32_t>(cmd->count);
|
||||||
cmd->~SetVertexBuffersCmd();
|
cmd->~SetVertexBuffersCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::TransitionBufferUsage: {
|
||||||
case Command::TransitionBufferUsage:
|
TransitionBufferUsageCmd* cmd =
|
||||||
{
|
commands->NextCommand<TransitionBufferUsageCmd>();
|
||||||
TransitionBufferUsageCmd* cmd = commands->NextCommand<TransitionBufferUsageCmd>();
|
|
||||||
cmd->~TransitionBufferUsageCmd();
|
cmd->~TransitionBufferUsageCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
case Command::TransitionTextureUsage: {
|
||||||
case Command::TransitionTextureUsage:
|
TransitionTextureUsageCmd* cmd =
|
||||||
{
|
commands->NextCommand<TransitionTextureUsageCmd>();
|
||||||
TransitionTextureUsageCmd* cmd = commands->NextCommand<TransitionTextureUsageCmd>();
|
|
||||||
cmd->~TransitionTextureUsageCmd();
|
cmd->~TransitionTextureUsageCmd();
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commands->DataWasDestroyed();
|
commands->DataWasDestroyed();
|
||||||
@ -340,12 +313,10 @@ namespace backend {
|
|||||||
commands->NextCommand<SetRenderPipelineCmd>();
|
commands->NextCommand<SetRenderPipelineCmd>();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::SetPushConstants:
|
case Command::SetPushConstants: {
|
||||||
{
|
|
||||||
auto* cmd = commands->NextCommand<SetPushConstantsCmd>();
|
auto* cmd = commands->NextCommand<SetPushConstantsCmd>();
|
||||||
commands->NextData<uint32_t>(cmd->count);
|
commands->NextData<uint32_t>(cmd->count);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetStencilReference:
|
case Command::SetStencilReference:
|
||||||
commands->NextCommand<SetStencilReferenceCmd>();
|
commands->NextCommand<SetStencilReferenceCmd>();
|
||||||
@ -363,13 +334,11 @@ namespace backend {
|
|||||||
commands->NextCommand<SetIndexBufferCmd>();
|
commands->NextCommand<SetIndexBufferCmd>();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::SetVertexBuffers:
|
case Command::SetVertexBuffers: {
|
||||||
{
|
|
||||||
auto* cmd = commands->NextCommand<SetVertexBuffersCmd>();
|
auto* cmd = commands->NextCommand<SetVertexBuffersCmd>();
|
||||||
commands->NextData<Ref<BufferBase>>(cmd->count);
|
commands->NextData<Ref<BufferBase>>(cmd->count);
|
||||||
commands->NextData<uint32_t>(cmd->count);
|
commands->NextData<uint32_t>(cmd->count);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::TransitionBufferUsage:
|
case Command::TransitionBufferUsage:
|
||||||
commands->NextCommand<TransitionBufferUsageCmd>();
|
commands->NextCommand<TransitionBufferUsageCmd>();
|
||||||
@ -381,7 +350,8 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBufferBuilder::CommandBufferBuilder(DeviceBase* device) : Builder(device), mState(std::make_unique<CommandBufferStateTracker>(this)) {
|
CommandBufferBuilder::CommandBufferBuilder(DeviceBase* device)
|
||||||
|
: Builder(device), mState(std::make_unique<CommandBufferStateTracker>(this)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBufferBuilder::~CommandBufferBuilder() {
|
CommandBufferBuilder::~CommandBufferBuilder() {
|
||||||
@ -397,17 +367,14 @@ namespace backend {
|
|||||||
Command type;
|
Command type;
|
||||||
while (mIterator.NextCommandId(&type)) {
|
while (mIterator.NextCommandId(&type)) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Command::BeginComputePass:
|
case Command::BeginComputePass: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<BeginComputePassCmd>();
|
mIterator.NextCommand<BeginComputePassCmd>();
|
||||||
if (!mState->BeginComputePass()) {
|
if (!mState->BeginComputePass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::BeginRenderPass:
|
case Command::BeginRenderPass: {
|
||||||
{
|
|
||||||
BeginRenderPassCmd* cmd = mIterator.NextCommand<BeginRenderPassCmd>();
|
BeginRenderPassCmd* cmd = mIterator.NextCommand<BeginRenderPassCmd>();
|
||||||
auto* renderPass = cmd->renderPass.Get();
|
auto* renderPass = cmd->renderPass.Get();
|
||||||
auto* framebuffer = cmd->framebuffer.Get();
|
auto* framebuffer = cmd->framebuffer.Get();
|
||||||
@ -423,193 +390,168 @@ namespace backend {
|
|||||||
if (!mState->BeginRenderPass(renderPass, framebuffer)) {
|
if (!mState->BeginRenderPass(renderPass, framebuffer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::BeginRenderSubpass:
|
case Command::BeginRenderSubpass: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<BeginRenderSubpassCmd>();
|
mIterator.NextCommand<BeginRenderSubpassCmd>();
|
||||||
if (!mState->BeginSubpass()) {
|
if (!mState->BeginSubpass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::CopyBufferToBuffer:
|
case Command::CopyBufferToBuffer: {
|
||||||
{
|
|
||||||
CopyBufferToBufferCmd* copy = mIterator.NextCommand<CopyBufferToBufferCmd>();
|
CopyBufferToBufferCmd* copy = mIterator.NextCommand<CopyBufferToBufferCmd>();
|
||||||
if (!ValidateCopySizeFitsInBuffer(this, copy->source, copy->size) ||
|
if (!ValidateCopySizeFitsInBuffer(this, copy->source, copy->size) ||
|
||||||
!ValidateCopySizeFitsInBuffer(this, copy->destination, copy->size) ||
|
!ValidateCopySizeFitsInBuffer(this, copy->destination, copy->size) ||
|
||||||
!mState->ValidateCanCopy() ||
|
!mState->ValidateCanCopy() ||
|
||||||
!mState->ValidateCanUseBufferAs(copy->source.buffer.Get(), nxt::BufferUsageBit::TransferSrc) ||
|
!mState->ValidateCanUseBufferAs(copy->source.buffer.Get(),
|
||||||
!mState->ValidateCanUseBufferAs(copy->destination.buffer.Get(), nxt::BufferUsageBit::TransferDst)) {
|
nxt::BufferUsageBit::TransferSrc) ||
|
||||||
|
!mState->ValidateCanUseBufferAs(copy->destination.buffer.Get(),
|
||||||
|
nxt::BufferUsageBit::TransferDst)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::CopyBufferToTexture:
|
case Command::CopyBufferToTexture: {
|
||||||
{
|
|
||||||
CopyBufferToTextureCmd* copy = mIterator.NextCommand<CopyBufferToTextureCmd>();
|
CopyBufferToTextureCmd* copy = mIterator.NextCommand<CopyBufferToTextureCmd>();
|
||||||
|
|
||||||
uint32_t bufferCopySize = 0;
|
uint32_t bufferCopySize = 0;
|
||||||
if (!ValidateRowPitch(this, copy->destination, copy->rowPitch) ||
|
if (!ValidateRowPitch(this, copy->destination, copy->rowPitch) ||
|
||||||
!ComputeTextureCopyBufferSize(this, copy->destination, copy->rowPitch, &bufferCopySize) ||
|
!ComputeTextureCopyBufferSize(this, copy->destination, copy->rowPitch,
|
||||||
|
&bufferCopySize) ||
|
||||||
!ValidateCopyLocationFitsInTexture(this, copy->destination) ||
|
!ValidateCopyLocationFitsInTexture(this, copy->destination) ||
|
||||||
!ValidateCopySizeFitsInBuffer(this, copy->source, bufferCopySize) ||
|
!ValidateCopySizeFitsInBuffer(this, copy->source, bufferCopySize) ||
|
||||||
!ValidateTexelBufferOffset(this, copy->destination.texture.Get(), copy->source) ||
|
!ValidateTexelBufferOffset(this, copy->destination.texture.Get(),
|
||||||
|
copy->source) ||
|
||||||
!mState->ValidateCanCopy() ||
|
!mState->ValidateCanCopy() ||
|
||||||
!mState->ValidateCanUseBufferAs(copy->source.buffer.Get(), nxt::BufferUsageBit::TransferSrc) ||
|
!mState->ValidateCanUseBufferAs(copy->source.buffer.Get(),
|
||||||
!mState->ValidateCanUseTextureAs(copy->destination.texture.Get(), nxt::TextureUsageBit::TransferDst)) {
|
nxt::BufferUsageBit::TransferSrc) ||
|
||||||
|
!mState->ValidateCanUseTextureAs(copy->destination.texture.Get(),
|
||||||
|
nxt::TextureUsageBit::TransferDst)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::CopyTextureToBuffer:
|
case Command::CopyTextureToBuffer: {
|
||||||
{
|
|
||||||
CopyTextureToBufferCmd* copy = mIterator.NextCommand<CopyTextureToBufferCmd>();
|
CopyTextureToBufferCmd* copy = mIterator.NextCommand<CopyTextureToBufferCmd>();
|
||||||
|
|
||||||
uint32_t bufferCopySize = 0;
|
uint32_t bufferCopySize = 0;
|
||||||
if (!ValidateRowPitch(this, copy->source, copy->rowPitch) ||
|
if (!ValidateRowPitch(this, copy->source, copy->rowPitch) ||
|
||||||
!ComputeTextureCopyBufferSize(this, copy->source, copy->rowPitch, &bufferCopySize) ||
|
!ComputeTextureCopyBufferSize(this, copy->source, copy->rowPitch,
|
||||||
|
&bufferCopySize) ||
|
||||||
!ValidateCopyLocationFitsInTexture(this, copy->source) ||
|
!ValidateCopyLocationFitsInTexture(this, copy->source) ||
|
||||||
!ValidateCopySizeFitsInBuffer(this, copy->destination, bufferCopySize) ||
|
!ValidateCopySizeFitsInBuffer(this, copy->destination, bufferCopySize) ||
|
||||||
!ValidateTexelBufferOffset(this, copy->source.texture.Get(), copy->destination) ||
|
!ValidateTexelBufferOffset(this, copy->source.texture.Get(),
|
||||||
|
copy->destination) ||
|
||||||
!mState->ValidateCanCopy() ||
|
!mState->ValidateCanCopy() ||
|
||||||
!mState->ValidateCanUseTextureAs(copy->source.texture.Get(), nxt::TextureUsageBit::TransferSrc) ||
|
!mState->ValidateCanUseTextureAs(copy->source.texture.Get(),
|
||||||
!mState->ValidateCanUseBufferAs(copy->destination.buffer.Get(), nxt::BufferUsageBit::TransferDst)) {
|
nxt::TextureUsageBit::TransferSrc) ||
|
||||||
|
!mState->ValidateCanUseBufferAs(copy->destination.buffer.Get(),
|
||||||
|
nxt::BufferUsageBit::TransferDst)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::Dispatch:
|
case Command::Dispatch: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<DispatchCmd>();
|
mIterator.NextCommand<DispatchCmd>();
|
||||||
if (!mState->ValidateCanDispatch()) {
|
if (!mState->ValidateCanDispatch()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::DrawArrays:
|
case Command::DrawArrays: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<DrawArraysCmd>();
|
mIterator.NextCommand<DrawArraysCmd>();
|
||||||
if (!mState->ValidateCanDrawArrays()) {
|
if (!mState->ValidateCanDrawArrays()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::DrawElements:
|
case Command::DrawElements: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<DrawElementsCmd>();
|
mIterator.NextCommand<DrawElementsCmd>();
|
||||||
if (!mState->ValidateCanDrawElements()) {
|
if (!mState->ValidateCanDrawElements()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::EndComputePass:
|
case Command::EndComputePass: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<EndComputePassCmd>();
|
mIterator.NextCommand<EndComputePassCmd>();
|
||||||
if (!mState->EndComputePass()) {
|
if (!mState->EndComputePass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::EndRenderPass:
|
case Command::EndRenderPass: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<EndRenderPassCmd>();
|
mIterator.NextCommand<EndRenderPassCmd>();
|
||||||
if (!mState->EndRenderPass()) {
|
if (!mState->EndRenderPass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::EndRenderSubpass:
|
case Command::EndRenderSubpass: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<EndRenderSubpassCmd>();
|
mIterator.NextCommand<EndRenderSubpassCmd>();
|
||||||
if (!mState->EndSubpass()) {
|
if (!mState->EndSubpass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetComputePipeline:
|
case Command::SetComputePipeline: {
|
||||||
{
|
|
||||||
SetComputePipelineCmd* cmd = mIterator.NextCommand<SetComputePipelineCmd>();
|
SetComputePipelineCmd* cmd = mIterator.NextCommand<SetComputePipelineCmd>();
|
||||||
ComputePipelineBase* pipeline = cmd->pipeline.Get();
|
ComputePipelineBase* pipeline = cmd->pipeline.Get();
|
||||||
if (!mState->SetComputePipeline(pipeline)) {
|
if (!mState->SetComputePipeline(pipeline)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetRenderPipeline:
|
case Command::SetRenderPipeline: {
|
||||||
{
|
|
||||||
SetRenderPipelineCmd* cmd = mIterator.NextCommand<SetRenderPipelineCmd>();
|
SetRenderPipelineCmd* cmd = mIterator.NextCommand<SetRenderPipelineCmd>();
|
||||||
RenderPipelineBase* pipeline = cmd->pipeline.Get();
|
RenderPipelineBase* pipeline = cmd->pipeline.Get();
|
||||||
if (!mState->SetRenderPipeline(pipeline)) {
|
if (!mState->SetRenderPipeline(pipeline)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetPushConstants:
|
case Command::SetPushConstants: {
|
||||||
{
|
|
||||||
SetPushConstantsCmd* cmd = mIterator.NextCommand<SetPushConstantsCmd>();
|
SetPushConstantsCmd* cmd = mIterator.NextCommand<SetPushConstantsCmd>();
|
||||||
mIterator.NextData<uint32_t>(cmd->count);
|
mIterator.NextData<uint32_t>(cmd->count);
|
||||||
// Validation of count and offset has already been done when the command was recorded
|
// Validation of count and offset has already been done when the command was
|
||||||
// because it impacts the size of an allocation in the CommandAllocator.
|
// recorded because it impacts the size of an allocation in the
|
||||||
|
// CommandAllocator.
|
||||||
if (!mState->ValidateSetPushConstants(cmd->stages)) {
|
if (!mState->ValidateSetPushConstants(cmd->stages)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetStencilReference:
|
case Command::SetStencilReference: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<SetStencilReferenceCmd>();
|
mIterator.NextCommand<SetStencilReferenceCmd>();
|
||||||
if (!mState->HaveRenderSubpass()) {
|
if (!mState->HaveRenderSubpass()) {
|
||||||
HandleError("Can't set stencil reference without an active render subpass");
|
HandleError("Can't set stencil reference without an active render subpass");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetBlendColor:
|
case Command::SetBlendColor: {
|
||||||
{
|
|
||||||
mIterator.NextCommand<SetBlendColorCmd>();
|
mIterator.NextCommand<SetBlendColorCmd>();
|
||||||
if (!mState->HaveRenderSubpass()) {
|
if (!mState->HaveRenderSubpass()) {
|
||||||
HandleError("Can't set blend color without an active render subpass");
|
HandleError("Can't set blend color without an active render subpass");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetBindGroup:
|
case Command::SetBindGroup: {
|
||||||
{
|
|
||||||
SetBindGroupCmd* cmd = mIterator.NextCommand<SetBindGroupCmd>();
|
SetBindGroupCmd* cmd = mIterator.NextCommand<SetBindGroupCmd>();
|
||||||
if (!mState->SetBindGroup(cmd->index, cmd->group.Get())) {
|
if (!mState->SetBindGroup(cmd->index, cmd->group.Get())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetIndexBuffer:
|
case Command::SetIndexBuffer: {
|
||||||
{
|
|
||||||
SetIndexBufferCmd* cmd = mIterator.NextCommand<SetIndexBufferCmd>();
|
SetIndexBufferCmd* cmd = mIterator.NextCommand<SetIndexBufferCmd>();
|
||||||
if (!mState->SetIndexBuffer(cmd->buffer.Get())) {
|
if (!mState->SetIndexBuffer(cmd->buffer.Get())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetVertexBuffers:
|
case Command::SetVertexBuffers: {
|
||||||
{
|
|
||||||
SetVertexBuffersCmd* cmd = mIterator.NextCommand<SetVertexBuffersCmd>();
|
SetVertexBuffersCmd* cmd = mIterator.NextCommand<SetVertexBuffersCmd>();
|
||||||
auto buffers = mIterator.NextData<Ref<BufferBase>>(cmd->count);
|
auto buffers = mIterator.NextData<Ref<BufferBase>>(cmd->count);
|
||||||
mIterator.NextData<uint32_t>(cmd->count);
|
mIterator.NextData<uint32_t>(cmd->count);
|
||||||
@ -617,27 +559,24 @@ namespace backend {
|
|||||||
for (uint32_t i = 0; i < cmd->count; ++i) {
|
for (uint32_t i = 0; i < cmd->count; ++i) {
|
||||||
mState->SetVertexBuffer(cmd->startSlot + i, buffers[i].Get());
|
mState->SetVertexBuffer(cmd->startSlot + i, buffers[i].Get());
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::TransitionBufferUsage:
|
case Command::TransitionBufferUsage: {
|
||||||
{
|
TransitionBufferUsageCmd* cmd =
|
||||||
TransitionBufferUsageCmd* cmd = mIterator.NextCommand<TransitionBufferUsageCmd>();
|
mIterator.NextCommand<TransitionBufferUsageCmd>();
|
||||||
if (!mState->TransitionBufferUsage(cmd->buffer.Get(), cmd->usage)) {
|
if (!mState->TransitionBufferUsage(cmd->buffer.Get(), cmd->usage)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::TransitionTextureUsage:
|
case Command::TransitionTextureUsage: {
|
||||||
{
|
TransitionTextureUsageCmd* cmd =
|
||||||
TransitionTextureUsageCmd* cmd = mIterator.NextCommand<TransitionTextureUsageCmd>();
|
mIterator.NextCommand<TransitionTextureUsageCmd>();
|
||||||
if (!mState->TransitionTextureUsage(cmd->texture.Get(), cmd->usage)) {
|
if (!mState->TransitionTextureUsage(cmd->texture.Get(), cmd->usage)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,9 +602,10 @@ namespace backend {
|
|||||||
mAllocator.Allocate<BeginComputePassCmd>(Command::BeginComputePass);
|
mAllocator.Allocate<BeginComputePassCmd>(Command::BeginComputePass);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::BeginRenderPass(RenderPassBase* renderPass, FramebufferBase* framebuffer) {
|
void CommandBufferBuilder::BeginRenderPass(RenderPassBase* renderPass,
|
||||||
|
FramebufferBase* framebuffer) {
|
||||||
BeginRenderPassCmd* cmd = mAllocator.Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
|
BeginRenderPassCmd* cmd = mAllocator.Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
|
||||||
new(cmd) BeginRenderPassCmd;
|
new (cmd) BeginRenderPassCmd;
|
||||||
cmd->renderPass = renderPass;
|
cmd->renderPass = renderPass;
|
||||||
cmd->framebuffer = framebuffer;
|
cmd->framebuffer = framebuffer;
|
||||||
}
|
}
|
||||||
@ -674,9 +614,14 @@ namespace backend {
|
|||||||
mAllocator.Allocate<BeginRenderSubpassCmd>(Command::BeginRenderSubpass);
|
mAllocator.Allocate<BeginRenderSubpassCmd>(Command::BeginRenderSubpass);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::CopyBufferToBuffer(BufferBase* source, uint32_t sourceOffset, BufferBase* destination, uint32_t destinationOffset, uint32_t size) {
|
void CommandBufferBuilder::CopyBufferToBuffer(BufferBase* source,
|
||||||
CopyBufferToBufferCmd* copy = mAllocator.Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
|
uint32_t sourceOffset,
|
||||||
new(copy) CopyBufferToBufferCmd;
|
BufferBase* destination,
|
||||||
|
uint32_t destinationOffset,
|
||||||
|
uint32_t size) {
|
||||||
|
CopyBufferToBufferCmd* copy =
|
||||||
|
mAllocator.Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
|
||||||
|
new (copy) CopyBufferToBufferCmd;
|
||||||
copy->source.buffer = source;
|
copy->source.buffer = source;
|
||||||
copy->source.offset = sourceOffset;
|
copy->source.offset = sourceOffset;
|
||||||
copy->destination.buffer = destination;
|
copy->destination.buffer = destination;
|
||||||
@ -684,14 +629,23 @@ namespace backend {
|
|||||||
copy->size = size;
|
copy->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::CopyBufferToTexture(BufferBase* buffer, uint32_t bufferOffset, uint32_t rowPitch,
|
void CommandBufferBuilder::CopyBufferToTexture(BufferBase* buffer,
|
||||||
TextureBase* texture, uint32_t x, uint32_t y, uint32_t z,
|
uint32_t bufferOffset,
|
||||||
uint32_t width, uint32_t height, uint32_t depth, uint32_t level) {
|
uint32_t rowPitch,
|
||||||
|
TextureBase* texture,
|
||||||
|
uint32_t x,
|
||||||
|
uint32_t y,
|
||||||
|
uint32_t z,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t depth,
|
||||||
|
uint32_t level) {
|
||||||
if (rowPitch == 0) {
|
if (rowPitch == 0) {
|
||||||
rowPitch = ComputeDefaultRowPitch(texture, width);
|
rowPitch = ComputeDefaultRowPitch(texture, width);
|
||||||
}
|
}
|
||||||
CopyBufferToTextureCmd* copy = mAllocator.Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
|
CopyBufferToTextureCmd* copy =
|
||||||
new(copy) CopyBufferToTextureCmd;
|
mAllocator.Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
|
||||||
|
new (copy) CopyBufferToTextureCmd;
|
||||||
copy->source.buffer = buffer;
|
copy->source.buffer = buffer;
|
||||||
copy->source.offset = bufferOffset;
|
copy->source.offset = bufferOffset;
|
||||||
copy->destination.texture = texture;
|
copy->destination.texture = texture;
|
||||||
@ -705,14 +659,23 @@ namespace backend {
|
|||||||
copy->rowPitch = rowPitch;
|
copy->rowPitch = rowPitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::CopyTextureToBuffer(TextureBase* texture, uint32_t x, uint32_t y, uint32_t z,
|
void CommandBufferBuilder::CopyTextureToBuffer(TextureBase* texture,
|
||||||
uint32_t width, uint32_t height, uint32_t depth, uint32_t level,
|
uint32_t x,
|
||||||
BufferBase* buffer, uint32_t bufferOffset, uint32_t rowPitch) {
|
uint32_t y,
|
||||||
|
uint32_t z,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t depth,
|
||||||
|
uint32_t level,
|
||||||
|
BufferBase* buffer,
|
||||||
|
uint32_t bufferOffset,
|
||||||
|
uint32_t rowPitch) {
|
||||||
if (rowPitch == 0) {
|
if (rowPitch == 0) {
|
||||||
rowPitch = ComputeDefaultRowPitch(texture, width);
|
rowPitch = ComputeDefaultRowPitch(texture, width);
|
||||||
}
|
}
|
||||||
CopyTextureToBufferCmd* copy = mAllocator.Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
|
CopyTextureToBufferCmd* copy =
|
||||||
new(copy) CopyTextureToBufferCmd;
|
mAllocator.Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
|
||||||
|
new (copy) CopyTextureToBufferCmd;
|
||||||
copy->source.texture = texture;
|
copy->source.texture = texture;
|
||||||
copy->source.x = x;
|
copy->source.x = x;
|
||||||
copy->source.y = y;
|
copy->source.y = y;
|
||||||
@ -728,24 +691,30 @@ namespace backend {
|
|||||||
|
|
||||||
void CommandBufferBuilder::Dispatch(uint32_t x, uint32_t y, uint32_t z) {
|
void CommandBufferBuilder::Dispatch(uint32_t x, uint32_t y, uint32_t z) {
|
||||||
DispatchCmd* dispatch = mAllocator.Allocate<DispatchCmd>(Command::Dispatch);
|
DispatchCmd* dispatch = mAllocator.Allocate<DispatchCmd>(Command::Dispatch);
|
||||||
new(dispatch) DispatchCmd;
|
new (dispatch) DispatchCmd;
|
||||||
dispatch->x = x;
|
dispatch->x = x;
|
||||||
dispatch->y = y;
|
dispatch->y = y;
|
||||||
dispatch->z = z;
|
dispatch->z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::DrawArrays(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) {
|
void CommandBufferBuilder::DrawArrays(uint32_t vertexCount,
|
||||||
|
uint32_t instanceCount,
|
||||||
|
uint32_t firstVertex,
|
||||||
|
uint32_t firstInstance) {
|
||||||
DrawArraysCmd* draw = mAllocator.Allocate<DrawArraysCmd>(Command::DrawArrays);
|
DrawArraysCmd* draw = mAllocator.Allocate<DrawArraysCmd>(Command::DrawArrays);
|
||||||
new(draw) DrawArraysCmd;
|
new (draw) DrawArraysCmd;
|
||||||
draw->vertexCount = vertexCount;
|
draw->vertexCount = vertexCount;
|
||||||
draw->instanceCount = instanceCount;
|
draw->instanceCount = instanceCount;
|
||||||
draw->firstVertex = firstVertex;
|
draw->firstVertex = firstVertex;
|
||||||
draw->firstInstance = firstInstance;
|
draw->firstInstance = firstInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::DrawElements(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t firstInstance) {
|
void CommandBufferBuilder::DrawElements(uint32_t indexCount,
|
||||||
|
uint32_t instanceCount,
|
||||||
|
uint32_t firstIndex,
|
||||||
|
uint32_t firstInstance) {
|
||||||
DrawElementsCmd* draw = mAllocator.Allocate<DrawElementsCmd>(Command::DrawElements);
|
DrawElementsCmd* draw = mAllocator.Allocate<DrawElementsCmd>(Command::DrawElements);
|
||||||
new(draw) DrawElementsCmd;
|
new (draw) DrawElementsCmd;
|
||||||
draw->indexCount = indexCount;
|
draw->indexCount = indexCount;
|
||||||
draw->instanceCount = instanceCount;
|
draw->instanceCount = instanceCount;
|
||||||
draw->firstIndex = firstIndex;
|
draw->firstIndex = firstIndex;
|
||||||
@ -765,26 +734,32 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::SetComputePipeline(ComputePipelineBase* pipeline) {
|
void CommandBufferBuilder::SetComputePipeline(ComputePipelineBase* pipeline) {
|
||||||
SetComputePipelineCmd* cmd = mAllocator.Allocate<SetComputePipelineCmd>(Command::SetComputePipeline);
|
SetComputePipelineCmd* cmd =
|
||||||
new(cmd) SetComputePipelineCmd;
|
mAllocator.Allocate<SetComputePipelineCmd>(Command::SetComputePipeline);
|
||||||
|
new (cmd) SetComputePipelineCmd;
|
||||||
cmd->pipeline = pipeline;
|
cmd->pipeline = pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::SetRenderPipeline(RenderPipelineBase* pipeline) {
|
void CommandBufferBuilder::SetRenderPipeline(RenderPipelineBase* pipeline) {
|
||||||
SetRenderPipelineCmd* cmd = mAllocator.Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline);
|
SetRenderPipelineCmd* cmd =
|
||||||
new(cmd) SetRenderPipelineCmd;
|
mAllocator.Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline);
|
||||||
|
new (cmd) SetRenderPipelineCmd;
|
||||||
cmd->pipeline = pipeline;
|
cmd->pipeline = pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::SetPushConstants(nxt::ShaderStageBit stages, uint32_t offset, uint32_t count, const void* data) {
|
void CommandBufferBuilder::SetPushConstants(nxt::ShaderStageBit stages,
|
||||||
|
uint32_t offset,
|
||||||
|
uint32_t count,
|
||||||
|
const void* data) {
|
||||||
// TODO(cwallez@chromium.org): check for overflows
|
// TODO(cwallez@chromium.org): check for overflows
|
||||||
if (offset + count > kMaxPushConstants) {
|
if (offset + count > kMaxPushConstants) {
|
||||||
HandleError("Setting too many push constants");
|
HandleError("Setting too many push constants");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPushConstantsCmd* cmd = mAllocator.Allocate<SetPushConstantsCmd>(Command::SetPushConstants);
|
SetPushConstantsCmd* cmd =
|
||||||
new(cmd) SetPushConstantsCmd;
|
mAllocator.Allocate<SetPushConstantsCmd>(Command::SetPushConstants);
|
||||||
|
new (cmd) SetPushConstantsCmd;
|
||||||
cmd->stages = stages;
|
cmd->stages = stages;
|
||||||
cmd->offset = offset;
|
cmd->offset = offset;
|
||||||
cmd->count = count;
|
cmd->count = count;
|
||||||
@ -794,14 +769,15 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::SetStencilReference(uint32_t reference) {
|
void CommandBufferBuilder::SetStencilReference(uint32_t reference) {
|
||||||
SetStencilReferenceCmd* cmd = mAllocator.Allocate<SetStencilReferenceCmd>(Command::SetStencilReference);
|
SetStencilReferenceCmd* cmd =
|
||||||
new(cmd) SetStencilReferenceCmd;
|
mAllocator.Allocate<SetStencilReferenceCmd>(Command::SetStencilReference);
|
||||||
|
new (cmd) SetStencilReferenceCmd;
|
||||||
cmd->reference = reference;
|
cmd->reference = reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::SetBlendColor(float r, float g, float b, float a) {
|
void CommandBufferBuilder::SetBlendColor(float r, float g, float b, float a) {
|
||||||
SetBlendColorCmd* cmd = mAllocator.Allocate<SetBlendColorCmd>(Command::SetBlendColor);
|
SetBlendColorCmd* cmd = mAllocator.Allocate<SetBlendColorCmd>(Command::SetBlendColor);
|
||||||
new(cmd) SetBlendColorCmd;
|
new (cmd) SetBlendColorCmd;
|
||||||
cmd->r = r;
|
cmd->r = r;
|
||||||
cmd->g = g;
|
cmd->g = g;
|
||||||
cmd->b = b;
|
cmd->b = b;
|
||||||
@ -815,7 +791,7 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetBindGroupCmd* cmd = mAllocator.Allocate<SetBindGroupCmd>(Command::SetBindGroup);
|
SetBindGroupCmd* cmd = mAllocator.Allocate<SetBindGroupCmd>(Command::SetBindGroup);
|
||||||
new(cmd) SetBindGroupCmd;
|
new (cmd) SetBindGroupCmd;
|
||||||
cmd->index = groupIndex;
|
cmd->index = groupIndex;
|
||||||
cmd->group = group;
|
cmd->group = group;
|
||||||
}
|
}
|
||||||
@ -824,38 +800,46 @@ namespace backend {
|
|||||||
// TODO(kainino@chromium.org): validation
|
// TODO(kainino@chromium.org): validation
|
||||||
|
|
||||||
SetIndexBufferCmd* cmd = mAllocator.Allocate<SetIndexBufferCmd>(Command::SetIndexBuffer);
|
SetIndexBufferCmd* cmd = mAllocator.Allocate<SetIndexBufferCmd>(Command::SetIndexBuffer);
|
||||||
new(cmd) SetIndexBufferCmd;
|
new (cmd) SetIndexBufferCmd;
|
||||||
cmd->buffer = buffer;
|
cmd->buffer = buffer;
|
||||||
cmd->offset = offset;
|
cmd->offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::SetVertexBuffers(uint32_t startSlot, uint32_t count, BufferBase* const* buffers, uint32_t const* offsets){
|
void CommandBufferBuilder::SetVertexBuffers(uint32_t startSlot,
|
||||||
|
uint32_t count,
|
||||||
|
BufferBase* const* buffers,
|
||||||
|
uint32_t const* offsets) {
|
||||||
// TODO(kainino@chromium.org): validation
|
// TODO(kainino@chromium.org): validation
|
||||||
|
|
||||||
SetVertexBuffersCmd* cmd = mAllocator.Allocate<SetVertexBuffersCmd>(Command::SetVertexBuffers);
|
SetVertexBuffersCmd* cmd =
|
||||||
new(cmd) SetVertexBuffersCmd;
|
mAllocator.Allocate<SetVertexBuffersCmd>(Command::SetVertexBuffers);
|
||||||
|
new (cmd) SetVertexBuffersCmd;
|
||||||
cmd->startSlot = startSlot;
|
cmd->startSlot = startSlot;
|
||||||
cmd->count = count;
|
cmd->count = count;
|
||||||
|
|
||||||
Ref<BufferBase>* cmdBuffers = mAllocator.AllocateData<Ref<BufferBase>>(count);
|
Ref<BufferBase>* cmdBuffers = mAllocator.AllocateData<Ref<BufferBase>>(count);
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
new(&cmdBuffers[i]) Ref<BufferBase>(buffers[i]);
|
new (&cmdBuffers[i]) Ref<BufferBase>(buffers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t* cmdOffsets = mAllocator.AllocateData<uint32_t>(count);
|
uint32_t* cmdOffsets = mAllocator.AllocateData<uint32_t>(count);
|
||||||
memcpy(cmdOffsets, offsets, count * sizeof(uint32_t));
|
memcpy(cmdOffsets, offsets, count * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::TransitionBufferUsage(BufferBase* buffer, nxt::BufferUsageBit usage) {
|
void CommandBufferBuilder::TransitionBufferUsage(BufferBase* buffer,
|
||||||
TransitionBufferUsageCmd* cmd = mAllocator.Allocate<TransitionBufferUsageCmd>(Command::TransitionBufferUsage);
|
nxt::BufferUsageBit usage) {
|
||||||
new(cmd) TransitionBufferUsageCmd;
|
TransitionBufferUsageCmd* cmd =
|
||||||
|
mAllocator.Allocate<TransitionBufferUsageCmd>(Command::TransitionBufferUsage);
|
||||||
|
new (cmd) TransitionBufferUsageCmd;
|
||||||
cmd->buffer = buffer;
|
cmd->buffer = buffer;
|
||||||
cmd->usage = usage;
|
cmd->usage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBuilder::TransitionTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage) {
|
void CommandBufferBuilder::TransitionTextureUsage(TextureBase* texture,
|
||||||
TransitionTextureUsageCmd* cmd = mAllocator.Allocate<TransitionTextureUsageCmd>(Command::TransitionTextureUsage);
|
nxt::TextureUsageBit usage) {
|
||||||
new(cmd) TransitionTextureUsageCmd;
|
TransitionTextureUsageCmd* cmd =
|
||||||
|
mAllocator.Allocate<TransitionTextureUsageCmd>(Command::TransitionTextureUsage);
|
||||||
|
new (cmd) TransitionTextureUsageCmd;
|
||||||
cmd->texture = texture;
|
cmd->texture = texture;
|
||||||
cmd->usage = usage;
|
cmd->usage = usage;
|
||||||
}
|
}
|
||||||
@ -867,4 +851,4 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
|
|
||||||
#include "backend/CommandAllocator.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/CommandAllocator.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -64,20 +64,49 @@ namespace backend {
|
|||||||
void BeginComputePass();
|
void BeginComputePass();
|
||||||
void BeginRenderPass(RenderPassBase* renderPass, FramebufferBase* framebuffer);
|
void BeginRenderPass(RenderPassBase* renderPass, FramebufferBase* framebuffer);
|
||||||
void BeginRenderSubpass();
|
void BeginRenderSubpass();
|
||||||
void CopyBufferToBuffer(BufferBase* source, uint32_t sourceOffset, BufferBase* destination, uint32_t destinationOffset, uint32_t size);
|
void CopyBufferToBuffer(BufferBase* source,
|
||||||
void CopyBufferToTexture(BufferBase* buffer, uint32_t bufferOffset, uint32_t rowPitch,
|
uint32_t sourceOffset,
|
||||||
TextureBase* texture, uint32_t x, uint32_t y, uint32_t z,
|
BufferBase* destination,
|
||||||
uint32_t width, uint32_t height, uint32_t depth, uint32_t level);
|
uint32_t destinationOffset,
|
||||||
void CopyTextureToBuffer(TextureBase* texture, uint32_t x, uint32_t y, uint32_t z,
|
uint32_t size);
|
||||||
uint32_t width, uint32_t height, uint32_t depth, uint32_t level,
|
void CopyBufferToTexture(BufferBase* buffer,
|
||||||
BufferBase* buffer, uint32_t bufferOffset, uint32_t rowPitch);
|
uint32_t bufferOffset,
|
||||||
|
uint32_t rowPitch,
|
||||||
|
TextureBase* texture,
|
||||||
|
uint32_t x,
|
||||||
|
uint32_t y,
|
||||||
|
uint32_t z,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t depth,
|
||||||
|
uint32_t level);
|
||||||
|
void CopyTextureToBuffer(TextureBase* texture,
|
||||||
|
uint32_t x,
|
||||||
|
uint32_t y,
|
||||||
|
uint32_t z,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height,
|
||||||
|
uint32_t depth,
|
||||||
|
uint32_t level,
|
||||||
|
BufferBase* buffer,
|
||||||
|
uint32_t bufferOffset,
|
||||||
|
uint32_t rowPitch);
|
||||||
void Dispatch(uint32_t x, uint32_t y, uint32_t z);
|
void Dispatch(uint32_t x, uint32_t y, uint32_t z);
|
||||||
void DrawArrays(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
|
void DrawArrays(uint32_t vertexCount,
|
||||||
void DrawElements(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t firstInstance);
|
uint32_t instanceCount,
|
||||||
|
uint32_t firstVertex,
|
||||||
|
uint32_t firstInstance);
|
||||||
|
void DrawElements(uint32_t vertexCount,
|
||||||
|
uint32_t instanceCount,
|
||||||
|
uint32_t firstIndex,
|
||||||
|
uint32_t firstInstance);
|
||||||
void EndComputePass();
|
void EndComputePass();
|
||||||
void EndRenderPass();
|
void EndRenderPass();
|
||||||
void EndRenderSubpass();
|
void EndRenderSubpass();
|
||||||
void SetPushConstants(nxt::ShaderStageBit stages, uint32_t offset, uint32_t count, const void* data);
|
void SetPushConstants(nxt::ShaderStageBit stages,
|
||||||
|
uint32_t offset,
|
||||||
|
uint32_t count,
|
||||||
|
const void* data);
|
||||||
void SetComputePipeline(ComputePipelineBase* pipeline);
|
void SetComputePipeline(ComputePipelineBase* pipeline);
|
||||||
void SetRenderPipeline(RenderPipelineBase* pipeline);
|
void SetRenderPipeline(RenderPipelineBase* pipeline);
|
||||||
void SetStencilReference(uint32_t reference);
|
void SetStencilReference(uint32_t reference);
|
||||||
@ -85,12 +114,19 @@ namespace backend {
|
|||||||
void SetBindGroup(uint32_t groupIndex, BindGroupBase* group);
|
void SetBindGroup(uint32_t groupIndex, BindGroupBase* group);
|
||||||
void SetIndexBuffer(BufferBase* buffer, uint32_t offset);
|
void SetIndexBuffer(BufferBase* buffer, uint32_t offset);
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void SetVertexBuffers(uint32_t startSlot, uint32_t count, T* const* buffers, uint32_t const* offsets) {
|
void SetVertexBuffers(uint32_t startSlot,
|
||||||
|
uint32_t count,
|
||||||
|
T* const* buffers,
|
||||||
|
uint32_t const* offsets) {
|
||||||
static_assert(std::is_base_of<BufferBase, T>::value, "");
|
static_assert(std::is_base_of<BufferBase, T>::value, "");
|
||||||
SetVertexBuffers(startSlot, count, reinterpret_cast<BufferBase* const*>(buffers), offsets);
|
SetVertexBuffers(startSlot, count, reinterpret_cast<BufferBase* const*>(buffers),
|
||||||
|
offsets);
|
||||||
}
|
}
|
||||||
void SetVertexBuffers(uint32_t startSlot, uint32_t count, BufferBase* const* buffers, uint32_t const* offsets);
|
void SetVertexBuffers(uint32_t startSlot,
|
||||||
|
uint32_t count,
|
||||||
|
BufferBase* const* buffers,
|
||||||
|
uint32_t const* offsets);
|
||||||
|
|
||||||
void TransitionBufferUsage(BufferBase* buffer, nxt::BufferUsageBit usage);
|
void TransitionBufferUsage(BufferBase* buffer, nxt::BufferUsageBit usage);
|
||||||
void TransitionTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage);
|
void TransitionTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage);
|
||||||
@ -108,6 +144,6 @@ namespace backend {
|
|||||||
bool mWereCommandsAcquired = false;
|
bool mWereCommandsAcquired = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_COMMANDBUFFER_H_
|
#endif // BACKEND_COMMANDBUFFER_H_
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
|
|
||||||
#include "backend/CommandBufferStateTracker.h"
|
#include "backend/CommandBufferStateTracker.h"
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/BindGroup.h"
|
#include "backend/BindGroup.h"
|
||||||
#include "backend/BindGroupLayout.h"
|
#include "backend/BindGroupLayout.h"
|
||||||
#include "backend/Buffer.h"
|
#include "backend/Buffer.h"
|
||||||
#include "backend/ComputePipeline.h"
|
#include "backend/ComputePipeline.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/Framebuffer.h"
|
#include "backend/Framebuffer.h"
|
||||||
#include "backend/InputState.h"
|
#include "backend/InputState.h"
|
||||||
#include "backend/PipelineLayout.h"
|
#include "backend/PipelineLayout.h"
|
||||||
@ -49,7 +49,8 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::ValidateCanUseBufferAs(BufferBase* buffer, nxt::BufferUsageBit usage) const {
|
bool CommandBufferStateTracker::ValidateCanUseBufferAs(BufferBase* buffer,
|
||||||
|
nxt::BufferUsageBit usage) const {
|
||||||
if (!BufferHasGuaranteedUsageBit(buffer, usage)) {
|
if (!BufferHasGuaranteedUsageBit(buffer, usage)) {
|
||||||
mBuilder->HandleError("Buffer is not in the necessary usage");
|
mBuilder->HandleError("Buffer is not in the necessary usage");
|
||||||
return false;
|
return false;
|
||||||
@ -57,7 +58,8 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::ValidateCanUseTextureAs(TextureBase* texture, nxt::TextureUsageBit usage) const {
|
bool CommandBufferStateTracker::ValidateCanUseTextureAs(TextureBase* texture,
|
||||||
|
nxt::TextureUsageBit usage) const {
|
||||||
if (!TextureHasGuaranteedUsageBit(texture, usage)) {
|
if (!TextureHasGuaranteedUsageBit(texture, usage)) {
|
||||||
mBuilder->HandleError("Texture is not in the necessary usage");
|
mBuilder->HandleError("Texture is not in the necessary usage");
|
||||||
return false;
|
return false;
|
||||||
@ -90,8 +92,7 @@ namespace backend {
|
|||||||
// TODO(kainino@chromium.org): Check for a current render pass
|
// TODO(kainino@chromium.org): Check for a current render pass
|
||||||
constexpr ValidationAspects requiredAspects =
|
constexpr ValidationAspects requiredAspects =
|
||||||
1 << VALIDATION_ASPECT_RENDER_PIPELINE | // implicitly requires RENDER_SUBPASS
|
1 << VALIDATION_ASPECT_RENDER_PIPELINE | // implicitly requires RENDER_SUBPASS
|
||||||
1 << VALIDATION_ASPECT_BIND_GROUPS |
|
1 << VALIDATION_ASPECT_BIND_GROUPS | 1 << VALIDATION_ASPECT_VERTEX_BUFFERS;
|
||||||
1 << VALIDATION_ASPECT_VERTEX_BUFFERS;
|
|
||||||
if ((requiredAspects & ~mAspects).none()) {
|
if ((requiredAspects & ~mAspects).none()) {
|
||||||
// Fast return-true path if everything is good
|
// Fast return-true path if everything is good
|
||||||
return true;
|
return true;
|
||||||
@ -103,10 +104,8 @@ namespace backend {
|
|||||||
bool CommandBufferStateTracker::ValidateCanDrawElements() {
|
bool CommandBufferStateTracker::ValidateCanDrawElements() {
|
||||||
// TODO(kainino@chromium.org): Check for a current render pass
|
// TODO(kainino@chromium.org): Check for a current render pass
|
||||||
constexpr ValidationAspects requiredAspects =
|
constexpr ValidationAspects requiredAspects =
|
||||||
1 << VALIDATION_ASPECT_RENDER_PIPELINE |
|
1 << VALIDATION_ASPECT_RENDER_PIPELINE | 1 << VALIDATION_ASPECT_BIND_GROUPS |
|
||||||
1 << VALIDATION_ASPECT_BIND_GROUPS |
|
1 << VALIDATION_ASPECT_VERTEX_BUFFERS | 1 << VALIDATION_ASPECT_INDEX_BUFFER;
|
||||||
1 << VALIDATION_ASPECT_VERTEX_BUFFERS |
|
|
||||||
1 << VALIDATION_ASPECT_INDEX_BUFFER;
|
|
||||||
if ((requiredAspects & ~mAspects).none()) {
|
if ((requiredAspects & ~mAspects).none()) {
|
||||||
// Fast return-true path if everything is good
|
// Fast return-true path if everything is good
|
||||||
return true;
|
return true;
|
||||||
@ -134,16 +133,19 @@ namespace backend {
|
|||||||
bool CommandBufferStateTracker::ValidateSetPushConstants(nxt::ShaderStageBit stages) {
|
bool CommandBufferStateTracker::ValidateSetPushConstants(nxt::ShaderStageBit stages) {
|
||||||
if (mAspects[VALIDATION_ASPECT_COMPUTE_PASS]) {
|
if (mAspects[VALIDATION_ASPECT_COMPUTE_PASS]) {
|
||||||
if (stages & ~nxt::ShaderStageBit::Compute) {
|
if (stages & ~nxt::ShaderStageBit::Compute) {
|
||||||
mBuilder->HandleError("SetPushConstants stage must be compute or 0 in compute passes");
|
mBuilder->HandleError(
|
||||||
|
"SetPushConstants stage must be compute or 0 in compute passes");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (mAspects[VALIDATION_ASPECT_RENDER_SUBPASS]) {
|
} else if (mAspects[VALIDATION_ASPECT_RENDER_SUBPASS]) {
|
||||||
if (stages & ~(nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment)) {
|
if (stages & ~(nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment)) {
|
||||||
mBuilder->HandleError("SetPushConstants stage must be a subset if (vertex|fragment) in subpasses");
|
mBuilder->HandleError(
|
||||||
|
"SetPushConstants stage must be a subset if (vertex|fragment) in subpasses");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mBuilder->HandleError("PushConstants must be set in either compute passes or subpasses");
|
mBuilder->HandleError(
|
||||||
|
"PushConstants must be set in either compute passes or subpasses");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -224,7 +226,8 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::BeginRenderPass(RenderPassBase* renderPass, FramebufferBase* framebuffer) {
|
bool CommandBufferStateTracker::BeginRenderPass(RenderPassBase* renderPass,
|
||||||
|
FramebufferBase* framebuffer) {
|
||||||
if (mAspects[VALIDATION_ASPECT_COMPUTE_PASS]) {
|
if (mAspects[VALIDATION_ASPECT_COMPUTE_PASS]) {
|
||||||
mBuilder->HandleError("Cannot begin a render pass while a compute pass is active");
|
mBuilder->HandleError("Cannot begin a render pass while a compute pass is active");
|
||||||
return false;
|
return false;
|
||||||
@ -338,7 +341,8 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::TransitionBufferUsage(BufferBase* buffer, nxt::BufferUsageBit usage) {
|
bool CommandBufferStateTracker::TransitionBufferUsage(BufferBase* buffer,
|
||||||
|
nxt::BufferUsageBit usage) {
|
||||||
if (!buffer->IsTransitionPossible(usage)) {
|
if (!buffer->IsTransitionPossible(usage)) {
|
||||||
if (buffer->IsFrozen()) {
|
if (buffer->IsFrozen()) {
|
||||||
mBuilder->HandleError("Buffer transition not possible (usage is frozen)");
|
mBuilder->HandleError("Buffer transition not possible (usage is frozen)");
|
||||||
@ -355,14 +359,17 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::TransitionTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage) {
|
bool CommandBufferStateTracker::TransitionTextureUsage(TextureBase* texture,
|
||||||
|
nxt::TextureUsageBit usage) {
|
||||||
if (!IsExplicitTextureTransitionPossible(texture, usage)) {
|
if (!IsExplicitTextureTransitionPossible(texture, usage)) {
|
||||||
if (texture->IsFrozen()) {
|
if (texture->IsFrozen()) {
|
||||||
mBuilder->HandleError("Texture transition not possible (usage is frozen)");
|
mBuilder->HandleError("Texture transition not possible (usage is frozen)");
|
||||||
} else if (!TextureBase::IsUsagePossible(texture->GetAllowedUsage(), usage)) {
|
} else if (!TextureBase::IsUsagePossible(texture->GetAllowedUsage(), usage)) {
|
||||||
mBuilder->HandleError("Texture transition not possible (usage not allowed)");
|
mBuilder->HandleError("Texture transition not possible (usage not allowed)");
|
||||||
} else if (mTexturesAttached.find(texture) != mTexturesAttached.end()) {
|
} else if (mTexturesAttached.find(texture) != mTexturesAttached.end()) {
|
||||||
mBuilder->HandleError("Texture transition not possible (texture is in use as a framebuffer attachment)");
|
mBuilder->HandleError(
|
||||||
|
"Texture transition not possible (texture is in use as a framebuffer "
|
||||||
|
"attachment)");
|
||||||
} else {
|
} else {
|
||||||
mBuilder->HandleError("Texture transition not possible");
|
mBuilder->HandleError("Texture transition not possible");
|
||||||
}
|
}
|
||||||
@ -374,7 +381,8 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::EnsureTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage) {
|
bool CommandBufferStateTracker::EnsureTextureUsage(TextureBase* texture,
|
||||||
|
nxt::TextureUsageBit usage) {
|
||||||
if (texture->HasFrozenUsage(usage)) {
|
if (texture->HasFrozenUsage(usage)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -386,7 +394,8 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::BufferHasGuaranteedUsageBit(BufferBase* buffer, nxt::BufferUsageBit usage) const {
|
bool CommandBufferStateTracker::BufferHasGuaranteedUsageBit(BufferBase* buffer,
|
||||||
|
nxt::BufferUsageBit usage) const {
|
||||||
ASSERT(usage != nxt::BufferUsageBit::None && nxt::HasZeroOrOneBits(usage));
|
ASSERT(usage != nxt::BufferUsageBit::None && nxt::HasZeroOrOneBits(usage));
|
||||||
if (buffer->HasFrozenUsage(usage)) {
|
if (buffer->HasFrozenUsage(usage)) {
|
||||||
return true;
|
return true;
|
||||||
@ -395,7 +404,8 @@ namespace backend {
|
|||||||
return it != mMostRecentBufferUsages.end() && (it->second & usage);
|
return it != mMostRecentBufferUsages.end() && (it->second & usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::TextureHasGuaranteedUsageBit(TextureBase* texture, nxt::TextureUsageBit usage) const {
|
bool CommandBufferStateTracker::TextureHasGuaranteedUsageBit(TextureBase* texture,
|
||||||
|
nxt::TextureUsageBit usage) const {
|
||||||
ASSERT(usage != nxt::TextureUsageBit::None && nxt::HasZeroOrOneBits(usage));
|
ASSERT(usage != nxt::TextureUsageBit::None && nxt::HasZeroOrOneBits(usage));
|
||||||
if (texture->HasFrozenUsage(usage)) {
|
if (texture->HasFrozenUsage(usage)) {
|
||||||
return true;
|
return true;
|
||||||
@ -404,7 +414,9 @@ namespace backend {
|
|||||||
return it != mMostRecentTextureUsages.end() && (it->second & usage);
|
return it != mMostRecentTextureUsages.end() && (it->second & usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::IsInternalTextureTransitionPossible(TextureBase* texture, nxt::TextureUsageBit usage) const {
|
bool CommandBufferStateTracker::IsInternalTextureTransitionPossible(
|
||||||
|
TextureBase* texture,
|
||||||
|
nxt::TextureUsageBit usage) const {
|
||||||
ASSERT(usage != nxt::TextureUsageBit::None && nxt::HasZeroOrOneBits(usage));
|
ASSERT(usage != nxt::TextureUsageBit::None && nxt::HasZeroOrOneBits(usage));
|
||||||
if (mTexturesAttached.find(texture) != mTexturesAttached.end()) {
|
if (mTexturesAttached.find(texture) != mTexturesAttached.end()) {
|
||||||
return false;
|
return false;
|
||||||
@ -412,9 +424,10 @@ namespace backend {
|
|||||||
return texture->IsTransitionPossible(usage);
|
return texture->IsTransitionPossible(usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferStateTracker::IsExplicitTextureTransitionPossible(TextureBase* texture, nxt::TextureUsageBit usage) const {
|
bool CommandBufferStateTracker::IsExplicitTextureTransitionPossible(
|
||||||
const nxt::TextureUsageBit attachmentUsages =
|
TextureBase* texture,
|
||||||
nxt::TextureUsageBit::OutputAttachment;
|
nxt::TextureUsageBit usage) const {
|
||||||
|
const nxt::TextureUsageBit attachmentUsages = nxt::TextureUsageBit::OutputAttachment;
|
||||||
if (usage & attachmentUsages) {
|
if (usage & attachmentUsages) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -456,8 +469,7 @@ namespace backend {
|
|||||||
|
|
||||||
bool CommandBufferStateTracker::HavePipeline() const {
|
bool CommandBufferStateTracker::HavePipeline() const {
|
||||||
constexpr ValidationAspects pipelineAspects =
|
constexpr ValidationAspects pipelineAspects =
|
||||||
1 << VALIDATION_ASPECT_COMPUTE_PIPELINE |
|
1 << VALIDATION_ASPECT_COMPUTE_PIPELINE | 1 << VALIDATION_ASPECT_RENDER_PIPELINE;
|
||||||
1 << VALIDATION_ASPECT_RENDER_PIPELINE;
|
|
||||||
return (mAspects & pipelineAspects).any();
|
return (mAspects & pipelineAspects).any();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,8 +483,7 @@ namespace backend {
|
|||||||
nxt::BindingType type = layoutInfo.types[i];
|
nxt::BindingType type = layoutInfo.types[i];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case nxt::BindingType::UniformBuffer:
|
case nxt::BindingType::UniformBuffer:
|
||||||
case nxt::BindingType::StorageBuffer:
|
case nxt::BindingType::StorageBuffer: {
|
||||||
{
|
|
||||||
nxt::BufferUsageBit requiredUsage = nxt::BufferUsageBit::None;
|
nxt::BufferUsageBit requiredUsage = nxt::BufferUsageBit::None;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case nxt::BindingType::UniformBuffer:
|
case nxt::BindingType::UniformBuffer:
|
||||||
@ -492,10 +503,8 @@ namespace backend {
|
|||||||
mBuilder->HandleError("Can't guarantee buffer usage needed by bind group");
|
mBuilder->HandleError("Can't guarantee buffer usage needed by bind group");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
case nxt::BindingType::SampledTexture: {
|
||||||
case nxt::BindingType::SampledTexture:
|
|
||||||
{
|
|
||||||
auto requiredUsage = nxt::TextureUsageBit::Sampled;
|
auto requiredUsage = nxt::TextureUsageBit::Sampled;
|
||||||
|
|
||||||
auto texture = group->GetBindingAsTextureView(i)->GetTexture();
|
auto texture = group->GetBindingAsTextureView(i)->GetTexture();
|
||||||
@ -503,8 +512,7 @@ namespace backend {
|
|||||||
mBuilder->HandleError("Can't guarantee texture usage needed by bind group");
|
mBuilder->HandleError("Can't guarantee texture usage needed by bind group");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case nxt::BindingType::Sampler:
|
case nxt::BindingType::Sampler:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -547,12 +555,10 @@ namespace backend {
|
|||||||
|
|
||||||
void CommandBufferStateTracker::UnsetPipeline() {
|
void CommandBufferStateTracker::UnsetPipeline() {
|
||||||
constexpr ValidationAspects pipelineDependentAspects =
|
constexpr ValidationAspects pipelineDependentAspects =
|
||||||
1 << VALIDATION_ASPECT_RENDER_PIPELINE |
|
1 << VALIDATION_ASPECT_RENDER_PIPELINE | 1 << VALIDATION_ASPECT_COMPUTE_PIPELINE |
|
||||||
1 << VALIDATION_ASPECT_COMPUTE_PIPELINE |
|
1 << VALIDATION_ASPECT_BIND_GROUPS | 1 << VALIDATION_ASPECT_VERTEX_BUFFERS |
|
||||||
1 << VALIDATION_ASPECT_BIND_GROUPS |
|
|
||||||
1 << VALIDATION_ASPECT_VERTEX_BUFFERS |
|
|
||||||
1 << VALIDATION_ASPECT_INDEX_BUFFER;
|
1 << VALIDATION_ASPECT_INDEX_BUFFER;
|
||||||
mAspects &= ~pipelineDependentAspects;
|
mAspects &= ~pipelineDependentAspects;
|
||||||
mBindgroups.fill(nullptr);
|
mBindgroups.fill(nullptr);
|
||||||
}
|
}
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -56,9 +56,9 @@ namespace backend {
|
|||||||
bool TransitionTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage);
|
bool TransitionTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage);
|
||||||
bool EnsureTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage);
|
bool EnsureTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage);
|
||||||
|
|
||||||
// These collections are copied to the CommandBuffer at build time.
|
// These collections are copied to the CommandBuffer at build time. These pointers will
|
||||||
// These pointers will remain valid since they are referenced by
|
// remain valid since they are referenced by the bind groups which are referenced by this
|
||||||
// the bind groups which are referenced by this command buffer.
|
// command buffer.
|
||||||
std::set<BufferBase*> mBuffersTransitioned;
|
std::set<BufferBase*> mBuffersTransitioned;
|
||||||
std::set<TextureBase*> mTexturesTransitioned;
|
std::set<TextureBase*> mTexturesTransitioned;
|
||||||
std::set<TextureBase*> mTexturesAttached;
|
std::set<TextureBase*> mTexturesAttached;
|
||||||
@ -80,8 +80,10 @@ namespace backend {
|
|||||||
// Usage helper functions
|
// Usage helper functions
|
||||||
bool BufferHasGuaranteedUsageBit(BufferBase* buffer, nxt::BufferUsageBit usage) const;
|
bool BufferHasGuaranteedUsageBit(BufferBase* buffer, nxt::BufferUsageBit usage) const;
|
||||||
bool TextureHasGuaranteedUsageBit(TextureBase* texture, nxt::TextureUsageBit usage) const;
|
bool TextureHasGuaranteedUsageBit(TextureBase* texture, nxt::TextureUsageBit usage) const;
|
||||||
bool IsInternalTextureTransitionPossible(TextureBase* texture, nxt::TextureUsageBit usage) const;
|
bool IsInternalTextureTransitionPossible(TextureBase* texture,
|
||||||
bool IsExplicitTextureTransitionPossible(TextureBase* texture, nxt::TextureUsageBit usage) const;
|
nxt::TextureUsageBit usage) const;
|
||||||
|
bool IsExplicitTextureTransitionPossible(TextureBase* texture,
|
||||||
|
nxt::TextureUsageBit usage) const;
|
||||||
|
|
||||||
// Queries for lazily evaluated aspects
|
// Queries for lazily evaluated aspects
|
||||||
bool RecomputeHaveAspectBindGroups();
|
bool RecomputeHaveAspectBindGroups();
|
||||||
@ -111,6 +113,6 @@ namespace backend {
|
|||||||
FramebufferBase* mCurrentFramebuffer = nullptr;
|
FramebufferBase* mCurrentFramebuffer = nullptr;
|
||||||
uint32_t mCurrentSubpass = 0;
|
uint32_t mCurrentSubpass = 0;
|
||||||
};
|
};
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_COMMANDBUFFERSTATETRACKER_H
|
#endif // BACKEND_COMMANDBUFFERSTATETRACKER_H
|
||||||
|
@ -52,16 +52,14 @@ namespace backend {
|
|||||||
TransitionTextureUsage,
|
TransitionTextureUsage,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BeginComputePassCmd {
|
struct BeginComputePassCmd {};
|
||||||
};
|
|
||||||
|
|
||||||
struct BeginRenderPassCmd {
|
struct BeginRenderPassCmd {
|
||||||
Ref<RenderPassBase> renderPass;
|
Ref<RenderPassBase> renderPass;
|
||||||
Ref<FramebufferBase> framebuffer;
|
Ref<FramebufferBase> framebuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BeginRenderSubpassCmd {
|
struct BeginRenderSubpassCmd {};
|
||||||
};
|
|
||||||
|
|
||||||
struct BufferCopyLocation {
|
struct BufferCopyLocation {
|
||||||
Ref<BufferBase> buffer;
|
Ref<BufferBase> buffer;
|
||||||
@ -113,14 +111,11 @@ namespace backend {
|
|||||||
uint32_t firstInstance;
|
uint32_t firstInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EndComputePassCmd {
|
struct EndComputePassCmd {};
|
||||||
};
|
|
||||||
|
|
||||||
struct EndRenderPassCmd {
|
struct EndRenderPassCmd {};
|
||||||
};
|
|
||||||
|
|
||||||
struct EndRenderSubpassCmd {
|
struct EndRenderSubpassCmd {};
|
||||||
};
|
|
||||||
|
|
||||||
struct SetComputePipelineCmd {
|
struct SetComputePipelineCmd {
|
||||||
Ref<ComputePipelineBase> pipeline;
|
Ref<ComputePipelineBase> pipeline;
|
||||||
@ -176,6 +171,6 @@ namespace backend {
|
|||||||
void FreeCommands(CommandIterator* commands);
|
void FreeCommands(CommandIterator* commands);
|
||||||
void SkipCommand(CommandIterator* commands, Command type);
|
void SkipCommand(CommandIterator* commands, Command type);
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_COMMANDS_H_
|
#endif // BACKEND_COMMANDS_H_
|
||||||
|
@ -38,4 +38,4 @@ namespace backend {
|
|||||||
return mDevice->CreateComputePipeline(this);
|
return mDevice->CreateComputePipeline(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -22,7 +22,6 @@ namespace backend {
|
|||||||
class ComputePipelineBase : public RefCounted, public PipelineBase {
|
class ComputePipelineBase : public RefCounted, public PipelineBase {
|
||||||
public:
|
public:
|
||||||
ComputePipelineBase(ComputePipelineBuilder* builder);
|
ComputePipelineBase(ComputePipelineBuilder* builder);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComputePipelineBuilder : public Builder<ComputePipelineBase>, public PipelineBuilder {
|
class ComputePipelineBuilder : public Builder<ComputePipelineBase>, public PipelineBuilder {
|
||||||
@ -33,6 +32,6 @@ namespace backend {
|
|||||||
ComputePipelineBase* GetResultImpl() override;
|
ComputePipelineBase* GetResultImpl() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_COMPUTEPIPELINE_H_
|
#endif // BACKEND_COMPUTEPIPELINE_H_
|
||||||
|
@ -60,7 +60,8 @@ namespace backend {
|
|||||||
return mDevice->CreateDepthStencilState(this);
|
return mDevice->CreateDepthStencilState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthStencilStateBuilder::SetDepthCompareFunction(nxt::CompareFunction depthCompareFunction) {
|
void DepthStencilStateBuilder::SetDepthCompareFunction(
|
||||||
|
nxt::CompareFunction depthCompareFunction) {
|
||||||
if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_DEPTH_COMPARE_FUNCTION) != 0) {
|
if ((mPropertiesSet & DEPTH_STENCIL_STATE_PROPERTY_DEPTH_COMPARE_FUNCTION) != 0) {
|
||||||
HandleError("Depth compare property set multiple times");
|
HandleError("Depth compare property set multiple times");
|
||||||
return;
|
return;
|
||||||
@ -82,8 +83,11 @@ namespace backend {
|
|||||||
mDepthInfo.depthWriteEnabled = enabled;
|
mDepthInfo.depthWriteEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthStencilStateBuilder::SetStencilFunction(nxt::Face face, nxt::CompareFunction stencilCompareFunction,
|
void DepthStencilStateBuilder::SetStencilFunction(nxt::Face face,
|
||||||
nxt::StencilOperation stencilFail, nxt::StencilOperation depthFail, nxt::StencilOperation depthStencilPass) {\
|
nxt::CompareFunction stencilCompareFunction,
|
||||||
|
nxt::StencilOperation stencilFail,
|
||||||
|
nxt::StencilOperation depthFail,
|
||||||
|
nxt::StencilOperation depthStencilPass) {
|
||||||
if (face == nxt::Face::None) {
|
if (face == nxt::Face::None) {
|
||||||
HandleError("Can't set stencil function of None face");
|
HandleError("Can't set stencil function of None face");
|
||||||
return;
|
return;
|
||||||
@ -128,4 +132,4 @@ namespace backend {
|
|||||||
mStencilInfo.writeMask = writeMask;
|
mStencilInfo.writeMask = writeMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,15 +15,14 @@
|
|||||||
#ifndef BACKEND_DEPTHSTENCILSTATE_H_
|
#ifndef BACKEND_DEPTHSTENCILSTATE_H_
|
||||||
#define BACKEND_DEPTHSTENCILSTATE_H_
|
#define BACKEND_DEPTHSTENCILSTATE_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
|
||||||
class DepthStencilStateBase : public RefCounted {
|
class DepthStencilStateBase : public RefCounted {
|
||||||
public:
|
public:
|
||||||
DepthStencilStateBase(DepthStencilStateBuilder* builder);
|
DepthStencilStateBase(DepthStencilStateBuilder* builder);
|
||||||
@ -63,8 +62,11 @@ namespace backend {
|
|||||||
// NXT API
|
// NXT API
|
||||||
void SetDepthCompareFunction(nxt::CompareFunction depthCompareFunction);
|
void SetDepthCompareFunction(nxt::CompareFunction depthCompareFunction);
|
||||||
void SetDepthWriteEnabled(bool enabled);
|
void SetDepthWriteEnabled(bool enabled);
|
||||||
void SetStencilFunction(nxt::Face face, nxt::CompareFunction stencilCompareFunction,
|
void SetStencilFunction(nxt::Face face,
|
||||||
nxt::StencilOperation stencilFail, nxt::StencilOperation depthFail, nxt::StencilOperation depthStencilPass);
|
nxt::CompareFunction stencilCompareFunction,
|
||||||
|
nxt::StencilOperation stencilFail,
|
||||||
|
nxt::StencilOperation depthFail,
|
||||||
|
nxt::StencilOperation depthStencilPass);
|
||||||
void SetStencilMask(uint32_t readMask, uint32_t writeMask);
|
void SetStencilMask(uint32_t readMask, uint32_t writeMask);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -78,6 +80,6 @@ namespace backend {
|
|||||||
DepthStencilStateBase::StencilInfo mStencilInfo;
|
DepthStencilStateBase::StencilInfo mStencilInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_DEPTHSTENCILSTATE_H_
|
#endif // BACKEND_DEPTHSTENCILSTATE_H_
|
||||||
|
@ -40,7 +40,8 @@ namespace backend {
|
|||||||
|
|
||||||
// The caches are unordered_sets of pointers with special hash and compare functions
|
// The caches are unordered_sets of pointers with special hash and compare functions
|
||||||
// to compare the value of the objects, instead of the pointers.
|
// to compare the value of the objects, instead of the pointers.
|
||||||
using BindGroupLayoutCache = std::unordered_set<BindGroupLayoutBase*, BindGroupLayoutCacheFuncs, BindGroupLayoutCacheFuncs>;
|
using BindGroupLayoutCache = std::
|
||||||
|
unordered_set<BindGroupLayoutBase*, BindGroupLayoutCacheFuncs, BindGroupLayoutCacheFuncs>;
|
||||||
|
|
||||||
struct DeviceBase::Caches {
|
struct DeviceBase::Caches {
|
||||||
BindGroupLayoutCache bindGroupLayouts;
|
BindGroupLayoutCache bindGroupLayouts;
|
||||||
@ -62,7 +63,8 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::SetErrorCallback(nxt::DeviceErrorCallback callback, nxt::CallbackUserdata userdata) {
|
void DeviceBase::SetErrorCallback(nxt::DeviceErrorCallback callback,
|
||||||
|
nxt::CallbackUserdata userdata) {
|
||||||
mErrorCallback = callback;
|
mErrorCallback = callback;
|
||||||
mErrorUserdata = userdata;
|
mErrorUserdata = userdata;
|
||||||
}
|
}
|
||||||
@ -71,7 +73,9 @@ namespace backend {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
BindGroupLayoutBase* DeviceBase::GetOrCreateBindGroupLayout(const BindGroupLayoutBase* blueprint, BindGroupLayoutBuilder* builder) {
|
BindGroupLayoutBase* DeviceBase::GetOrCreateBindGroupLayout(
|
||||||
|
const BindGroupLayoutBase* blueprint,
|
||||||
|
BindGroupLayoutBuilder* builder) {
|
||||||
// The blueprint is only used to search in the cache and is not modified. However cached
|
// The blueprint is only used to search in the cache and is not modified. However cached
|
||||||
// objects can be modified, and unordered_set cannot search for a const pointer in a non
|
// objects can be modified, and unordered_set cannot search for a const pointer in a non
|
||||||
// const pointer set. That's why we do a const_cast here, but the blueprint won't be
|
// const pointer set. That's why we do a const_cast here, but the blueprint won't be
|
||||||
@ -159,4 +163,4 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -41,7 +41,8 @@ namespace backend {
|
|||||||
virtual BufferViewBase* CreateBufferView(BufferViewBuilder* builder) = 0;
|
virtual BufferViewBase* CreateBufferView(BufferViewBuilder* builder) = 0;
|
||||||
virtual CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) = 0;
|
virtual CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) = 0;
|
||||||
virtual ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) = 0;
|
virtual ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) = 0;
|
||||||
virtual DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) = 0;
|
virtual DepthStencilStateBase* CreateDepthStencilState(
|
||||||
|
DepthStencilStateBuilder* builder) = 0;
|
||||||
virtual FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) = 0;
|
virtual FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) = 0;
|
||||||
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
|
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
|
||||||
virtual PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) = 0;
|
virtual PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) = 0;
|
||||||
@ -70,7 +71,8 @@ namespace backend {
|
|||||||
// the built object will be, the "blueprint". The blueprint is just a FooBase object
|
// the built object will be, the "blueprint". The blueprint is just a FooBase object
|
||||||
// instead of a backend Foo object. If the blueprint doesn't match an object in the
|
// instead of a backend Foo object. If the blueprint doesn't match an object in the
|
||||||
// cache, then the builder is used to make a new object.
|
// cache, then the builder is used to make a new object.
|
||||||
BindGroupLayoutBase* GetOrCreateBindGroupLayout(const BindGroupLayoutBase* blueprint, BindGroupLayoutBuilder* builder);
|
BindGroupLayoutBase* GetOrCreateBindGroupLayout(const BindGroupLayoutBase* blueprint,
|
||||||
|
BindGroupLayoutBuilder* builder);
|
||||||
void UncacheBindGroupLayout(BindGroupLayoutBase* obj);
|
void UncacheBindGroupLayout(BindGroupLayoutBase* obj);
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
@ -108,6 +110,6 @@ namespace backend {
|
|||||||
uint32_t mRefCount = 1;
|
uint32_t mRefCount = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_DEVICEBASE_H_
|
#endif // BACKEND_DEVICEBASE_H_
|
||||||
|
@ -60,13 +60,13 @@ namespace backend {
|
|||||||
|
|
||||||
class DeviceBase;
|
class DeviceBase;
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
class Ref;
|
class Ref;
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
class PerStage;
|
class PerStage;
|
||||||
|
|
||||||
enum PushConstantType : uint8_t;
|
enum PushConstantType : uint8_t;
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_FORWARD_H_
|
#endif // BACKEND_FORWARD_H_
|
||||||
|
@ -25,9 +25,13 @@ namespace backend {
|
|||||||
// Framebuffer
|
// Framebuffer
|
||||||
|
|
||||||
FramebufferBase::FramebufferBase(FramebufferBuilder* builder)
|
FramebufferBase::FramebufferBase(FramebufferBuilder* builder)
|
||||||
: mDevice(builder->mDevice), mRenderPass(std::move(builder->mRenderPass)),
|
: mDevice(builder->mDevice),
|
||||||
mWidth(builder->mWidth), mHeight(builder->mHeight), mTextureViews(std::move(builder->mTextureViews)),
|
mRenderPass(std::move(builder->mRenderPass)),
|
||||||
mClearColors(mTextureViews.size()), mClearDepthStencils(mTextureViews.size()) {
|
mWidth(builder->mWidth),
|
||||||
|
mHeight(builder->mHeight),
|
||||||
|
mTextureViews(std::move(builder->mTextureViews)),
|
||||||
|
mClearColors(mTextureViews.size()),
|
||||||
|
mClearDepthStencils(mTextureViews.size()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceBase* FramebufferBase::GetDevice() {
|
DeviceBase* FramebufferBase::GetDevice() {
|
||||||
@ -48,7 +52,8 @@ namespace backend {
|
|||||||
return mClearColors[attachmentSlot];
|
return mClearColors[attachmentSlot];
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferBase::ClearDepthStencil FramebufferBase::GetClearDepthStencil(uint32_t attachmentSlot) {
|
FramebufferBase::ClearDepthStencil FramebufferBase::GetClearDepthStencil(
|
||||||
|
uint32_t attachmentSlot) {
|
||||||
ASSERT(attachmentSlot < mClearDepthStencils.size());
|
ASSERT(attachmentSlot < mClearDepthStencils.size());
|
||||||
return mClearDepthStencils[attachmentSlot];
|
return mClearDepthStencils[attachmentSlot];
|
||||||
}
|
}
|
||||||
@ -61,7 +66,11 @@ namespace backend {
|
|||||||
return mHeight;
|
return mHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferBase::AttachmentSetClearColor(uint32_t attachmentSlot, float clearR, float clearG, float clearB, float clearA) {
|
void FramebufferBase::AttachmentSetClearColor(uint32_t attachmentSlot,
|
||||||
|
float clearR,
|
||||||
|
float clearG,
|
||||||
|
float clearB,
|
||||||
|
float clearA) {
|
||||||
if (attachmentSlot >= mRenderPass->GetAttachmentCount()) {
|
if (attachmentSlot >= mRenderPass->GetAttachmentCount()) {
|
||||||
mDevice->HandleError("Framebuffer attachment out of bounds");
|
mDevice->HandleError("Framebuffer attachment out of bounds");
|
||||||
return;
|
return;
|
||||||
@ -74,7 +83,9 @@ namespace backend {
|
|||||||
c.color[3] = clearA;
|
c.color[3] = clearA;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferBase::AttachmentSetClearDepthStencil(uint32_t attachmentSlot, float clearDepth, uint32_t clearStencil) {
|
void FramebufferBase::AttachmentSetClearDepthStencil(uint32_t attachmentSlot,
|
||||||
|
float clearDepth,
|
||||||
|
uint32_t clearStencil) {
|
||||||
if (attachmentSlot >= mRenderPass->GetAttachmentCount()) {
|
if (attachmentSlot >= mRenderPass->GetAttachmentCount()) {
|
||||||
mDevice->HandleError("Framebuffer attachment out of bounds");
|
mDevice->HandleError("Framebuffer attachment out of bounds");
|
||||||
return;
|
return;
|
||||||
@ -92,12 +103,12 @@ namespace backend {
|
|||||||
FRAMEBUFFER_PROPERTY_DIMENSIONS = 0x2,
|
FRAMEBUFFER_PROPERTY_DIMENSIONS = 0x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
FramebufferBuilder::FramebufferBuilder(DeviceBase* device)
|
FramebufferBuilder::FramebufferBuilder(DeviceBase* device) : Builder(device) {
|
||||||
: Builder(device) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferBase* FramebufferBuilder::GetResultImpl() {
|
FramebufferBase* FramebufferBuilder::GetResultImpl() {
|
||||||
constexpr int requiredProperties = FRAMEBUFFER_PROPERTY_RENDER_PASS | FRAMEBUFFER_PROPERTY_DIMENSIONS;
|
constexpr int requiredProperties =
|
||||||
|
FRAMEBUFFER_PROPERTY_RENDER_PASS | FRAMEBUFFER_PROPERTY_DIMENSIONS;
|
||||||
if ((mPropertiesSet & requiredProperties) != requiredProperties) {
|
if ((mPropertiesSet & requiredProperties) != requiredProperties) {
|
||||||
HandleError("Framebuffer missing properties");
|
HandleError("Framebuffer missing properties");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -170,4 +181,4 @@ namespace backend {
|
|||||||
|
|
||||||
mTextureViews[attachmentSlot] = textureView;
|
mTextureViews[attachmentSlot] = textureView;
|
||||||
}
|
}
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -48,8 +48,14 @@ namespace backend {
|
|||||||
uint32_t GetHeight() const;
|
uint32_t GetHeight() const;
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
void AttachmentSetClearColor(uint32_t attachmentSlot, float clearR, float clearG, float clearB, float clearA);
|
void AttachmentSetClearColor(uint32_t attachmentSlot,
|
||||||
void AttachmentSetClearDepthStencil(uint32_t attachmentSlot, float clearDepth, uint32_t clearStencil);
|
float clearR,
|
||||||
|
float clearG,
|
||||||
|
float clearB,
|
||||||
|
float clearA);
|
||||||
|
void AttachmentSetClearDepthStencil(uint32_t attachmentSlot,
|
||||||
|
float clearDepth,
|
||||||
|
uint32_t clearStencil);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeviceBase* mDevice;
|
DeviceBase* mDevice;
|
||||||
@ -81,6 +87,6 @@ namespace backend {
|
|||||||
int mPropertiesSet = 0;
|
int mPropertiesSet = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_FRAMEBUFFER_H_
|
#endif // BACKEND_FRAMEBUFFER_H_
|
||||||
|
@ -104,7 +104,9 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InputStateBuilder::SetAttribute(uint32_t shaderLocation,
|
void InputStateBuilder::SetAttribute(uint32_t shaderLocation,
|
||||||
uint32_t bindingSlot, nxt::VertexFormat format, uint32_t offset) {
|
uint32_t bindingSlot,
|
||||||
|
nxt::VertexFormat format,
|
||||||
|
uint32_t offset) {
|
||||||
if (shaderLocation >= kMaxVertexAttributes) {
|
if (shaderLocation >= kMaxVertexAttributes) {
|
||||||
HandleError("Setting attribute out of bounds");
|
HandleError("Setting attribute out of bounds");
|
||||||
return;
|
return;
|
||||||
@ -125,7 +127,8 @@ namespace backend {
|
|||||||
info.offset = offset;
|
info.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputStateBuilder::SetInput(uint32_t bindingSlot, uint32_t stride,
|
void InputStateBuilder::SetInput(uint32_t bindingSlot,
|
||||||
|
uint32_t stride,
|
||||||
nxt::InputStepMode stepMode) {
|
nxt::InputStepMode stepMode) {
|
||||||
if (bindingSlot >= kMaxVertexInputs) {
|
if (bindingSlot >= kMaxVertexInputs) {
|
||||||
HandleError("Setting input out of bounds");
|
HandleError("Setting input out of bounds");
|
||||||
@ -142,4 +145,4 @@ namespace backend {
|
|||||||
info.stepMode = stepMode;
|
info.stepMode = stepMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_INPUTSTATE_H_
|
#ifndef BACKEND_INPUTSTATE_H_
|
||||||
#define BACKEND_INPUTSTATE_H_
|
#define BACKEND_INPUTSTATE_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
|
|
||||||
@ -63,10 +63,11 @@ namespace backend {
|
|||||||
InputStateBuilder(DeviceBase* device);
|
InputStateBuilder(DeviceBase* device);
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
void SetAttribute(uint32_t shaderLocation, uint32_t bindingSlot,
|
void SetAttribute(uint32_t shaderLocation,
|
||||||
nxt::VertexFormat format, uint32_t offset);
|
uint32_t bindingSlot,
|
||||||
void SetInput(uint32_t bindingSlot, uint32_t stride,
|
nxt::VertexFormat format,
|
||||||
nxt::InputStepMode stepMode);
|
uint32_t offset);
|
||||||
|
void SetInput(uint32_t bindingSlot, uint32_t stride, nxt::InputStepMode stepMode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class InputStateBase;
|
friend class InputStateBase;
|
||||||
@ -79,6 +80,6 @@ namespace backend {
|
|||||||
std::array<InputStateBase::InputInfo, kMaxVertexInputs> mInputInfos;
|
std::array<InputStateBase::InputInfo, kMaxVertexInputs> mInputInfos;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_INPUTSTATE_H_
|
#endif // BACKEND_INPUTSTATE_H_
|
||||||
|
@ -26,4 +26,4 @@ namespace backend {
|
|||||||
return static_cast<nxt::ShaderStageBit>(1 << static_cast<uint32_t>(stage));
|
return static_cast<nxt::ShaderStageBit>(1 << static_cast<uint32_t>(stage));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -29,16 +29,23 @@ namespace backend {
|
|||||||
static_assert(static_cast<uint32_t>(nxt::ShaderStage::Fragment) < kNumStages, "");
|
static_assert(static_cast<uint32_t>(nxt::ShaderStage::Fragment) < kNumStages, "");
|
||||||
static_assert(static_cast<uint32_t>(nxt::ShaderStage::Compute) < kNumStages, "");
|
static_assert(static_cast<uint32_t>(nxt::ShaderStage::Compute) < kNumStages, "");
|
||||||
|
|
||||||
static_assert(static_cast<uint32_t>(nxt::ShaderStageBit::Vertex) == (1 << static_cast<uint32_t>(nxt::ShaderStage::Vertex)), "");
|
static_assert(static_cast<uint32_t>(nxt::ShaderStageBit::Vertex) ==
|
||||||
static_assert(static_cast<uint32_t>(nxt::ShaderStageBit::Fragment) == (1 << static_cast<uint32_t>(nxt::ShaderStage::Fragment)), "");
|
(1 << static_cast<uint32_t>(nxt::ShaderStage::Vertex)),
|
||||||
static_assert(static_cast<uint32_t>(nxt::ShaderStageBit::Compute) == (1 << static_cast<uint32_t>(nxt::ShaderStage::Compute)), "");
|
"");
|
||||||
|
static_assert(static_cast<uint32_t>(nxt::ShaderStageBit::Fragment) ==
|
||||||
|
(1 << static_cast<uint32_t>(nxt::ShaderStage::Fragment)),
|
||||||
|
"");
|
||||||
|
static_assert(static_cast<uint32_t>(nxt::ShaderStageBit::Compute) ==
|
||||||
|
(1 << static_cast<uint32_t>(nxt::ShaderStage::Compute)),
|
||||||
|
"");
|
||||||
|
|
||||||
BitSetIterator<kNumStages, nxt::ShaderStage> IterateStages(nxt::ShaderStageBit stages);
|
BitSetIterator<kNumStages, nxt::ShaderStage> IterateStages(nxt::ShaderStageBit stages);
|
||||||
nxt::ShaderStageBit StageBit(nxt::ShaderStage stage);
|
nxt::ShaderStageBit StageBit(nxt::ShaderStage stage);
|
||||||
|
|
||||||
static constexpr nxt::ShaderStageBit kAllStages = static_cast<nxt::ShaderStageBit>((1 << kNumStages) - 1);
|
static constexpr nxt::ShaderStageBit kAllStages =
|
||||||
|
static_cast<nxt::ShaderStageBit>((1 << kNumStages) - 1);
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
class PerStage {
|
class PerStage {
|
||||||
public:
|
public:
|
||||||
T& operator[](nxt::ShaderStage stage) {
|
T& operator[](nxt::ShaderStage stage) {
|
||||||
@ -65,6 +72,6 @@ namespace backend {
|
|||||||
std::array<T, kNumStages> mData;
|
std::array<T, kNumStages> mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_PERSTAGE_H_
|
#endif // BACKEND_PERSTAGE_H_
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
#include "backend/Pipeline.h"
|
#include "backend/Pipeline.h"
|
||||||
|
|
||||||
#include "backend/Device.h"
|
|
||||||
#include "backend/DepthStencilState.h"
|
#include "backend/DepthStencilState.h"
|
||||||
|
#include "backend/Device.h"
|
||||||
#include "backend/InputState.h"
|
#include "backend/InputState.h"
|
||||||
#include "backend/PipelineLayout.h"
|
#include "backend/PipelineLayout.h"
|
||||||
#include "backend/RenderPass.h"
|
#include "backend/RenderPass.h"
|
||||||
@ -28,7 +28,10 @@ namespace backend {
|
|||||||
PipelineBase::PipelineBase(PipelineBuilder* builder)
|
PipelineBase::PipelineBase(PipelineBuilder* builder)
|
||||||
: mStageMask(builder->mStageMask), mLayout(std::move(builder->mLayout)) {
|
: mStageMask(builder->mStageMask), mLayout(std::move(builder->mLayout)) {
|
||||||
if (!mLayout) {
|
if (!mLayout) {
|
||||||
mLayout = builder->GetParentBuilder()->GetDevice()->CreatePipelineLayoutBuilder()->GetResult();
|
mLayout = builder->GetParentBuilder()
|
||||||
|
->GetDevice()
|
||||||
|
->CreatePipelineLayoutBuilder()
|
||||||
|
->GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto FillPushConstants = [](const ShaderModuleBase* module, PushConstantInfo* info) {
|
auto FillPushConstants = [](const ShaderModuleBase* module, PushConstantInfo* info) {
|
||||||
@ -58,7 +61,8 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const PipelineBase::PushConstantInfo& PipelineBase::GetPushConstants(nxt::ShaderStage stage) const {
|
const PipelineBase::PushConstantInfo& PipelineBase::GetPushConstants(
|
||||||
|
nxt::ShaderStage stage) const {
|
||||||
return mPushConstants[stage];
|
return mPushConstants[stage];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +93,9 @@ namespace backend {
|
|||||||
mLayout = layout;
|
mLayout = layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineBuilder::SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint) {
|
void PipelineBuilder::SetStage(nxt::ShaderStage stage,
|
||||||
|
ShaderModuleBase* module,
|
||||||
|
const char* entryPoint) {
|
||||||
if (entryPoint != std::string("main")) {
|
if (entryPoint != std::string("main")) {
|
||||||
mParentBuilder->HandleError("Currently the entry point has to be main()");
|
mParentBuilder->HandleError("Currently the entry point has to be main()");
|
||||||
return;
|
return;
|
||||||
@ -111,4 +117,4 @@ namespace backend {
|
|||||||
mStages[stage].entryPoint = entryPoint;
|
mStages[stage].entryPoint = entryPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_PIPELINE_H_
|
#ifndef BACKEND_PIPELINE_H_
|
||||||
#define BACKEND_PIPELINE_H_
|
#define BACKEND_PIPELINE_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/PerStage.h"
|
#include "backend/PerStage.h"
|
||||||
#include "backend/PipelineLayout.h"
|
#include "backend/PipelineLayout.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
@ -80,6 +80,6 @@ namespace backend {
|
|||||||
PerStage<StageInfo> mStages;
|
PerStage<StageInfo> mStages;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_PIPELINE_H_
|
#endif // BACKEND_PIPELINE_H_
|
||||||
|
@ -35,8 +35,9 @@ namespace backend {
|
|||||||
return mMask;
|
return mMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::bitset<kMaxBindGroups> PipelineLayoutBase::InheritedGroupsMask(const PipelineLayoutBase* other) const {
|
std::bitset<kMaxBindGroups> PipelineLayoutBase::InheritedGroupsMask(
|
||||||
return { GroupsInheritUpTo(other) - 1 };
|
const PipelineLayoutBase* other) const {
|
||||||
|
return {GroupsInheritUpTo(other) - 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t PipelineLayoutBase::GroupsInheritUpTo(const PipelineLayoutBase* other) const {
|
uint32_t PipelineLayoutBase::GroupsInheritUpTo(const PipelineLayoutBase* other) const {
|
||||||
@ -54,8 +55,8 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PipelineLayoutBase* PipelineLayoutBuilder::GetResultImpl() {
|
PipelineLayoutBase* PipelineLayoutBuilder::GetResultImpl() {
|
||||||
// TODO(cwallez@chromium.org): this is a hack, have the null bind group layout somewhere in the device
|
// TODO(cwallez@chromium.org): this is a hack, have the null bind group layout somewhere in
|
||||||
// once we have a cache of BGL
|
// the device once we have a cache of BGL
|
||||||
for (size_t group = 0; group < kMaxBindGroups; ++group) {
|
for (size_t group = 0; group < kMaxBindGroups; ++group) {
|
||||||
if (!mBindGroupLayouts[group]) {
|
if (!mBindGroupLayouts[group]) {
|
||||||
mBindGroupLayouts[group] = mDevice->CreateBindGroupLayoutBuilder()->GetResult();
|
mBindGroupLayouts[group] = mDevice->CreateBindGroupLayoutBuilder()->GetResult();
|
||||||
@ -65,7 +66,8 @@ namespace backend {
|
|||||||
return mDevice->CreatePipelineLayout(this);
|
return mDevice->CreatePipelineLayout(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineLayoutBuilder::SetBindGroupLayout(uint32_t groupIndex, BindGroupLayoutBase* layout) {
|
void PipelineLayoutBuilder::SetBindGroupLayout(uint32_t groupIndex,
|
||||||
|
BindGroupLayoutBase* layout) {
|
||||||
if (groupIndex >= kMaxBindGroups) {
|
if (groupIndex >= kMaxBindGroups) {
|
||||||
HandleError("groupIndex is over the maximum allowed");
|
HandleError("groupIndex is over the maximum allowed");
|
||||||
return;
|
return;
|
||||||
@ -79,4 +81,4 @@ namespace backend {
|
|||||||
mMask.set(groupIndex);
|
mMask.set(groupIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_PIPELINELAYOUT_H_
|
#ifndef BACKEND_PIPELINELAYOUT_H_
|
||||||
#define BACKEND_PIPELINELAYOUT_H_
|
#define BACKEND_PIPELINELAYOUT_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
|
|
||||||
@ -37,10 +37,11 @@ namespace backend {
|
|||||||
const std::bitset<kMaxBindGroups> GetBindGroupsLayoutMask() const;
|
const std::bitset<kMaxBindGroups> GetBindGroupsLayoutMask() const;
|
||||||
|
|
||||||
// Utility functions to compute inherited bind groups.
|
// Utility functions to compute inherited bind groups.
|
||||||
// Returns the inherited bind groups as a mask
|
// Returns the inherited bind groups as a mask.
|
||||||
std::bitset<kMaxBindGroups> InheritedGroupsMask(const PipelineLayoutBase* other) const;
|
std::bitset<kMaxBindGroups> InheritedGroupsMask(const PipelineLayoutBase* other) const;
|
||||||
|
|
||||||
// Returns the index of the first incompatible bind group (in the range [1, kMaxBindGroups + 1])
|
// Returns the index of the first incompatible bind group in the range
|
||||||
|
// [1, kMaxBindGroups + 1]
|
||||||
uint32_t GroupsInheritUpTo(const PipelineLayoutBase* other) const;
|
uint32_t GroupsInheritUpTo(const PipelineLayoutBase* other) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -64,6 +65,6 @@ namespace backend {
|
|||||||
std::bitset<kMaxBindGroups> mMask;
|
std::bitset<kMaxBindGroups> mMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_PIPELINELAYOUT_H_
|
#endif // BACKEND_PIPELINELAYOUT_H_
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
#include "backend/Queue.h"
|
#include "backend/Queue.h"
|
||||||
|
|
||||||
#include "backend/Device.h"
|
|
||||||
#include "backend/CommandBuffer.h"
|
#include "backend/CommandBuffer.h"
|
||||||
|
#include "backend/Device.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
@ -41,4 +41,4 @@ namespace backend {
|
|||||||
return mDevice->CreateQueue(this);
|
return mDevice->CreateQueue(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_QUEUE_H_
|
#ifndef BACKEND_QUEUE_H_
|
||||||
#define BACKEND_QUEUE_H_
|
#define BACKEND_QUEUE_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
@ -29,9 +29,10 @@ namespace backend {
|
|||||||
|
|
||||||
DeviceBase* GetDevice();
|
DeviceBase* GetDevice();
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool ValidateSubmit(uint32_t numCommands, T* const * commands) {
|
bool ValidateSubmit(uint32_t numCommands, T* const* commands) {
|
||||||
static_assert(std::is_base_of<CommandBufferBase, T>::value, "invalid command buffer type");
|
static_assert(std::is_base_of<CommandBufferBase, T>::value,
|
||||||
|
"invalid command buffer type");
|
||||||
|
|
||||||
for (uint32_t i = 0; i < numCommands; ++i) {
|
for (uint32_t i = 0; i < numCommands; ++i) {
|
||||||
if (!ValidateSubmitCommand(commands[i])) {
|
if (!ValidateSubmitCommand(commands[i])) {
|
||||||
@ -56,6 +57,6 @@ namespace backend {
|
|||||||
QueueBase* GetResultImpl() override;
|
QueueBase* GetResultImpl() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_QUEUE_H_
|
#endif // BACKEND_QUEUE_H_
|
||||||
|
@ -27,12 +27,12 @@ namespace backend {
|
|||||||
void RefCounted::ReferenceInternal() {
|
void RefCounted::ReferenceInternal() {
|
||||||
ASSERT(mInternalRefs != 0);
|
ASSERT(mInternalRefs != 0);
|
||||||
// TODO(cwallez@chromium.org): what to do on overflow?
|
// TODO(cwallez@chromium.org): what to do on overflow?
|
||||||
mInternalRefs ++;
|
mInternalRefs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefCounted::ReleaseInternal() {
|
void RefCounted::ReleaseInternal() {
|
||||||
ASSERT(mInternalRefs != 0);
|
ASSERT(mInternalRefs != 0);
|
||||||
mInternalRefs --;
|
mInternalRefs--;
|
||||||
if (mInternalRefs == 0) {
|
if (mInternalRefs == 0) {
|
||||||
ASSERT(mExternalRefs == 0);
|
ASSERT(mExternalRefs == 0);
|
||||||
// TODO(cwallez@chromium.org): would this work with custom allocators?
|
// TODO(cwallez@chromium.org): would this work with custom allocators?
|
||||||
@ -51,15 +51,15 @@ namespace backend {
|
|||||||
void RefCounted::Reference() {
|
void RefCounted::Reference() {
|
||||||
ASSERT(mExternalRefs != 0);
|
ASSERT(mExternalRefs != 0);
|
||||||
// TODO(cwallez@chromium.org): what to do on overflow?
|
// TODO(cwallez@chromium.org): what to do on overflow?
|
||||||
mExternalRefs ++;
|
mExternalRefs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefCounted::Release() {
|
void RefCounted::Release() {
|
||||||
ASSERT(mExternalRefs != 0);
|
ASSERT(mExternalRefs != 0);
|
||||||
mExternalRefs --;
|
mExternalRefs--;
|
||||||
if (mExternalRefs == 0) {
|
if (mExternalRefs == 0) {
|
||||||
ReleaseInternal();
|
ReleaseInternal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -39,20 +39,22 @@ namespace backend {
|
|||||||
uint32_t mInternalRefs = 1;
|
uint32_t mInternalRefs = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
class Ref {
|
class Ref {
|
||||||
public:
|
public:
|
||||||
Ref() {}
|
Ref() {
|
||||||
|
}
|
||||||
|
|
||||||
Ref(T* p): mPointee(p) {
|
Ref(T* p) : mPointee(p) {
|
||||||
Reference();
|
Reference();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref(const Ref<T>& other): mPointee(other.mPointee) {
|
Ref(const Ref<T>& other) : mPointee(other.mPointee) {
|
||||||
Reference();
|
Reference();
|
||||||
}
|
}
|
||||||
Ref<T>& operator=(const Ref<T>& other) {
|
Ref<T>& operator=(const Ref<T>& other) {
|
||||||
if (&other == this) return *this;
|
if (&other == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
other.Reference();
|
other.Reference();
|
||||||
Release();
|
Release();
|
||||||
@ -66,7 +68,8 @@ namespace backend {
|
|||||||
other.mPointee = nullptr;
|
other.mPointee = nullptr;
|
||||||
}
|
}
|
||||||
Ref<T>& operator=(Ref<T>&& other) {
|
Ref<T>& operator=(Ref<T>&& other) {
|
||||||
if (&other == this) return *this;
|
if (&other == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
Release();
|
Release();
|
||||||
mPointee = other.mPointee;
|
mPointee = other.mPointee;
|
||||||
@ -117,10 +120,10 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//static_assert(std::is_base_of<RefCounted, T>::value, "");
|
// static_assert(std::is_base_of<RefCounted, T>::value, "");
|
||||||
T* mPointee = nullptr;
|
T* mPointee = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_REFCOUNTED_H_
|
#endif // BACKEND_REFCOUNTED_H_
|
||||||
|
@ -25,7 +25,8 @@ namespace backend {
|
|||||||
// RenderPass
|
// RenderPass
|
||||||
|
|
||||||
RenderPassBase::RenderPassBase(RenderPassBuilder* builder)
|
RenderPassBase::RenderPassBase(RenderPassBuilder* builder)
|
||||||
: mAttachments(std::move(builder->mAttachments)), mSubpasses(std::move(builder->mSubpasses)) {
|
: mAttachments(std::move(builder->mAttachments)),
|
||||||
|
mSubpasses(std::move(builder->mSubpasses)) {
|
||||||
for (uint32_t s = 0; s < GetSubpassCount(); ++s) {
|
for (uint32_t s = 0; s < GetSubpassCount(); ++s) {
|
||||||
const auto& subpass = GetSubpassInfo(s);
|
const auto& subpass = GetSubpassInfo(s);
|
||||||
for (auto location : IterateBitSet(subpass.colorAttachmentsSet)) {
|
for (auto location : IterateBitSet(subpass.colorAttachmentsSet)) {
|
||||||
@ -49,7 +50,8 @@ namespace backend {
|
|||||||
return static_cast<uint32_t>(mAttachments.size());
|
return static_cast<uint32_t>(mAttachments.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
const RenderPassBase::AttachmentInfo& RenderPassBase::GetAttachmentInfo(uint32_t attachment) const {
|
const RenderPassBase::AttachmentInfo& RenderPassBase::GetAttachmentInfo(
|
||||||
|
uint32_t attachment) const {
|
||||||
ASSERT(attachment < mAttachments.size());
|
ASSERT(attachment < mAttachments.size());
|
||||||
return mAttachments[attachment];
|
return mAttachments[attachment];
|
||||||
}
|
}
|
||||||
@ -76,12 +78,12 @@ namespace backend {
|
|||||||
RENDERPASS_PROPERTY_SUBPASS_COUNT = 0x2,
|
RENDERPASS_PROPERTY_SUBPASS_COUNT = 0x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
RenderPassBuilder::RenderPassBuilder(DeviceBase* device)
|
RenderPassBuilder::RenderPassBuilder(DeviceBase* device) : Builder(device), mSubpasses(1) {
|
||||||
: Builder(device), mSubpasses(1) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderPassBase* RenderPassBuilder::GetResultImpl() {
|
RenderPassBase* RenderPassBuilder::GetResultImpl() {
|
||||||
constexpr int requiredProperties = RENDERPASS_PROPERTY_ATTACHMENT_COUNT | RENDERPASS_PROPERTY_SUBPASS_COUNT;
|
constexpr int requiredProperties =
|
||||||
|
RENDERPASS_PROPERTY_ATTACHMENT_COUNT | RENDERPASS_PROPERTY_SUBPASS_COUNT;
|
||||||
if ((mPropertiesSet & requiredProperties) != requiredProperties) {
|
if ((mPropertiesSet & requiredProperties) != requiredProperties) {
|
||||||
HandleError("Render pass missing properties");
|
HandleError("Render pass missing properties");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -105,7 +107,8 @@ namespace backend {
|
|||||||
if (subpass.depthStencilAttachmentSet) {
|
if (subpass.depthStencilAttachmentSet) {
|
||||||
uint32_t slot = subpass.depthStencilAttachment;
|
uint32_t slot = subpass.depthStencilAttachment;
|
||||||
if (!TextureFormatHasDepthOrStencil(mAttachments[slot].format)) {
|
if (!TextureFormatHasDepthOrStencil(mAttachments[slot].format)) {
|
||||||
HandleError("Render pass depth/stencil attachment is not of a depth/stencil format");
|
HandleError(
|
||||||
|
"Render pass depth/stencil attachment is not of a depth/stencil format");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +128,8 @@ namespace backend {
|
|||||||
mPropertiesSet |= RENDERPASS_PROPERTY_ATTACHMENT_COUNT;
|
mPropertiesSet |= RENDERPASS_PROPERTY_ATTACHMENT_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPassBuilder::AttachmentSetFormat(uint32_t attachmentSlot, nxt::TextureFormat format) {
|
void RenderPassBuilder::AttachmentSetFormat(uint32_t attachmentSlot,
|
||||||
|
nxt::TextureFormat format) {
|
||||||
if ((mPropertiesSet & RENDERPASS_PROPERTY_ATTACHMENT_COUNT) == 0) {
|
if ((mPropertiesSet & RENDERPASS_PROPERTY_ATTACHMENT_COUNT) == 0) {
|
||||||
HandleError("Render pass attachment count not set yet");
|
HandleError("Render pass attachment count not set yet");
|
||||||
return;
|
return;
|
||||||
@ -156,7 +160,9 @@ namespace backend {
|
|||||||
mAttachments[attachmentSlot].colorLoadOp = op;
|
mAttachments[attachmentSlot].colorLoadOp = op;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPassBuilder::AttachmentSetDepthStencilLoadOps(uint32_t attachmentSlot, nxt::LoadOp depthOp, nxt::LoadOp stencilOp) {
|
void RenderPassBuilder::AttachmentSetDepthStencilLoadOps(uint32_t attachmentSlot,
|
||||||
|
nxt::LoadOp depthOp,
|
||||||
|
nxt::LoadOp stencilOp) {
|
||||||
if ((mPropertiesSet & RENDERPASS_PROPERTY_ATTACHMENT_COUNT) == 0) {
|
if ((mPropertiesSet & RENDERPASS_PROPERTY_ATTACHMENT_COUNT) == 0) {
|
||||||
HandleError("Render pass attachment count not set yet");
|
HandleError("Render pass attachment count not set yet");
|
||||||
return;
|
return;
|
||||||
@ -170,7 +176,6 @@ namespace backend {
|
|||||||
mAttachments[attachmentSlot].stencilLoadOp = stencilOp;
|
mAttachments[attachmentSlot].stencilLoadOp = stencilOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderPassBuilder::SetSubpassCount(uint32_t subpassCount) {
|
void RenderPassBuilder::SetSubpassCount(uint32_t subpassCount) {
|
||||||
if ((mPropertiesSet & RENDERPASS_PROPERTY_SUBPASS_COUNT) != 0) {
|
if ((mPropertiesSet & RENDERPASS_PROPERTY_SUBPASS_COUNT) != 0) {
|
||||||
HandleError("Render pass subpass count property set multiple times");
|
HandleError("Render pass subpass count property set multiple times");
|
||||||
@ -185,7 +190,9 @@ namespace backend {
|
|||||||
mPropertiesSet |= RENDERPASS_PROPERTY_SUBPASS_COUNT;
|
mPropertiesSet |= RENDERPASS_PROPERTY_SUBPASS_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPassBuilder::SubpassSetColorAttachment(uint32_t subpass, uint32_t outputAttachmentLocation, uint32_t attachmentSlot) {
|
void RenderPassBuilder::SubpassSetColorAttachment(uint32_t subpass,
|
||||||
|
uint32_t outputAttachmentLocation,
|
||||||
|
uint32_t attachmentSlot) {
|
||||||
if ((mPropertiesSet & RENDERPASS_PROPERTY_SUBPASS_COUNT) == 0) {
|
if ((mPropertiesSet & RENDERPASS_PROPERTY_SUBPASS_COUNT) == 0) {
|
||||||
HandleError("Render pass subpass count not set yet");
|
HandleError("Render pass subpass count not set yet");
|
||||||
return;
|
return;
|
||||||
@ -215,7 +222,8 @@ namespace backend {
|
|||||||
mSubpasses[subpass].colorAttachments[outputAttachmentLocation] = attachmentSlot;
|
mSubpasses[subpass].colorAttachments[outputAttachmentLocation] = attachmentSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPassBuilder::SubpassSetDepthStencilAttachment(uint32_t subpass, uint32_t attachmentSlot) {
|
void RenderPassBuilder::SubpassSetDepthStencilAttachment(uint32_t subpass,
|
||||||
|
uint32_t attachmentSlot) {
|
||||||
if ((mPropertiesSet & RENDERPASS_PROPERTY_SUBPASS_COUNT) == 0) {
|
if ((mPropertiesSet & RENDERPASS_PROPERTY_SUBPASS_COUNT) == 0) {
|
||||||
HandleError("Render pass subpass count not set yet");
|
HandleError("Render pass subpass count not set yet");
|
||||||
return;
|
return;
|
||||||
@ -241,4 +249,4 @@ namespace backend {
|
|||||||
mSubpasses[subpass].depthStencilAttachment = attachmentSlot;
|
mSubpasses[subpass].depthStencilAttachment = attachmentSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -37,9 +37,8 @@ namespace backend {
|
|||||||
nxt::LoadOp colorLoadOp = nxt::LoadOp::Load;
|
nxt::LoadOp colorLoadOp = nxt::LoadOp::Load;
|
||||||
nxt::LoadOp depthLoadOp = nxt::LoadOp::Load;
|
nxt::LoadOp depthLoadOp = nxt::LoadOp::Load;
|
||||||
nxt::LoadOp stencilLoadOp = nxt::LoadOp::Load;
|
nxt::LoadOp stencilLoadOp = nxt::LoadOp::Load;
|
||||||
// The first subpass that this attachment is used in.
|
// The first subpass that this attachment is used in. This is used to determine, for
|
||||||
// This is used to determine, for each subpass, whether each
|
// each subpass, whether each of its attachments is being used for the first time.
|
||||||
// of its attachments is being used for the first time.
|
|
||||||
uint32_t firstSubpass = UINT32_MAX;
|
uint32_t firstSubpass = UINT32_MAX;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -72,18 +71,19 @@ namespace backend {
|
|||||||
void SetAttachmentCount(uint32_t attachmentCount);
|
void SetAttachmentCount(uint32_t attachmentCount);
|
||||||
void AttachmentSetFormat(uint32_t attachmentSlot, nxt::TextureFormat format);
|
void AttachmentSetFormat(uint32_t attachmentSlot, nxt::TextureFormat format);
|
||||||
void AttachmentSetColorLoadOp(uint32_t attachmentSlot, nxt::LoadOp op);
|
void AttachmentSetColorLoadOp(uint32_t attachmentSlot, nxt::LoadOp op);
|
||||||
void AttachmentSetDepthStencilLoadOps(uint32_t attachmentSlot, nxt::LoadOp depthOp, nxt::LoadOp stencilOp);
|
void AttachmentSetDepthStencilLoadOps(uint32_t attachmentSlot,
|
||||||
|
nxt::LoadOp depthOp,
|
||||||
|
nxt::LoadOp stencilOp);
|
||||||
void SetSubpassCount(uint32_t subpassCount);
|
void SetSubpassCount(uint32_t subpassCount);
|
||||||
void SubpassSetColorAttachment(uint32_t subpass, uint32_t outputAttachmentLocation, uint32_t attachmentSlot);
|
void SubpassSetColorAttachment(uint32_t subpass,
|
||||||
|
uint32_t outputAttachmentLocation,
|
||||||
|
uint32_t attachmentSlot);
|
||||||
void SubpassSetDepthStencilAttachment(uint32_t subpass, uint32_t attachmentSlot);
|
void SubpassSetDepthStencilAttachment(uint32_t subpass, uint32_t attachmentSlot);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class RenderPassBase;
|
friend class RenderPassBase;
|
||||||
|
|
||||||
enum AttachmentProperty {
|
enum AttachmentProperty { ATTACHMENT_PROPERTY_FORMAT, ATTACHMENT_PROPERTY_COUNT };
|
||||||
ATTACHMENT_PROPERTY_FORMAT,
|
|
||||||
ATTACHMENT_PROPERTY_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<std::bitset<ATTACHMENT_PROPERTY_COUNT>> mAttachmentProperties;
|
std::vector<std::bitset<ATTACHMENT_PROPERTY_COUNT>> mAttachmentProperties;
|
||||||
std::vector<RenderPassBase::AttachmentInfo> mAttachments;
|
std::vector<RenderPassBase::AttachmentInfo> mAttachments;
|
||||||
@ -91,6 +91,6 @@ namespace backend {
|
|||||||
int mPropertiesSet = 0;
|
int mPropertiesSet = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_RENDERPASS_H_
|
#endif // BACKEND_RENDERPASS_H_
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#include "backend/RenderPipeline.h"
|
#include "backend/RenderPipeline.h"
|
||||||
|
|
||||||
#include "backend/BlendState.h"
|
#include "backend/BlendState.h"
|
||||||
#include "backend/Device.h"
|
|
||||||
#include "backend/DepthStencilState.h"
|
#include "backend/DepthStencilState.h"
|
||||||
|
#include "backend/Device.h"
|
||||||
#include "backend/InputState.h"
|
#include "backend/InputState.h"
|
||||||
#include "backend/RenderPass.h"
|
#include "backend/RenderPass.h"
|
||||||
#include "common/BitSetIterator.h"
|
#include "common/BitSetIterator.h"
|
||||||
@ -32,8 +32,8 @@ namespace backend {
|
|||||||
mInputState(std::move(builder->mInputState)),
|
mInputState(std::move(builder->mInputState)),
|
||||||
mPrimitiveTopology(builder->mPrimitiveTopology),
|
mPrimitiveTopology(builder->mPrimitiveTopology),
|
||||||
mBlendStates(builder->mBlendStates),
|
mBlendStates(builder->mBlendStates),
|
||||||
mRenderPass(std::move(builder->mRenderPass)), mSubpass(builder->mSubpass) {
|
mRenderPass(std::move(builder->mRenderPass)),
|
||||||
|
mSubpass(builder->mSubpass) {
|
||||||
if (GetStageMask() != (nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment)) {
|
if (GetStageMask() != (nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment)) {
|
||||||
builder->HandleError("Render pipeline should have exactly a vertex and fragment stage");
|
builder->HandleError("Render pipeline should have exactly a vertex and fragment stage");
|
||||||
return;
|
return;
|
||||||
@ -41,7 +41,9 @@ namespace backend {
|
|||||||
|
|
||||||
// TODO(kainino@chromium.org): Need to verify the pipeline against its render subpass.
|
// TODO(kainino@chromium.org): Need to verify the pipeline against its render subpass.
|
||||||
|
|
||||||
if ((builder->GetStageInfo(nxt::ShaderStage::Vertex).module->GetUsedVertexAttributes() & ~mInputState->GetAttributesSetMask()).any()) {
|
if ((builder->GetStageInfo(nxt::ShaderStage::Vertex).module->GetUsedVertexAttributes() &
|
||||||
|
~mInputState->GetAttributesSetMask())
|
||||||
|
.any()) {
|
||||||
builder->HandleError("Pipeline vertex stage uses inputs not in the input state");
|
builder->HandleError("Pipeline vertex stage uses inputs not in the input state");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -83,7 +85,8 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RenderPipelineBase* RenderPipelineBuilder::GetResultImpl() {
|
RenderPipelineBase* RenderPipelineBuilder::GetResultImpl() {
|
||||||
// TODO(cwallez@chromium.org): the layout should be required, and put the default objects in the device
|
// TODO(cwallez@chromium.org): the layout should be required, and put the default objects in
|
||||||
|
// the device
|
||||||
if (!mInputState) {
|
if (!mInputState) {
|
||||||
mInputState = mDevice->CreateInputStateBuilder()->GetResult();
|
mInputState = mDevice->CreateInputStateBuilder()->GetResult();
|
||||||
}
|
}
|
||||||
@ -95,21 +98,24 @@ namespace backend {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const auto& subpassInfo = mRenderPass->GetSubpassInfo(mSubpass);
|
const auto& subpassInfo = mRenderPass->GetSubpassInfo(mSubpass);
|
||||||
if ((mBlendStatesSet | subpassInfo.colorAttachmentsSet) != subpassInfo.colorAttachmentsSet) {
|
if ((mBlendStatesSet | subpassInfo.colorAttachmentsSet) !=
|
||||||
|
subpassInfo.colorAttachmentsSet) {
|
||||||
HandleError("Blend state set on unset color attachment");
|
HandleError("Blend state set on unset color attachment");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign all color attachments without a blend state the default state
|
// Assign all color attachments without a blend state the default state
|
||||||
// TODO(enga@google.com): Put the default objects in the device
|
// TODO(enga@google.com): Put the default objects in the device
|
||||||
for (uint32_t attachmentSlot : IterateBitSet(subpassInfo.colorAttachmentsSet & ~mBlendStatesSet)) {
|
for (uint32_t attachmentSlot :
|
||||||
|
IterateBitSet(subpassInfo.colorAttachmentsSet & ~mBlendStatesSet)) {
|
||||||
mBlendStates[attachmentSlot] = mDevice->CreateBlendStateBuilder()->GetResult();
|
mBlendStates[attachmentSlot] = mDevice->CreateBlendStateBuilder()->GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mDevice->CreateRenderPipeline(this);
|
return mDevice->CreateRenderPipeline(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPipelineBuilder::SetColorAttachmentBlendState(uint32_t attachmentSlot, BlendStateBase* blendState) {
|
void RenderPipelineBuilder::SetColorAttachmentBlendState(uint32_t attachmentSlot,
|
||||||
|
BlendStateBase* blendState) {
|
||||||
if (attachmentSlot > mBlendStates.size()) {
|
if (attachmentSlot > mBlendStates.size()) {
|
||||||
HandleError("Attachment index out of bounds");
|
HandleError("Attachment index out of bounds");
|
||||||
return;
|
return;
|
||||||
@ -144,4 +150,4 @@ namespace backend {
|
|||||||
mSubpass = subpass;
|
mSubpass = subpass;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -65,7 +65,8 @@ namespace backend {
|
|||||||
|
|
||||||
Ref<DepthStencilStateBase> mDepthStencilState;
|
Ref<DepthStencilStateBase> mDepthStencilState;
|
||||||
Ref<InputStateBase> mInputState;
|
Ref<InputStateBase> mInputState;
|
||||||
// TODO(enga@google.com): Remove default when we validate that all required properties are set
|
// TODO(enga@google.com): Remove default when we validate that all required properties are
|
||||||
|
// set
|
||||||
nxt::PrimitiveTopology mPrimitiveTopology = nxt::PrimitiveTopology::TriangleList;
|
nxt::PrimitiveTopology mPrimitiveTopology = nxt::PrimitiveTopology::TriangleList;
|
||||||
nxt::IndexFormat mIndexFormat = nxt::IndexFormat::Uint32;
|
nxt::IndexFormat mIndexFormat = nxt::IndexFormat::Uint32;
|
||||||
std::bitset<kMaxColorAttachments> mBlendStatesSet;
|
std::bitset<kMaxColorAttachments> mBlendStatesSet;
|
||||||
@ -74,6 +75,6 @@ namespace backend {
|
|||||||
uint32_t mSubpass;
|
uint32_t mSubpass;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_RENDERPIPELINE_H_
|
#endif // BACKEND_RENDERPIPELINE_H_
|
||||||
|
@ -43,7 +43,9 @@ namespace backend {
|
|||||||
return mMipMapFilter;
|
return mMipMapFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SamplerBuilder::SetFilterMode(nxt::FilterMode magFilter, nxt::FilterMode minFilter, nxt::FilterMode mipMapFilter) {
|
void SamplerBuilder::SetFilterMode(nxt::FilterMode magFilter,
|
||||||
|
nxt::FilterMode minFilter,
|
||||||
|
nxt::FilterMode mipMapFilter) {
|
||||||
if ((mPropertiesSet & SAMPLER_PROPERTY_FILTER) != 0) {
|
if ((mPropertiesSet & SAMPLER_PROPERTY_FILTER) != 0) {
|
||||||
HandleError("Sampler filter property set multiple times");
|
HandleError("Sampler filter property set multiple times");
|
||||||
return;
|
return;
|
||||||
@ -59,4 +61,4 @@ namespace backend {
|
|||||||
return mDevice->CreateSampler(this);
|
return mDevice->CreateSampler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_SAMPLER_H_
|
#ifndef BACKEND_SAMPLER_H_
|
||||||
#define BACKEND_SAMPLER_H_
|
#define BACKEND_SAMPLER_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Buffer.h"
|
#include "backend/Buffer.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
@ -37,7 +37,9 @@ namespace backend {
|
|||||||
nxt::FilterMode GetMipMapFilter() const;
|
nxt::FilterMode GetMipMapFilter() const;
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
void SetFilterMode(nxt::FilterMode magFilter, nxt::FilterMode minFilter, nxt::FilterMode mipMapFilter);
|
void SetFilterMode(nxt::FilterMode magFilter,
|
||||||
|
nxt::FilterMode minFilter,
|
||||||
|
nxt::FilterMode mipMapFilter);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class SamplerBase;
|
friend class SamplerBase;
|
||||||
@ -51,6 +53,6 @@ namespace backend {
|
|||||||
nxt::FilterMode mMipMapFilter = nxt::FilterMode::Nearest;
|
nxt::FilterMode mMipMapFilter = nxt::FilterMode::Nearest;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_SAMPLER_H_
|
#endif // BACKEND_SAMPLER_H_
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
ShaderModuleBase::ShaderModuleBase(ShaderModuleBuilder* builder)
|
ShaderModuleBase::ShaderModuleBase(ShaderModuleBuilder* builder) : mDevice(builder->mDevice) {
|
||||||
: mDevice(builder->mDevice) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceBase* ShaderModuleBase::GetDevice() const {
|
DeviceBase* ShaderModuleBase::GetDevice() const {
|
||||||
@ -62,8 +61,10 @@ namespace backend {
|
|||||||
ASSERT(blockType.basetype == spirv_cross::SPIRType::Struct);
|
ASSERT(blockType.basetype == spirv_cross::SPIRType::Struct);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < blockType.member_types.size(); i++) {
|
for (uint32_t i = 0; i < blockType.member_types.size(); i++) {
|
||||||
ASSERT(compiler.get_member_decoration_mask(blockType.self, i) & 1ull << spv::DecorationOffset);
|
ASSERT(compiler.get_member_decoration_mask(blockType.self, i) &
|
||||||
uint32_t offset = compiler.get_member_decoration(blockType.self, i, spv::DecorationOffset);
|
1ull << spv::DecorationOffset);
|
||||||
|
uint32_t offset =
|
||||||
|
compiler.get_member_decoration(blockType.self, i, spv::DecorationOffset);
|
||||||
ASSERT(offset % 4 == 0);
|
ASSERT(offset % 4 == 0);
|
||||||
offset /= 4;
|
offset /= 4;
|
||||||
|
|
||||||
@ -78,8 +79,8 @@ namespace backend {
|
|||||||
constantType = PushConstantType::Float;
|
constantType = PushConstantType::Float;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(cwallez@chromium.org): check for overflows and make the logic better take into account
|
// TODO(cwallez@chromium.org): check for overflows and make the logic better take
|
||||||
// things like the array of types with padding.
|
// into account things like the array of types with padding.
|
||||||
uint32_t size = memberType.vecsize * memberType.columns;
|
uint32_t size = memberType.vecsize * memberType.columns;
|
||||||
// Handle unidimensional arrays
|
// Handle unidimensional arrays
|
||||||
if (!memberType.array.empty()) {
|
if (!memberType.array.empty()) {
|
||||||
@ -92,7 +93,8 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mPushConstants.mask.set(offset);
|
mPushConstants.mask.set(offset);
|
||||||
mPushConstants.names[offset] = interfaceBlock.name + "." + compiler.get_member_name(blockType.self, i);
|
mPushConstants.names[offset] =
|
||||||
|
interfaceBlock.name + "." + compiler.get_member_name(blockType.self, i);
|
||||||
mPushConstants.sizes[offset] = size;
|
mPushConstants.sizes[offset] = size;
|
||||||
mPushConstants.types[offset] = constantType;
|
mPushConstants.types[offset] = constantType;
|
||||||
}
|
}
|
||||||
@ -100,11 +102,14 @@ namespace backend {
|
|||||||
|
|
||||||
// Fill in bindingInfo with the SPIRV bindings
|
// Fill in bindingInfo with the SPIRV bindings
|
||||||
auto ExtractResourcesBinding = [this](const std::vector<spirv_cross::Resource>& resources,
|
auto ExtractResourcesBinding = [this](const std::vector<spirv_cross::Resource>& resources,
|
||||||
const spirv_cross::Compiler& compiler, nxt::BindingType bindingType) {
|
const spirv_cross::Compiler& compiler,
|
||||||
constexpr uint64_t requiredBindingDecorationMask = (1ull << spv::DecorationBinding) | (1ull << spv::DecorationDescriptorSet);
|
nxt::BindingType bindingType) {
|
||||||
|
constexpr uint64_t requiredBindingDecorationMask =
|
||||||
|
(1ull << spv::DecorationBinding) | (1ull << spv::DecorationDescriptorSet);
|
||||||
|
|
||||||
for (const auto& resource : resources) {
|
for (const auto& resource : resources) {
|
||||||
ASSERT((compiler.get_decoration_mask(resource.id) & requiredBindingDecorationMask) == requiredBindingDecorationMask);
|
ASSERT((compiler.get_decoration_mask(resource.id) &
|
||||||
|
requiredBindingDecorationMask) == requiredBindingDecorationMask);
|
||||||
uint32_t binding = compiler.get_decoration(resource.id, spv::DecorationBinding);
|
uint32_t binding = compiler.get_decoration(resource.id, spv::DecorationBinding);
|
||||||
uint32_t set = compiler.get_decoration(resource.id, spv::DecorationDescriptorSet);
|
uint32_t set = compiler.get_decoration(resource.id, spv::DecorationDescriptorSet);
|
||||||
|
|
||||||
@ -121,10 +126,13 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ExtractResourcesBinding(resources.uniform_buffers, compiler, nxt::BindingType::UniformBuffer);
|
ExtractResourcesBinding(resources.uniform_buffers, compiler,
|
||||||
ExtractResourcesBinding(resources.separate_images, compiler, nxt::BindingType::SampledTexture);
|
nxt::BindingType::UniformBuffer);
|
||||||
|
ExtractResourcesBinding(resources.separate_images, compiler,
|
||||||
|
nxt::BindingType::SampledTexture);
|
||||||
ExtractResourcesBinding(resources.separate_samplers, compiler, nxt::BindingType::Sampler);
|
ExtractResourcesBinding(resources.separate_samplers, compiler, nxt::BindingType::Sampler);
|
||||||
ExtractResourcesBinding(resources.storage_buffers, compiler, nxt::BindingType::StorageBuffer);
|
ExtractResourcesBinding(resources.storage_buffers, compiler,
|
||||||
|
nxt::BindingType::StorageBuffer);
|
||||||
|
|
||||||
// Extract the vertex attributes
|
// Extract the vertex attributes
|
||||||
if (mExecutionModel == nxt::ShaderStage::Vertex) {
|
if (mExecutionModel == nxt::ShaderStage::Vertex) {
|
||||||
@ -140,10 +148,11 @@ namespace backend {
|
|||||||
mUsedVertexAttributes.set(location);
|
mUsedVertexAttributes.set(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Without a location qualifier on vertex outputs, spirv_cross::CompilerMSL gives them all
|
// Without a location qualifier on vertex outputs, spirv_cross::CompilerMSL gives them
|
||||||
// the location 0, causing a compile error.
|
// all the location 0, causing a compile error.
|
||||||
for (const auto& attrib : resources.stage_outputs) {
|
for (const auto& attrib : resources.stage_outputs) {
|
||||||
if (!(compiler.get_decoration_mask(attrib.id) & (1ull << spv::DecorationLocation))) {
|
if (!(compiler.get_decoration_mask(attrib.id) &
|
||||||
|
(1ull << spv::DecorationLocation))) {
|
||||||
mDevice->HandleError("Need location qualifier on vertex output");
|
mDevice->HandleError("Need location qualifier on vertex output");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -151,10 +160,11 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mExecutionModel == nxt::ShaderStage::Fragment) {
|
if (mExecutionModel == nxt::ShaderStage::Fragment) {
|
||||||
// Without a location qualifier on vertex inputs, spirv_cross::CompilerMSL gives them all
|
// Without a location qualifier on vertex inputs, spirv_cross::CompilerMSL gives them
|
||||||
// the location 0, causing a compile error.
|
// all the location 0, causing a compile error.
|
||||||
for (const auto& attrib : resources.stage_inputs) {
|
for (const auto& attrib : resources.stage_inputs) {
|
||||||
if (!(compiler.get_decoration_mask(attrib.id) & (1ull << spv::DecorationLocation))) {
|
if (!(compiler.get_decoration_mask(attrib.id) &
|
||||||
|
(1ull << spv::DecorationLocation))) {
|
||||||
mDevice->HandleError("Need location qualifier on fragment input");
|
mDevice->HandleError("Need location qualifier on fragment input");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -187,7 +197,8 @@ namespace backend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderModuleBase::IsCompatibleWithBindGroupLayout(size_t group, const BindGroupLayoutBase* layout) {
|
bool ShaderModuleBase::IsCompatibleWithBindGroupLayout(size_t group,
|
||||||
|
const BindGroupLayoutBase* layout) {
|
||||||
const auto& layoutInfo = layout->GetBindingInfo();
|
const auto& layoutInfo = layout->GetBindingInfo();
|
||||||
for (size_t i = 0; i < kMaxBindingsPerGroup; ++i) {
|
for (size_t i = 0; i < kMaxBindingsPerGroup; ++i) {
|
||||||
const auto& moduleInfo = mBindingInfo[group][i];
|
const auto& moduleInfo = mBindingInfo[group][i];
|
||||||
@ -227,4 +238,4 @@ namespace backend {
|
|||||||
mSpirv.assign(code, code + codeSize);
|
mSpirv.assign(code, code + codeSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_SHADERMODULE_H_
|
#ifndef BACKEND_SHADERMODULE_H_
|
||||||
#define BACKEND_SHADERMODULE_H_
|
#define BACKEND_SHADERMODULE_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
|
|
||||||
@ -55,7 +55,8 @@ namespace backend {
|
|||||||
nxt::BindingType type;
|
nxt::BindingType type;
|
||||||
bool used = false;
|
bool used = false;
|
||||||
};
|
};
|
||||||
using ModuleBindingInfo = std::array<std::array<BindingInfo, kMaxBindingsPerGroup>, kMaxBindGroups>;
|
using ModuleBindingInfo =
|
||||||
|
std::array<std::array<BindingInfo, kMaxBindingsPerGroup>, kMaxBindGroups>;
|
||||||
|
|
||||||
const PushConstantInfo& GetPushConstants() const;
|
const PushConstantInfo& GetPushConstants() const;
|
||||||
const ModuleBindingInfo& GetBindingInfo() const;
|
const ModuleBindingInfo& GetBindingInfo() const;
|
||||||
@ -91,6 +92,6 @@ namespace backend {
|
|||||||
std::vector<uint32_t> mSpirv;
|
std::vector<uint32_t> mSpirv;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_SHADERMODULE_H_
|
#endif // BACKEND_SHADERMODULE_H_
|
||||||
|
@ -34,7 +34,10 @@ namespace backend {
|
|||||||
return mDevice;
|
return mDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChainBase::Configure(nxt::TextureFormat format, nxt::TextureUsageBit allowedUsage, uint32_t width, uint32_t height) {
|
void SwapChainBase::Configure(nxt::TextureFormat format,
|
||||||
|
nxt::TextureUsageBit allowedUsage,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height) {
|
||||||
if (width == 0 || height == 0) {
|
if (width == 0 || height == 0) {
|
||||||
mDevice->HandleError("Swap chain cannot be configured to zero size");
|
mDevice->HandleError("Swap chain cannot be configured to zero size");
|
||||||
return;
|
return;
|
||||||
@ -45,8 +48,8 @@ namespace backend {
|
|||||||
mAllowedUsage = allowedUsage;
|
mAllowedUsage = allowedUsage;
|
||||||
mWidth = width;
|
mWidth = width;
|
||||||
mHeight = height;
|
mHeight = height;
|
||||||
mImplementation.Configure(mImplementation.userData,
|
mImplementation.Configure(mImplementation.userData, static_cast<nxtTextureFormat>(format),
|
||||||
static_cast<nxtTextureFormat>(format), static_cast<nxtTextureUsageBit>(allowedUsage), width, height);
|
static_cast<nxtTextureUsageBit>(allowedUsage), width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureBase* SwapChainBase::GetNextTexture() {
|
TextureBase* SwapChainBase::GetNextTexture() {
|
||||||
@ -87,8 +90,7 @@ namespace backend {
|
|||||||
|
|
||||||
// SwapChain Builder
|
// SwapChain Builder
|
||||||
|
|
||||||
SwapChainBuilder::SwapChainBuilder(DeviceBase* device)
|
SwapChainBuilder::SwapChainBuilder(DeviceBase* device) : Builder(device) {
|
||||||
: Builder(device) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapChainBase* SwapChainBuilder::GetResultImpl() {
|
SwapChainBase* SwapChainBuilder::GetResultImpl() {
|
||||||
@ -105,14 +107,15 @@ namespace backend {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nxtSwapChainImplementation& impl = *reinterpret_cast<nxtSwapChainImplementation*>(implementation);
|
nxtSwapChainImplementation& impl =
|
||||||
|
*reinterpret_cast<nxtSwapChainImplementation*>(implementation);
|
||||||
|
|
||||||
if (!impl.Init || !impl.Destroy || !impl.Configure ||
|
if (!impl.Init || !impl.Destroy || !impl.Configure || !impl.GetNextTexture ||
|
||||||
!impl.GetNextTexture || !impl.Present) {
|
!impl.Present) {
|
||||||
HandleError("Implementation is incomplete");
|
HandleError("Implementation is incomplete");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mImplementation = impl;
|
mImplementation = impl;
|
||||||
}
|
}
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
#ifndef BACKEND_SWAPCHAIN_H_
|
#ifndef BACKEND_SWAPCHAIN_H_
|
||||||
#define BACKEND_SWAPCHAIN_H_
|
#define BACKEND_SWAPCHAIN_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
|
||||||
#include "nxt/nxt_wsi.h"
|
#include "nxt/nxt_wsi.h"
|
||||||
|
#include "nxt/nxtcpp.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
@ -32,7 +32,10 @@ namespace backend {
|
|||||||
DeviceBase* GetDevice();
|
DeviceBase* GetDevice();
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
void Configure(nxt::TextureFormat format, nxt::TextureUsageBit allowedUsage, uint32_t width, uint32_t height);
|
void Configure(nxt::TextureFormat format,
|
||||||
|
nxt::TextureUsageBit allowedUsage,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height);
|
||||||
TextureBase* GetNextTexture();
|
TextureBase* GetNextTexture();
|
||||||
void Present(TextureBase* texture);
|
void Present(TextureBase* texture);
|
||||||
|
|
||||||
@ -64,6 +67,6 @@ namespace backend {
|
|||||||
nxtSwapChainImplementation mImplementation = {};
|
nxtSwapChainImplementation mImplementation = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_SWAPCHAIN_H_
|
#endif // BACKEND_SWAPCHAIN_H_
|
||||||
|
@ -71,13 +71,18 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TextureBase
|
// TextureBase
|
||||||
|
|
||||||
TextureBase::TextureBase(TextureBuilder* builder)
|
TextureBase::TextureBase(TextureBuilder* builder)
|
||||||
: mDevice(builder->mDevice), mDimension(builder->mDimension), mFormat(builder->mFormat), mWidth(builder->mWidth),
|
: mDevice(builder->mDevice),
|
||||||
mHeight(builder->mHeight), mDepth(builder->mDepth), mNumMipLevels(builder->mNumMipLevels),
|
mDimension(builder->mDimension),
|
||||||
mAllowedUsage(builder->mAllowedUsage), mCurrentUsage(builder->mCurrentUsage) {
|
mFormat(builder->mFormat),
|
||||||
|
mWidth(builder->mWidth),
|
||||||
|
mHeight(builder->mHeight),
|
||||||
|
mDepth(builder->mDepth),
|
||||||
|
mNumMipLevels(builder->mNumMipLevels),
|
||||||
|
mAllowedUsage(builder->mAllowedUsage),
|
||||||
|
mCurrentUsage(builder->mCurrentUsage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceBase* TextureBase::GetDevice() {
|
DeviceBase* TextureBase::GetDevice() {
|
||||||
@ -121,7 +126,8 @@ namespace backend {
|
|||||||
return mIsFrozen && (usage & mAllowedUsage);
|
return mIsFrozen && (usage & mAllowedUsage);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureBase::IsUsagePossible(nxt::TextureUsageBit allowedUsage, nxt::TextureUsageBit usage) {
|
bool TextureBase::IsUsagePossible(nxt::TextureUsageBit allowedUsage,
|
||||||
|
nxt::TextureUsageBit usage) {
|
||||||
bool allowed = (usage & allowedUsage) == usage;
|
bool allowed = (usage & allowedUsage) == usage;
|
||||||
bool singleUse = nxt::HasZeroOrOneBits(usage);
|
bool singleUse = nxt::HasZeroOrOneBits(usage);
|
||||||
return allowed && singleUse;
|
return allowed && singleUse;
|
||||||
@ -173,13 +179,13 @@ namespace backend {
|
|||||||
TEXTURE_PROPERTY_INITIAL_USAGE = 0x20,
|
TEXTURE_PROPERTY_INITIAL_USAGE = 0x20,
|
||||||
};
|
};
|
||||||
|
|
||||||
TextureBuilder::TextureBuilder(DeviceBase* device)
|
TextureBuilder::TextureBuilder(DeviceBase* device) : Builder(device) {
|
||||||
: Builder(device) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureBase* TextureBuilder::GetResultImpl() {
|
TextureBase* TextureBuilder::GetResultImpl() {
|
||||||
constexpr int allProperties = TEXTURE_PROPERTY_DIMENSION | TEXTURE_PROPERTY_EXTENT |
|
constexpr int allProperties = TEXTURE_PROPERTY_DIMENSION | TEXTURE_PROPERTY_EXTENT |
|
||||||
TEXTURE_PROPERTY_FORMAT | TEXTURE_PROPERTY_MIP_LEVELS | TEXTURE_PROPERTY_ALLOWED_USAGE;
|
TEXTURE_PROPERTY_FORMAT | TEXTURE_PROPERTY_MIP_LEVELS |
|
||||||
|
TEXTURE_PROPERTY_ALLOWED_USAGE;
|
||||||
if ((mPropertiesSet & allProperties) != allProperties) {
|
if ((mPropertiesSet & allProperties) != allProperties) {
|
||||||
HandleError("Texture missing properties");
|
HandleError("Texture missing properties");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -264,8 +270,7 @@ namespace backend {
|
|||||||
|
|
||||||
// TextureViewBase
|
// TextureViewBase
|
||||||
|
|
||||||
TextureViewBase::TextureViewBase(TextureViewBuilder* builder)
|
TextureViewBase::TextureViewBase(TextureViewBuilder* builder) : mTexture(builder->mTexture) {
|
||||||
: mTexture(builder->mTexture) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureBase* TextureViewBase::GetTexture() {
|
TextureBase* TextureViewBase::GetTexture() {
|
||||||
@ -282,4 +287,4 @@ namespace backend {
|
|||||||
return mDevice->CreateTextureView(this);
|
return mDevice->CreateTextureView(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#ifndef BACKEND_TEXTURE_H_
|
#ifndef BACKEND_TEXTURE_H_
|
||||||
#define BACKEND_TEXTURE_H_
|
#define BACKEND_TEXTURE_H_
|
||||||
|
|
||||||
#include "backend/Forward.h"
|
|
||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
#include "backend/Forward.h"
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
@ -53,7 +53,8 @@ namespace backend {
|
|||||||
void TransitionUsage(nxt::TextureUsageBit usage);
|
void TransitionUsage(nxt::TextureUsageBit usage);
|
||||||
void FreezeUsage(nxt::TextureUsageBit usage);
|
void FreezeUsage(nxt::TextureUsageBit usage);
|
||||||
|
|
||||||
virtual void TransitionUsageImpl(nxt::TextureUsageBit currentUsage, nxt::TextureUsageBit targetUsage) = 0;
|
virtual void TransitionUsageImpl(nxt::TextureUsageBit currentUsage,
|
||||||
|
nxt::TextureUsageBit targetUsage) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeviceBase* mDevice;
|
DeviceBase* mDevice;
|
||||||
@ -116,6 +117,6 @@ namespace backend {
|
|||||||
Ref<TextureBase> mTexture;
|
Ref<TextureBase> mTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_TEXTURE_H_
|
#endif // BACKEND_TEXTURE_H_
|
||||||
|
@ -20,105 +20,105 @@
|
|||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
// ToBackendTraits implements the mapping from base type to member type of BackendTraits
|
// ToBackendTraits implements the mapping from base type to member type of BackendTraits
|
||||||
template<typename T, typename BackendTraits>
|
template <typename T, typename BackendTraits>
|
||||||
struct ToBackendTraits;
|
struct ToBackendTraits;
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<BindGroupBase, BackendTraits> {
|
struct ToBackendTraits<BindGroupBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::BindGroupType;
|
using BackendType = typename BackendTraits::BindGroupType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<BindGroupLayoutBase, BackendTraits> {
|
struct ToBackendTraits<BindGroupLayoutBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::BindGroupLayoutType;
|
using BackendType = typename BackendTraits::BindGroupLayoutType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<BlendStateBase, BackendTraits> {
|
struct ToBackendTraits<BlendStateBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::BlendStateType;
|
using BackendType = typename BackendTraits::BlendStateType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<BufferBase, BackendTraits> {
|
struct ToBackendTraits<BufferBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::BufferType;
|
using BackendType = typename BackendTraits::BufferType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<BufferViewBase, BackendTraits> {
|
struct ToBackendTraits<BufferViewBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::BufferViewType;
|
using BackendType = typename BackendTraits::BufferViewType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<CommandBufferBase, BackendTraits> {
|
struct ToBackendTraits<CommandBufferBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::CommandBufferType;
|
using BackendType = typename BackendTraits::CommandBufferType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<ComputePipelineBase, BackendTraits> {
|
struct ToBackendTraits<ComputePipelineBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::ComputePipelineType;
|
using BackendType = typename BackendTraits::ComputePipelineType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<DepthStencilStateBase, BackendTraits> {
|
struct ToBackendTraits<DepthStencilStateBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::DepthStencilStateType;
|
using BackendType = typename BackendTraits::DepthStencilStateType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<DeviceBase, BackendTraits> {
|
struct ToBackendTraits<DeviceBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::DeviceType;
|
using BackendType = typename BackendTraits::DeviceType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<FramebufferBase, BackendTraits> {
|
struct ToBackendTraits<FramebufferBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::FramebufferType;
|
using BackendType = typename BackendTraits::FramebufferType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<InputStateBase, BackendTraits> {
|
struct ToBackendTraits<InputStateBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::InputStateType;
|
using BackendType = typename BackendTraits::InputStateType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<PipelineLayoutBase, BackendTraits> {
|
struct ToBackendTraits<PipelineLayoutBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::PipelineLayoutType;
|
using BackendType = typename BackendTraits::PipelineLayoutType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<QueueBase, BackendTraits> {
|
struct ToBackendTraits<QueueBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::QueueType;
|
using BackendType = typename BackendTraits::QueueType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<RenderPassBase, BackendTraits> {
|
struct ToBackendTraits<RenderPassBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::RenderPassType;
|
using BackendType = typename BackendTraits::RenderPassType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<RenderPipelineBase, BackendTraits> {
|
struct ToBackendTraits<RenderPipelineBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::RenderPipelineType;
|
using BackendType = typename BackendTraits::RenderPipelineType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<SamplerBase, BackendTraits> {
|
struct ToBackendTraits<SamplerBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::SamplerType;
|
using BackendType = typename BackendTraits::SamplerType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<ShaderModuleBase, BackendTraits> {
|
struct ToBackendTraits<ShaderModuleBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::ShaderModuleType;
|
using BackendType = typename BackendTraits::ShaderModuleType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<TextureBase, BackendTraits> {
|
struct ToBackendTraits<TextureBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::TextureType;
|
using BackendType = typename BackendTraits::TextureType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<SwapChainBase, BackendTraits> {
|
struct ToBackendTraits<SwapChainBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::SwapChainType;
|
using BackendType = typename BackendTraits::SwapChainType;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BackendTraits>
|
template <typename BackendTraits>
|
||||||
struct ToBackendTraits<TextureViewBase, BackendTraits> {
|
struct ToBackendTraits<TextureViewBase, BackendTraits> {
|
||||||
using BackendType = typename BackendTraits::TextureViewType;
|
using BackendType = typename BackendTraits::TextureViewType;
|
||||||
};
|
};
|
||||||
@ -130,26 +130,30 @@ namespace backend {
|
|||||||
// return ToBackendBase<MyBackendTraits>(common);
|
// return ToBackendBase<MyBackendTraits>(common);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
template<typename BackendTraits, typename T>
|
template <typename BackendTraits, typename T>
|
||||||
Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(Ref<T>& common) {
|
Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(Ref<T>& common) {
|
||||||
return reinterpret_cast<Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&>(common);
|
return reinterpret_cast<Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&>(
|
||||||
|
common);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BackendTraits, typename T>
|
template <typename BackendTraits, typename T>
|
||||||
const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(const Ref<T>& common) {
|
const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(
|
||||||
return reinterpret_cast<const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&>(common);
|
const Ref<T>& common) {
|
||||||
|
return reinterpret_cast<
|
||||||
|
const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&>(common);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BackendTraits, typename T>
|
template <typename BackendTraits, typename T>
|
||||||
typename ToBackendTraits<T, BackendTraits>::BackendType* ToBackendBase(T* common) {
|
typename ToBackendTraits<T, BackendTraits>::BackendType* ToBackendBase(T* common) {
|
||||||
return reinterpret_cast<typename ToBackendTraits<T, BackendTraits>::BackendType*>(common);
|
return reinterpret_cast<typename ToBackendTraits<T, BackendTraits>::BackendType*>(common);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BackendTraits, typename T>
|
template <typename BackendTraits, typename T>
|
||||||
const typename ToBackendTraits<T, BackendTraits>::BackendType* ToBackendBase(const T* common) {
|
const typename ToBackendTraits<T, BackendTraits>::BackendType* ToBackendBase(const T* common) {
|
||||||
return reinterpret_cast<const typename ToBackendTraits<T, BackendTraits>::BackendType*>(common);
|
return reinterpret_cast<const typename ToBackendTraits<T, BackendTraits>::BackendType*>(
|
||||||
|
common);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace backend
|
||||||
|
|
||||||
#endif // BACKEND_TOBACKEND_H_
|
#endif // BACKEND_TOBACKEND_H_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user