Exemplo n.º 1
0
    void DirectorySearchRules::ResolveFile(ResChar destination[], unsigned destinationCount, const ResChar baseName[]) const
    {
        ResChar tempBuffer[MaxPath];

        auto splitter = MakeFileNameSplitter(baseName);
        bool baseFileExist = false;
        if (!splitter.ParametersWithDivider().Empty()) {
            XlCopyString(tempBuffer, splitter.AllExceptParameters());
            baseFileExist = DoesFileExist(tempBuffer);
        } else {
            baseFileExist = DoesFileExist(baseName);
        }

            // by definition, we always check the unmodified file name first
        if (!baseFileExist) {
            const ResChar* b = _buffer;
            if (!_bufferOverflow.empty()) {
                b = AsPointer(_bufferOverflow.begin());
            }

                // We want to support the case were destination == baseName
                // But that cases requires another temporary buffer, because we
                // don't want to trash "baseName" while searching for matches
            ResChar* workingBuffer = (baseName!=destination) ? destination : tempBuffer;
            unsigned workingBufferSize = (baseName!=destination) ? destinationCount : unsigned(dimof(tempBuffer));

            for (unsigned c=0; c<_startPointCount; ++c) {
                XlConcatPath(workingBuffer, workingBufferSize, &b[_startOffsets[c]], 
                    splitter.AllExceptParameters().begin(), splitter.AllExceptParameters().end());
                if (DoesFileExist(workingBuffer)) {
                    SplitPath<ResChar>(workingBuffer).Simplify().Rebuild(workingBuffer, workingBufferSize);
                    if (workingBuffer != destination) {
                        auto workingBufferLen = std::min((ptrdiff_t)XlStringLen(workingBuffer), ptrdiff_t(destinationCount) - 1);
                        auto colonLen = (ptrdiff_t)splitter.ParametersWithDivider().Length();
                        auto colonCopy = std::min(ptrdiff_t(destinationCount) - workingBufferLen - 1, colonLen);
                        assert((workingBufferLen + colonCopy) < ptrdiff_t(destinationCount));
                        if (colonCopy > 0)
                            XlMoveMemory(&destination[workingBufferLen], splitter.ParametersWithDivider().begin(), colonCopy);
                        destination[workingBufferLen + colonCopy] = '\0';
                        assert(workingBufferLen < (ptrdiff_t(destinationCount)-1));
                        XlCopyMemory(destination, workingBuffer, workingBufferLen);
                    } else {
                        XlCatString(destination, destinationCount, splitter.ParametersWithDivider());
                    }
                    return;
                }
            }
        }

        if (baseName != destination)
            XlCopyString(destination, destinationCount, baseName);
        SplitPath<ResChar>(destination).Simplify().Rebuild(destination, destinationCount);
    }
Exemplo n.º 2
0
        static std::shared_ptr<MaterialScaffold> CreateMaterialScaffold(
            const ::Assets::ResChar model[], 
            const ::Assets::ResChar material[], 
            RenderCore::Assets::IModelFormat& modelFormat)
        {
                // note --  we need to remove any parameters after ':' in the model name
                //          these are references to sub-nodes within the model hierarchy
                //          (which are irrelevant when dealing with materials, since the
                //          materials are shared for the entire model file)
            ::Assets::ResChar temp[MaxPath];
            const auto paramStart = XlFindChar(model, (::Assets::ResChar)':');
            if (paramStart) {
                XlCopyString(temp, MakeStringSection(model, paramStart));
                model = temp;
            }

            auto& compilers = ::Assets::Services::GetAsyncMan().GetIntermediateCompilers();
            auto& store = ::Assets::Services::GetAsyncMan().GetIntermediateStore();
            const ::Assets::ResChar* inits[] = { material, model };
            auto marker = compilers.PrepareAsset(
                MaterialScaffold::CompileProcessType, 
                inits, dimof(inits), store);
            if (!marker) return nullptr;
            return std::make_shared<MaterialScaffold>(std::move(marker));
        }
Exemplo n.º 3
0
    RenderCore::Metal::BoundUniforms* SharedStateSet::BeginVariation(
            const ModelRendererContext& context,
            SharedShaderName shaderName, SharedTechniqueInterface techniqueInterface, 
            SharedParameterBox geoParamBox, SharedParameterBox materialParamBox) const
    {
        if (    shaderName == _currentShaderName && techniqueInterface == _currentTechniqueInterface 
            &&  geoParamBox == _currentGeoParamBox && materialParamBox == _currentMaterialParamBox) {
            return _currentBoundUniforms;
        }

            // we need to check both the "xleres" and "xleres_cry" folders for material files
        char buffer[MaxPath];
        XlCopyString(buffer, "game/xleres/");
        XlCatString(buffer, dimof(buffer), _pimpl->_shaderNames[shaderName.Value()].c_str());
        XlCatString(buffer, dimof(buffer), ".txt");

        if (!DoesFileExist(buffer)) {
            XlCopyString(buffer, "game/xleres_cry/");
            XlCatString(buffer, dimof(buffer), _pimpl->_shaderNames[shaderName.Value()].c_str());
            XlCatString(buffer, dimof(buffer), ".txt");
        }

        auto& techniqueContext = context._parserContext->GetTechniqueContext();
        auto& shaderType = ::Assets::GetAssetDep<Techniques::ShaderType>(buffer);
        const ParameterBox* state[] = {
            &_pimpl->_parameterBoxes[geoParamBox.Value()],
            &techniqueContext._globalEnvironmentState,
            &techniqueContext._runtimeState,
            &_pimpl->_parameterBoxes[materialParamBox.Value()]
        };

        auto& techniqueInterfaceObj = _pimpl->_techniqueInterfaces[techniqueInterface.Value()];

            // (FindVariation can throw pending/invalid resource)
        auto variation = shaderType.FindVariation(context._techniqueIndex, state, techniqueInterfaceObj);
        if (variation._shaderProgram && variation._boundLayout) {
            context._context->Bind(*variation._shaderProgram);
            context._context->Bind(*variation._boundLayout);
        }

        _currentShaderName = shaderName;
        _currentTechniqueInterface = techniqueInterface;
        _currentMaterialParamBox = materialParamBox;
        _currentGeoParamBox = geoParamBox;
        _currentBoundUniforms = variation._boundUniforms;
        return _currentBoundUniforms;
    }
Exemplo n.º 4
0
    CompiledShaderByteCode::CompiledShaderByteCode(const ::Assets::ResChar initializer[], const ::Assets::ResChar definesTable[])
    {
        _stage = ShaderStage::Null;
        auto validationCallback = std::make_shared<Assets::DependencyValidation>();
        std::shared_ptr<ShaderService::IPendingMarker> compileHelper;
        DEBUG_ONLY(XlCopyString(_initializer, initializer);)

        if (initializer && initializer[0] != '\0') {
Exemplo n.º 5
0
    void DirectorySearchRules::ResolveDirectory(
            ResChar destination[], unsigned destinationCount, 
            const ResChar baseName[]) const
    {
            //  We have a problem with basic paths (like '../')
            //  These will match for most directories -- which means that
            //  there is some ambiguity. Let's prefer to use the first
            //  registered path for simple relative paths like this.
        bool useBaseName = 
            (baseName[0] != '.' && DoesDirectoryExist(baseName));

        if (!useBaseName) {
            const ResChar* b = _buffer;
            if (!_bufferOverflow.empty()) {
                b = AsPointer(_bufferOverflow.begin());
            }

            const auto* baseEnd = XlStringEnd(baseName);
            
            ResChar tempBuffer[MaxPath];
            ResChar* workingBuffer = (baseName!=destination) ? destination : tempBuffer;
            unsigned workingBufferSize = (baseName!=destination) ? destinationCount : unsigned(dimof(tempBuffer));

            for (unsigned c=0; c<_startPointCount; ++c) {
                XlConcatPath(workingBuffer, workingBufferSize, &b[_startOffsets[c]], baseName, baseEnd);
                if (DoesDirectoryExist(workingBuffer)) {
                    if (workingBuffer != destination)
                        XlCopyString(destination, destinationCount, workingBuffer);
                    return;
                }
            }
        }

        if (baseName != destination)
            XlCopyString(destination, destinationCount, baseName);
    }
Exemplo n.º 6
0
    void AsyncLoadOperation::Enqueue(const ResChar filename[], CompletionThreadPool& pool)
    {
        assert(!_hasBeenQueued);
        _hasBeenQueued = true;
        XlCopyString(_filename, filename);

            // We will hold an extra reference to this object
            // during the queueing processing and while the background
            // load is occurring.
            //
            // Before the file open is started, it will be just a 
            // weak reference. If all client references are destroyed
            // before we open the file, then we will cancel.
            // However, once the file has been opened we need to
            // hold a strong reference at least until the read has
            // completed

        std::weak_ptr<AsyncLoadOperation> weakToThis = shared_from_this();
        pool.Enqueue(
            [weakToThis]()
            {
                auto thisOp = weakToThis.lock();
                    // if all other references to this object have been released
                    // then the weak_ptr::lock() will fail, and we can consider
                    // it a cancel
                if (!thisOp) return;

                    // if we got to this point, we cannot cancel until the load
                    // level read operation has been completed
                auto h = CreateFile(
                    thisOp->_filename, GENERIC_READ, FILE_SHARE_READ,
                    nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
                    nullptr);

                if (h == INVALID_HANDLE_VALUE) {
                        // failed to load the file -- probably because it's missing
                    thisOp->SetState(::Assets::AssetState::Invalid);
                    return;
                }
                    
                auto fileSize = GetFileSize(h, nullptr);
                if (!fileSize || fileSize == INVALID_FILE_SIZE) {
                    thisOp->SetState(::Assets::AssetState::Invalid);
                    CloseHandle(h);
                    return;
                }

                thisOp->_buffer.reset((uint8*)XlMemAlign(fileSize, 16));
                thisOp->_bufferLength = fileSize;

                thisOp->_overlapped = std::make_unique<SpecialOverlapped>();
                XlSetMemory(thisOp->_overlapped.get(), 0, sizeof(OVERLAPPED));
                thisOp->_overlapped->_fileHandle = INVALID_HANDLE_VALUE;
                thisOp->_overlapped->_returnPointer = thisOp;

                auto readResult = ReadFileEx(
                    h, thisOp->_buffer.get(), fileSize, 
                    thisOp->_overlapped.get(), &SpecialOverlapped::CompletionRoutine);
                if (!readResult) {
                    CloseHandle(h);
                    thisOp->SetState(::Assets::AssetState::Invalid);
                    thisOp->_overlapped->_returnPointer.reset();
                    return;
                }

                thisOp->_overlapped->_fileHandle = h;

                // execution will pass to AsyncLoadOperation::CompletionRoutine, which
                // will complete the load operation
            });
    }